Skip to content

Add neighbors_from_distance for computing neighborhood graphs from precomputed distance matrices #3627

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 20 commits into
base: main
Choose a base branch
from

Conversation

amalia-k510
Copy link

Adding a function, neighbors_from_distance, that allows users to compute connectivities and distances directly from precomputed distance matrix. Might be useful where distances are generated externally, and we want to plug them into the standard scanpy graph-based pipeline without recomputing neighbors.

This function should support the following:

  • supports both dense and sparse matrices
  • zeroes the diagonal to avoid self-loops
  • builds connectivities using either the UMAP or Gauss method
  • stores results in .obsp and .uns using the same structure as sc.pp.neighbors,
  • optionally allows key namespacing via key_added

@amalia-k510 amalia-k510 marked this pull request as ready for review May 8, 2025 16:15
Copy link
Member

@flying-sheep flying-sheep left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks good except for the metrics changes being here instead of remaining in their own PR 😉

It also looks like some code is copied. Please check if you can introduce a helper function for everything after if method == "umap":, looks like most of that is identical to what’s in def neighbors. But if it’s too complicated or different, don’t do it!

Please also (after removing the metrics tests from this PR) add tests to check that passing distances results in the same stuff being added to adata as not doing it. Something like

adata_n = ...
adata_d = adata_n.copy()

sc.pp.neighbors(adata_n)
sc.pp.neighbors(adata_d, distances=adata_n.obsp["distances"])

# for all the parts that should be there:
np.testing.assert_almost_equal(...)
…

# for all the parts that can’t be derived from distances
assert "somekey" in adata_n.…
assert "somekey" not in adata_d.…

@flying-sheep flying-sheep added this to the 1.12.0 milestone May 16, 2025
Copy link
Member

@flying-sheep flying-sheep left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks good! please add a release note by running hatch run towncrier:create 3627.feature.md and editing that (don’t forget to add your name as in the other release note fragments)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants