squidpy.gr.calculate_niche_neighborhood

squidpy.gr.calculate_niche_neighborhood(data, *, groups, resolutions, n_neighbors=15, spatial_connectivities_key='spatial_connectivities', scale=True, distance=1, abs_nhood=False, n_hop_weights=None, embedding_key_added='niche_embedding', key_added='nhood_niche', min_niche_size=None, cluster_mask=None, copy=False, table_key=None, flavor='igraph', n_iterations=-1, rng=None)[source]

Compute spatial niches from local cell-type composition.

Follows monkeybread’s https://github.com/immunitastx/monkeybread/blob/main/src/monkeybread/calc/_neighborhood_profile.py

This method represents every observation by a neighborhood composition profile: a vector describing the cell-type labels observed in its local spatial neighborhood. Observations with similar surrounding cell-type compositions are then grouped into niches using Leiden clustering.

A spatial connectivity graph must already be available in adata.obsp[spatial_connectivities_key]. The graph defines which observations are spatial neighbors; this function does not construct the graph itself.

For each observation i, the method:

  1. Retrieves observations reachable from i in the spatial graph up to distance hops away.

  2. Counts the values of groups among those neighboring observations.

  3. Optionally combines profiles from different graph-hop distances using n_hop_weights.

  4. Uses either raw counts or normalized cell-type proportions as the neighborhood profile.

  5. Optionally z-scores the resulting profile across observations (scale argument).

  6. Constructs a k-nearest-neighbor graph from the profile embedding and applies Leiden clustering at each requested resolution.

Thus, a niche is defined by a recurring local cellular composition, rather than by the expression profile of an individual observation. For example, cells surrounded by many immune cells and fibroblasts may be assigned to one niche even when those cells themselves have different expression profiles or cell-type labels.

Parameters:
  • adata – Annotated data object.

  • groups (str) – Column in adata.obs containing categorical labels used to define neighborhood composition, such as cell types, cell states, clusters, or anatomical annotations.

  • resolutions (float | list[float]) – Resolution parameter(s) for Leiden clustering. A single value produces one niche annotation. Supplying multiple values performs Leiden clustering separately for each resolution and adds one niche column per resolution to adata.obs.

  • n_neighbors (int) – Number of nearest neighbors used to construct the k-nearest-neighbor graph on the neighborhood composition embedding before Leiden clustering.

  • spatial_connectivities_key (str) – Key in anndata.AnnData.obsp containing the spatial connectivity matrix.

  • scale (bool) – Whether to z-score each neighborhood-profile feature across observations before constructing the clustering graph.

  • distance (int) – Maximum number of graph hops used to construct each neighborhood profile. distance=1 uses direct spatial neighbors. Larger values incorporate increasingly distal observations in the spatial graph.

  • abs_nhood (bool) –

    Whether to use absolute group counts in the neighborhood profile.

    If False (the default), counts are normalized to proportions, so each profile captures relative neighborhood composition and is less sensitive to differences in neighborhood size.

    If True, raw counts are retained, so both composition and the total number of reachable neighbors can influence the embedding.

  • n_hop_weights (list[float] | None) – Optional weights used when combining contributions from successive graph-hop distances. If provided, the weights determine the relative contribution of direct and higher-order neighbors to the final neighborhood profile. If not provided, equal weights are used.

  • cluster_mask (Series | None) – Boolean pandas.Series indexed like anndata.AnnData.obs. False observations are labeled 'not_a_niche' and take no part in the clustering, though they still reach their neighbors through the graph. Observations it omits are kept. To drop them from the graph as well, subset and rebuild it with spatial_neighbors().

  • key_added (str) – Stem of the anndata.AnnData.obs columns the labels are written to, one per resolution, named f"{key_added}_res={resolution}".

  • embedding_key_added (str) – Controls the name of the key to be added in anndata.AnnData.obsm, which will hold the niche embedding computed.

  • min_niche_size (int | None) – Minimum number of observations required for a niche. Niches with fewer observations are relabeled 'not_a_niche'.

  • copy (bool) – If True, return the result, otherwise save it to the adata 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.

  • flavor (Literal['igraph', 'leidenalg']) – Leiden backend passed to scanpy.tl.leiden(). Defaults to 'igraph' (the 'leidenalg' backend is deprecated in scanpy).

  • n_iterations (int) – Number of Leiden iterations. -1 iterates until convergence.

  • 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. Every resolution is clustered with an independent rng derived from it.

Return type:

AnnData | None

Returns:

If copy=True, returns a copy of adata with the neighborhood profile stored in .obsm[embedding_key_added] and niche assignments added to .obs. Otherwise, modifies adata in place and returns None.

Notes

This approach is most appropriate when niches are expected to differ primarily in local cellular composition. In contrast, calculate_niche_utag() and calculate_niche_cellcharter() derive niche embeddings from spatially aggregated molecular or latent features rather than from categorical group frequencies.