Skip to content
Back to skills

Alterlab Squidpy Spatial

ASecurity

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 ...

  • 158 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added October 6, 2026
toolspythongobashexpressapi

Works with

  • api

Security analysis

A100/100

Pro scans all 6 files and shows the line behind each finding

Scanned October 6, 2026

npx -y skills add NVlabs/Skill2Env --skill alterlab-squidpy-spatial --agent claude-code

Installs 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 with every re-scan.

Security grade badge for Alterlab Squidpy Spatial
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/nvlabs-alterlab-squidpy-spatial/badge)](https://www.skillsdirectory.com/skills/nvlabs-alterlab-squidpy-spatial)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
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.

Files in this skill

  • SKILL.md8.7 KB
  • evals/evals.json5.6 KB
  • references/analysis_recipes.md3.8 KB
  • references/platform_routing.md3.6 KB
  • references/spatialdata_io.md2.8 KB
  • scripts/spatial_neighborhood.py6.4 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…