Define relative positioning of cells along a spatial axis in spatial biology data.
Spatial Axis is a Python package for analyzing the relative positioning of cells along anatomical or spatial axes. It's particularly useful for spatial biology applications where you need to understand how cells are distributed along defined gradients or anatomical structures.
The package allows you to:
- Define spatial axes using anatomical annotations
- Calculate relative positions of cells along these axes
- Handle various data formats (AnnData, GeoDataFrame, numpy arrays)
- Visualize spatial relationships
git clone https://github.com/callum-jpg/spatial_axis.git
cd spatial_axis
pip install -e .import geopandas
from spatial_axis import spatial_axis
# Create example cell data
cells = geopandas.GeoDataFrame(...) # Your cell geometries
# Define anatomical annotations
annotations = geopandas.GeoDataFrame(...) # Your anatomical regions
# Calculate spatial axis
annotation_order = [0, 1, 2, 3, 4] # Order along the axis
cells['spatial_axis'] = spatial_axis(
cells,
annotations,
annotation_order,
k_neighbours=5
)- AnnData: Integration with scanpy/squidpy workflows
- GeoDataFrame: Direct spatial data analysis
- NumPy arrays: Label-based analysis
- Polygon-based anatomical regions
- Label array-based annotations
- Exclusion of specific regions
- Missing data handling
- K-nearest neighbors for spatial smoothing
- Configurable weighting schemes
- Validation and preprocessing
from spatial_axis import spatial_axis
from spatial_axis.utility import random_shapely_circles, create_broad_annotation_polygons
import geopandas
import numpy
# Generate example data
IMG_SHAPE = (256, 256)
cells = random_shapely_circles(IMG_SHAPE, num_circles=200, seed=42)
cells_gdf = geopandas.GeoDataFrame(geometry=cells)
# Create anatomical annotations
annotations = create_broad_annotation_polygons(
IMG_SHAPE,
annotation_shape="circle",
num_levels=5
)
annotations_gdf = geopandas.GeoDataFrame(geometry=annotations)
# Calculate spatial axis
annotation_order = numpy.arange(5)
cells_gdf['spatial_axis'] = spatial_axis(
cells_gdf,
annotations_gdf,
annotation_order,
k_neighbours=5
)# Use rasterized label arrays instead of polygons
from rasterio.features import rasterize
labeled_annotations = rasterize(
[(poly, idx) for idx, poly in enumerate(annotations)],
out_shape=IMG_SHAPE
)
cells_gdf['spatial_axis'] = spatial_axis(
cells_gdf,
labeled_annotations,
annotation_order,
k_neighbours=5
)import anndata
# Load your spatial data
adata = anndata.read_h5ad("spatial_data.h5ad")
# Calculate spatial axis
adata.obs['spatial_axis'] = spatial_axis(
adata,
annotations,
annotation_order,
annotation_column='region_id'
)# Exclude specific annotation regions
cells['spatial_axis'] = spatial_axis(
cells,
annotations,
annotation_order,
broad_annotations_to_exclude=[-1, 999] # Exclude background/artifact regions
)# Apply custom weights to annotations
weights = [1.0, 1.5, 2.0, 1.5, 1.0] # Emphasize central regions
cells['spatial_axis'] = spatial_axis(
cells,
annotations,
annotation_order,
weights=weights
)# Handle cells not assigned to any annotation
cells['spatial_axis'] = spatial_axis(
cells,
annotations,
annotation_order,
missing_annotation_method="knn", # Use k-nearest neighbors
k_neighbours=10
)