scverse / squidpy

Spatial Single Cell Analysis in Python
https://squidpy.readthedocs.io/en/stable/
BSD 3-Clause "New" or "Revised" License
401 stars 72 forks source link

Spatial network CSR matrix seems not symmetrical #774

Closed AlexCoul closed 7 months ago

AlexCoul commented 7 months ago

Description

Hi, I noticed while running the tutorial_merfish.ipynb notebook that the adata.obsp['spatial_connectivities'] object seems non symmetrical, whereas I was expecting a symmetrical matrix. Is it normal?

Minimal reproducible example

Start executing the tutorial_merfish.ipynb notebook. Then after cell 6 where we run sq.gr.spatial_neighbors(adata, coord_type="generic", spatial_key="spatial3d"), add a new cell to run:

import numpy as np

# get pairs of connected nodes
src, trg = adata.obsp['spatial_connectivities'].nonzero()
pairs = np.vstack([src, trg]).T
print(pairs[:5, :])

# detect all non-symmetrical pairs
n_diff = 0
for i, (src, trg) in enumerate(pairs):
    a = adata.obsp['spatial_connectivities'][src, trg]
    b = adata.obsp['spatial_connectivities'][trg, src]
    if a!= b:
        print(f"difference at pair {i}: src {src} = {a}, trg {trg} = {b}")
        n_diff += 1
print(f"Number of differing elements: {n_diff}, over {len(pairs)} pairs")

# check on the first elements
# compare [1, 2] vs [2, 1]
n = 5
adata.obsp['spatial_connectivities'][:n, :n].toarray().astype(int)

Version

scanpy==1.9.6 anndata==0.10.3 umap==0.5.5 numpy==1.23.4 scipy==1.11.4 pandas==2.1.3 scikit-learn==1.3.2 statsmodels==0.14.0 igraph==0.10.8 pynndescent==0.5.11 squidpy==1.3.1

...

giovp commented 7 months ago

hi @AlexCoul ,

it is very much expected, in the k-nearest neighbor setting you are using (but in many other cases, especially for combinations of behaviors e.g. when additional filtering are used) the resulting adjacency matrices are never symmetric. A simple thought experiment is the following. Take 3 points in a line, at positions 0,1,1000. The nearest neighbor of point 1000 is 1, but the nearest neighbor of point 1 is not 1000. HTH.

AlexCoul commented 7 months ago

Ah right! I nearly always use Delaunnay triangulation so I totally forgot this network was built with the k-nearest neighbor method, thanks!