Spatial analysis¶
Spatial neighborhood-graph statistics and message passing over the physical-distance graph.
- class phenocoder.spatial.SpatialGraphAnalyzer(adata, cluster_key, spatial_key, radii, index, stats=None, chull_min_nds=10, chull_min_degree=3)[source]¶
Bases:
objectAnalyzer for computing spatial graph statistics on spatial omics data.
This class provides comprehensive analysis of spatial relationships between cells and cell clusters in spatial transcriptomics or imaging data. It constructs spatial neighborhood graphs at multiple radii and computes various statistics including interaction matrices, spatial autocorrelation, centrality scores, connectivity metrics, and convex hull properties.
- Typical workflow:
Initialize with AnnData object and analysis parameters
Call run() to compute all statistics across all specified radii
Call to_df() to get results as a single DataFrame
- Parameters:
- adata¶
Annotated data object with spatial coordinates and cluster labels.
- Type:
ad.AnnData
Example
>>> analyzer = SpatialGraphAnalyzer( ... adata=adata_sample, ... cluster_key='leiden', ... spatial_key='spatial', ... radii=(25, 50, 100), ... index='sample_001' ... ) >>> analyzer.run() >>> df_stats = analyzer.to_df()
- VALID_STATS = ('interactions', 'centrality', 'connectivity', 'moran_features', 'moran_clusters', 'chull')¶
Stat groups that can be selected via the
statsargument.
- get_chull(radius=100, degree_threshold=5)[source]¶
Calculate convex hull volume, area, and density for spatial data.
Operates on
self.adata(uses the ‘z’, ‘centroid-0’, ‘centroid-1’ obs columns).
- get_chulls_connected_components(clusters, radius=100, min_nds=10, min_degree=4)[source]¶
Calculate convex hull for connected components in subset of spatial graph.
- Parameters:
clusters (list) – List of cluster identifiers to include (matched against self.cluster_key).
radius (int) – Radius for neighbor graph construction. Defaults to 100.
min_nds (int) – Minimum number of nodes for connected components. Defaults to 10.
min_degree (int) – Drop nodes with fewer than this many connections before extracting components. Defaults to 3.
- Returns:
DataFrame containing convex hull metrics for each connected component.
- Return type:
pd.DataFrame
- get_interactions()[source]¶
Calculate interaction matrices between clusters.
Computes both normalized and raw cluster-cluster interaction counts on
self.adata(requires spatial neighbors to have been computed).- Returns:
- DataFrame containing normalized and raw interaction counts, one row indexed
by self.index.
- Return type:
pd.DataFrame
- get_moran()[source]¶
Calculate Moran’s I spatial autocorrelation for features.
Operates on
self.adata.varfeatures using the precomputedspatial_connectivities; returns zeros if the graph has no edges.- Returns:
- DataFrame containing Moran’s I values for each feature, one row indexed
by self.index.
- Return type:
pd.DataFrame
- get_moran_cluster()[source]¶
Calculate Moran’s I spatial autocorrelation for cluster assignments.
One-hot encodes
self.cluster_keyand computes Moran’s I per cluster using the precomputedspatial_connectivities; returns zeros if the graph has no edges.- Returns:
- DataFrame containing Moran’s I values for each cluster, one row indexed
by self.index.
- Return type:
pd.DataFrame
- get_centrality()[source]¶
Calculate centrality scores between clusters.
Computes pairwise centrality scores that measure how central each cluster is relative to other clusters in the spatial graph.
- Returns:
- DataFrame containing centrality scores for each cluster pair, with one row
indexed by self.index and columns named ‘centrality_{from}_{to}’.
- Return type:
pd.DataFrame
- get_connectivity()[source]¶
Calculate connectivity statistics (degree) for the spatial graph.
Computes the mean and standard deviation of node degrees (number of neighbors) both globally and per cluster.
- Returns:
- DataFrame with one row indexed by self.index containing:
’mean’: Mean degree across all nodes
’std’: Standard deviation of degree across all nodes
’mean_degree_{cluster}’: Mean degree for each cluster
’std_degree_{cluster}’: Standard deviation of degree for each cluster
- Return type:
pd.DataFrame
- get_counts()[source]¶
Calculate cell counts per cluster.
Computes the number of cells in each cluster and the total number of cells.
- Returns:
- DataFrame with one row indexed by self.index containing:
’cluster’: Cluster label
’count’: Number of cells in the cluster
’total’: Total number of cells across all clusters
- Return type:
pd.DataFrame
- get_spatial_stats(radius)[source]¶
Calculate the selected spatial statistics for a sample.
Only the stat groups in
self.statsare computed (seestatsin the class constructor).
- to_df()[source]¶
Collect the computed statistics into a single-row DataFrame.
Concatenates the per-radius, per-stat-group results (populated by
run()) into one row indexed byself.index. Column names are prefixed withradius:{radius}_stat:{group}_so every statistic is traceable to the radius and stat group it came from.- Returns:
One row of spatial statistics for this sample/subunit.
- Return type:
pd.DataFrame
- run()[source]¶
Compute all selected spatial statistics across every configured radius.
Populates
self.results(a dict keyed by radius) by callingget_spatial_stats()for each radius inself.radii. Callto_df()afterwards to collect the results into a DataFrame.- Returns:
None
- Return type:
None
- phenocoder.spatial.spatial_message_passing(adata, radius)[source]¶
Smooth latent representations over a spatial neighborhood graph.
Builds a radius-based spatial connectivity graph in physical space, adds self-loops, and applies a degree-normalized adjacency matrix
A' = (A + I) · D⁻¹toadata.X. Each object’s smoothed latent is the (degree-normalized) average of itself and its spatial neighbors. The result is stored inadata.layers['spatial_message_passing'].- Parameters:
adata (ad.AnnData) – Annotated data with latents in
.Xand spatial coordinates in.obsm['spatial'](falls back to the ‘x’, ‘y’, ‘z’ obs columns if ‘spatial’ is missing).radius (int) – Radius (in spatial units) used to connect neighboring objects.
- Returns:
- The same object, with the smoothed latents added as
.layers['spatial_message_passing'].
- Return type:
ad.AnnData