squidpy.gr.nhood_enrichment

squidpy.gr.nhood_enrichment(adata, *, cluster_key, library_key=None, connectivity_key=None, n_perms=1000, rng=None, copy=False, n_jobs=None, show_progress_bar=True, normalization='none', min_cell_count=0, handle_nan='keep', table_key=None)[source]

Compute neighborhood enrichment by permutation test.

Changed in version 1.8.4: Every permutation now uses an independent numpy.random.Generator spawned from a numpy.random.SeedSequence. Consequently the permutation-based results no longer depend on n_jobs / backend, but results obtained with a given seed differ from those produced by squidpy < 1.8.4. See #1232 and #1233.

Changed in version 1.8.4: seed / random_state were renamed to rng, which also accepts a numpy.random.Generator (SPEC 7). The old names still work but emit a FutureWarning.

Parameters:
  • adata (AnnData | SpatialData) – Annotated data object.

  • table_key (str | None) – Key in spatialdata.SpatialData.tables where the table is stored. Required when adata is a spatialdata.SpatialData object and ignored otherwise.

  • cluster_key (str) – Key in anndata.AnnData.obs where clustering is stored.

  • library_key (str | None) – If multiple library_id, column in anndata.AnnData.obs which stores mapping between library_id and obs.

  • connectivity_key (str | None) – Key in anndata.AnnData.obsp where spatial connectivities are stored. Default is: anndata.AnnData.obsp ['spatial_connectivities'].

  • n_perms (int) – Number of permutations for the permutation test.

  • rng (int | integer | Sequence[int] | SeedSequence | Generator | BitGenerator | None) –

    Pseudorandom number generator state, following SPEC 7. When None, a new numpy.random.Generator is created using entropy from the operating system. Types other than numpy.random.Generator are passed to numpy.random.default_rng() to instantiate a generator.

  • copy (bool) – If True, return the result, otherwise save it to the adata object.

  • n_jobs (int | None) – Number of parallel threads to use. None and -1 use numba’s default thread count (NUMBA_NUM_THREADS); asking for more threads than that warns and falls back to it, while 0 and values below -1 raise, since scanpy only supports n_jobs >= -1.

  • show_progress_bar (bool) – Whether to show the progress bar or not.

  • normalization (str) –

    Normalization mode to use, as compared in [Schiller et al., 2025]:

    • 'none': No normalization of neighbor counts.

    • 'total': Divide by the number of cells of the index cluster (SEA). Cluster sizes are unchanged by the permutation, so this rescales the statistic without changing the z-score.

    • 'conditional': Divide by the number of index-cluster cells having at least one neighbor of the given type (COZI).

  • min_cell_count (int) – Minimum number of cells a cluster must contain to be included. Clusters with fewer cells are dropped before counting (default 0 keeps all clusters) and their z-scores are NaN whatever handle_nan says. Worth raising: a cluster too small to give the permutation null a spread of values yields an unreliable z-score, and in 'conditional' mode a rare cluster pair can leave the denominator at zero, which is reported as 0.

  • handle_nan (Literal['keep', 'zero']) –

    How to handle NaN values in z-scores:

    • 'zero': Replace NaN values with 0

    • 'keep': Keep NaN values (undefined enrichment)

Return type:

NhoodEnrichmentResult | None

Returns:

If copy = True, returns a NhoodEnrichmentResult with the z-score and the enrichment count. If normalization = “conditional”, also contains the conditional ratio, otherwise it is None.

Otherwise, modifies the adata with the following keys:

  • anndata.AnnData.uns ['{cluster_key}_nhood_enrichment']['zscore'] - the enrichment z-score.

  • anndata.AnnData.uns ['{cluster_key}_nhood_enrichment']['count'] - the enrichment count.

  • anndata.AnnData.uns ['{cluster_key}_nhood_enrichment']['conditional_ratio'] - the ratio of cells of type A that neighbor type B.