Analyzes spatial transcriptomics with squidpy (1.8.x) on AnnData and SpatialData objects, routing platforms correctly: Visium spots use spatial_neighbors(coord_type='grid') and pair with deconvolution, while Xenium/MERFISH single-cell data use coord_type='generic'/Delaunay neighbors and spatialdata-io readers (xenium, visium_hd, merscope). Runs sq.gr.spatial_neighbors, nhood_enrichment, co_occurrence, spatial_autocorr (Moran's I for spatially variable genes), ripley, and ligrec. Use when the ...
Scanned 9/6/2026
Install to Claude Code
npx -y skills add AlterLab-IEU/AlterLab-Academic-Skills --skill alterlab-squidpy-spatial --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Alterlab Squidpy Spatial?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/alterlab-ieu-alterlab-squidpy-spatial)More formats (shields.io, HTML) on the badges page.
---
name: alterlab-squidpy-spatial
description: "Analyzes spatial transcriptomics with squidpy (1.8.x) on AnnData and SpatialData objects, routing platforms correctly: Visium spots use spatial_neighbors(coord_type='grid') and pair with deconvolution, while Xenium/MERFISH single-cell data use coord_type='generic'/Delaunay neighbors and spatialdata-io readers (xenium, visium_hd, merscope). Runs sq.gr.spatial_neighbors, nhood_enrichment, co_occurrence, spatial_autocorr (Moran's I for spatially variable genes), ripley, and ligrec. Use when the user wants spatial transcriptomics, squidpy, Visium/Xenium/MERFISH analysis, neighborhood enrichment, co-occurrence, or spatially variable genes; QC/clustering uses alterlab-scanpy and spot deconvolution (destVI/Tangram) uses alterlab-scvi-tools. Part of the AlterLab Academic Skills suite."
license: MIT
allowed-tools: Read Write Edit Bash(python:*) Bash(uv:*)
compatibility: "Self-contained — runs under `uv run python` with squidpy (1.8.x, needs spatialdata>=0.7.1, scanpy>=1.9.3, anndata>=0.9, Python>=3.11) installed; no API key or account required."
metadata:
skill-author: AlterLab
version: "1.0.0"
---
# Squidpy: Spatial Transcriptomics
Squidpy is the scverse toolkit for spatially-resolved omics, built on AnnData and
SpatialData. It answers questions a non-spatial scRNA-seq pipeline cannot: *which
cell types sit next to which* (neighborhood enrichment), *how cell-type pairs
co-occur across distance* (co-occurrence), *which genes vary across tissue space*
(Moran's I / spatially variable genes), and *what ligand-receptor signalling is
plausible* (ligrec). This skill does the spatial analysis; it hands non-spatial
QC/clustering to `alterlab-scanpy` and spot deconvolution to `alterlab-scvi-tools`.
## When to Use This Skill
Use when the request involves:
- Spatial transcriptomics / spatially-resolved omics on **Visium, Visium HD, Xenium,
MERFISH/MERSCOPE, or CosMx** data.
- Building a **spatial neighbor graph** and running **neighborhood enrichment**,
**co-occurrence**, **interaction matrix**, **Ripley's statistics**, or
**centrality scores**.
- Finding **spatially variable genes** via Moran's I (`spatial_autocorr`) or Sepal.
- **Ligand-receptor** analysis in a spatial context (`ligrec`).
- Reading platform output into AnnData/SpatialData and choosing the right
`coord_type` for the platform.
### Does NOT Trigger
| Request | Route to |
|---------|----------|
| Non-spatial scRNA-seq QC, normalization, PCA/UMAP, Leiden clustering, marker genes | `alterlab-scanpy` |
| Spot **deconvolution** / mapping cell types to Visium spots (destVI, Tangram), probabilistic batch correction/integration | `alterlab-scvi-tools` (see its `references/models-spatial.md`) |
| Building/slicing/concatenating `.h5ad` AnnData objects, layer & obsm wrangling (no spatial analysis) | `alterlab-anndata` |
| RNA-velocity / trajectory dynamics | `alterlab-scvelo` |
| Bulk RNA-seq **differential expression** from a count matrix | `alterlab-pydeseq2` |
| Raw FASTQ → expression matrix (read alignment/quantification) | `alterlab-rnaseq-quant` |
| Diversity / ecology statistics on a feature table | `alterlab-scikit-bio` |
If the user wants the *whole* pipeline ("cluster my Xenium data, then find which
cell types are neighbors"), run the scanpy clustering step under `alterlab-scanpy`
first, then return here for the spatial graph and enrichment.
## The One Decision That Matters: Platform → coord_type
Squidpy's spatial graph depends on the measurement geometry. Getting `coord_type`
wrong silently produces a meaningless graph. (All parameter behavior below is from
the squidpy 1.8 `sq.gr.spatial_neighbors` API.)
| Platform | Resolution | Builder | Pair with |
|----------|-----------|---------|-----------|
| **Visium** | spot (multi-cell, hex grid) | `coord_type="grid"`, `n_neighs=6`, `n_rings=1..2` | deconvolution → `alterlab-scvi-tools` |
| **Visium HD** | 2/8/16 µm bins (square grid) | `coord_type="grid"` (square lattice) | binning choice up front |
| **Xenium / MERFISH / CosMx** | single cell | `coord_type="generic"`, `delaunay=True` (or `n_neighs=k`) | direct cell-type analysis |
- `coord_type=None` auto-picks `"grid"` only when `spatial` is in `adata.uns` with
`n_neighs=6` (the Visium signature); otherwise it falls back to `"generic"`. **Set
`coord_type` explicitly** rather than relying on auto-detection.
- `delaunay=True` is only used when `coord_type="generic"`; it builds the graph from
a Delaunay triangulation instead of k-nearest spots. `n_rings` is only used for
`coord_type="grid"`.
## Loading Data (pick the reader for the platform)
```python
import squidpy as sq
import scanpy as sc
# Visium (legacy spot data) — squidpy's own reader, returns AnnData
adata = sq.read.visium("path/to/visium_outs/")
# Vizgen MERSCOPE / Nanostring CosMx via squidpy readers
adata = sq.read.vizgen("path/to/merscope/", counts_file="cell_by_gene.csv",
meta_file="cell_metadata.csv")
adata = sq.read.nanostring("path/to/cosmx/", counts_file="exprMat_file.csv",
meta_file="metadata_file.csv", fov_file="fov_positions.csv")
```
For **Xenium and Visium HD**, use the **`spatialdata-io`** readers (squidpy has no
`sq.read.xenium`) and operate on a `SpatialData` object:
```python
from spatialdata_io import xenium, visium_hd, merscope
sdata = xenium("path/to/xenium_outs/") # 10x Xenium
sdata = visium_hd("path/to/visium_hd_outs/") # 10x Visium HD
sdata = merscope("path/to/merscope/") # Vizgen MERSCOPE
```
`spatialdata-io` reader names are verified against the spatialdata-io stable API.
Squidpy 1.8 accepts SpatialData objects directly; see
`references/spatialdata_io.md` for the SpatialData ↔ AnnData (table) flow.
## Standard Spatial Workflow
QC, normalization, HVGs, PCA, neighbors, Leiden, and `sc.tl.umap` are **scanpy**
steps — run them via `alterlab-scanpy`. Once you have clusters / cell-type labels,
do the spatial part here.
```python
import squidpy as sq
# 1. Build the spatial neighbor graph (choose coord_type per the table above)
sq.gr.spatial_neighbors(adata, coord_type="generic", delaunay=True) # Xenium/MERFISH
# sq.gr.spatial_neighbors(adata, coord_type="grid", n_neighs=6) # Visium
# 2. Neighborhood enrichment: which cluster pairs are spatially adjacent?
sq.gr.nhood_enrichment(adata, cluster_key="leiden")
sq.pl.nhood_enrichment(adata, cluster_key="leiden")
# 3. Co-occurrence across distance
sq.gr.co_occurrence(adata, cluster_key="leiden")
sq.pl.co_occurrence(adata, cluster_key="leiden", clusters="0")
# 4. Spatially variable genes via Moran's I
sq.gr.spatial_autocorr(adata, mode="moran")
svgs = adata.uns["moranI"].head(20) # ranked by Moran's I
# 5. Ligand-receptor interaction (Omnipath-backed)
sq.gr.ligrec(adata, cluster_key="leiden")
```
Other graph statistics: `sq.gr.interaction_matrix`, `sq.gr.centrality_scores`,
`sq.gr.ripley` (clustering/dispersion vs. CSR), and `sq.gr.sepal` (an alternative
spatially-variable-gene test). Visualize tissue with `sq.pl.spatial_scatter`
(spot/point) or `sq.pl.spatial_segment` (segmented cells). For image features on
H&E/IF, the `sq.im` module (`process`, `segment`, `calculate_image_features`)
operates on an `ImageContainer`.
**Helper script** — build the graph and run the core statistics in one call:
```bash
uv run python skills/bioinformatics/alterlab-squidpy-spatial/scripts/spatial_neighborhood.py \
clustered.h5ad --platform xenium --cluster-key leiden --out spatial_report.json
```
See `scripts/spatial_neighborhood.py --help`. It chooses `coord_type` from
`--platform`, runs `spatial_neighbors`, `nhood_enrichment`, `co_occurrence`, and
`spatial_autocorr`, and writes a JSON summary (top spatially variable genes + the
enrichment z-score matrix) plus the updated `.h5ad`.
## Deeper References
- `references/platform_routing.md` — full platform→`coord_type` decision table, the
`n_neighs`/`n_rings`/`delaunay` parameter semantics, and per-platform gotchas.
- `references/analysis_recipes.md` — copy-paste recipes for each `sq.gr` / `sq.pl`
function with the parameters that matter and how to read the outputs.
- `references/spatialdata_io.md` — reading Xenium / Visium HD / MERSCOPE into
SpatialData and getting the AnnData `table` squidpy operates on.
## Self-Check Before Reporting
- Did you set `coord_type` to match the platform (grid for Visium, generic for
single-cell)? A wrong graph invalidates every downstream statistic.
- Did clustering/QC run under `alterlab-scanpy` (this skill assumes labels exist)?
- For Visium spot data, did you flag that **deconvolution** (`alterlab-scvi-tools`)
is needed before cell-type-level claims — spots are multi-cell?
- Are `nhood_enrichment` z-scores reported with the permutation context, not as raw
counts?
Part of the AlterLab Academic Skills suite.
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!