# Squidpy

> Comprehensive toolkit for spatial single-cell analysis in Python with MCP DeepWiki integration. Use this skill when users need to: (1) Build and analyze spatial neighbor graphs from spatial coordinates, (2) Compute spatial statistics for cell types and genes (Moran's I, co-occurrence, neighborhood enrichment), (3) Analyze tissue images and extract image features, (4) Identify spatial niches using neighborhood profiles, UTAG, or CellCharter algorithms, (5) Perform ligand-receptor interaction analysis, (6) Read spatial omics data from various platforms (Visium, MERFISH, CosMx, Xenium) using squidpy.read or spatialdata_io, or (7) Visualize spatial data and analysis results.

- Skill: `non-lab/squidpy` (Agent Skill, multi-file: 5 files)
- Install (CLI): `npx skillmds@latest add non-lab/squidpy`
- Raw SKILL.md: https://api.skillmd.com/api/skills/non-lab/squidpy/raw
- Safety review: pending (external: skill-scanner PASS, skillspector PASS)
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: AI & ML
- Author: non-lab (https://skillmd.com/u/non-lab)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/non-lab/squidpy

---


# Squidpy - Spatial Single Cell Analysis in Python

## 概述

Squidpy 是一个用于分析和可视化空间分子数据的 Python 工具包。它构建在 scanpy 和 anndata 之上，继承了模块化和可扩展性。Squidpy 提供了利用数据空间坐标以及组织图像（如果可用）的分析工具。

Squidpy 是 scverse 生态系统（website, governance）的核心组件，与 scanpy、anndata、muon、spatialdata-io 等工具紧密集成。

**MCP DeepWiki 集成**：本 skill 完全支持通过 **MCP DeepWiki** 获取 squidpy 的最新文档和信息。当需要最新 API 文档、教程、特定函数的使用说明或遇到问题时，**强烈建议使用 DeepWiki 查询功能**。DeepWiki 提供对 scverse/squidpy GitHub 仓库的深度访问，确保获取的信息是最新和准确的。使用方法见"资源"部分的详细说明。

## 核心模块

Squidpy 的 API 组织为几个主要模块，所有函数都通过 `squidpy` 命名空间暴露：

### 空间图分析模块 (`squidpy.gr`)

用于构建和分析空间邻域图，计算空间统计量：

**空间图构建**：
- `squidpy.gr.spatial_neighbors`: 从空间坐标构建空间邻域图（支持 KNN、Delaunay 三角剖分、半径方法）
- `squidpy.gr.mask_graph`: 使用多边形掩码进行空间图过滤

**空间统计**：
- `squidpy.gr.spatial_autocorr`: 计算 Moran's I 或 Geary's C 空间自相关统计量
- `squidpy.gr.co_occurrence`: 计算细胞类型簇的共现概率
- `squidpy.gr.ripley`: 计算 Ripley's 统计量（F、G 或 L）
- `squidpy.gr.sepal`: 通过基于扩散的模拟识别空间可变基因

**邻域分析**：
- `squidpy.gr.nhood_enrichment`: 执行基于排列的邻域富集测试
- `squidpy.gr.centrality_scores`: 计算网络中心性度量
- `squidpy.gr.interaction_matrix`: 生成簇-簇相互作用矩阵

**生态位分析**：
- `squidpy.gr.calculate_niche`: 使用不同算法识别空间生态位（neighborhood profile、UTAG、CellCharter）

**配体-受体分析**：
- `squidpy.gr.ligrec`: 执行配体-受体相互作用分析

### 图像分析模块 (`squidpy.im`)

提供组织图像分析和特征提取功能：

**图像容器**：
- `squidpy.im.ImageContainer`: 存储多维图像，支持大图像的延迟加载

**特征提取**：
- `squidpy.im.features_summary`: 计算图像通道的摘要统计
- `squidpy.im.features_histogram`: 计算直方图特征
- `squidpy.im.features_texture`: 计算纹理特征
- `squidpy.im.features_segmentation`: 计算分割特征
- `squidpy.im.features_custom`: 使用自定义函数计算特征

**图像处理**：
- `ImageContainer.apply`: 对图像层应用函数
- `ImageContainer.crop`: 裁剪图像
- `ImageContainer.to_gray`: 转换为灰度图像

### 可视化模块 (`squidpy.pl`)

提供可视化函数，通常镜像 `squidpy.gr` 函数来绘制结果：

**空间可视化**：
- `squidpy.pl.spatial_scatter`: 在空间坐标中绘制散点图
- `squidpy.pl.spatial`: 通用空间可视化

**统计可视化**：
- `squidpy.pl.nhood_enrichment`: 邻域富集可视化
- `squidpy.pl.centrality_scores`: 中心性得分可视化
- `squidpy.pl.interaction_matrix`: 相互作用矩阵可视化
- `squidpy.pl.ripley`: Ripley's 统计量可视化
- `squidpy.pl.ligrec`: 配体-受体相互作用可视化

**图像可视化**：
- `squidpy.pl.image_container`: 可视化图像容器

### 数据导入模块 (`squidpy.read`)

提供从各种平台导入空间组学数据的函数：

**平台特定读取器**：
- `squidpy.read.visium`: 加载 10x Genomics Visium 数据
- `squidpy.read.vizgen`: 导入 Vizgen MERFISH 数据
- `squidpy.read.nanostring`: 处理 Nanostring CosMx 数据

**注意**：对于某些平台，也可以使用 `spatialdata-io` 包进行数据读取，它提供了更统一的数据格式（SpatialData 对象）。**强烈建议使用 spatialdata-io skill** 来读取以下平台的数据：
- `spatialdata_io.xenium`: 读取 10x Xenium 数据
- `spatialdata_io.merscope`: 读取 Vizgen MERSCOPE (MERFISH) 数据
- `spatialdata_io.cosmx`: 读取 Nanostring CosMx 数据
- `spatialdata_io.codex`: 读取 Akoya PhenoCycler (CODEX) 数据
- `spatialdata_io.visium_hd`: 读取 10x Visium HD 数据
- `spatialdata_io.seqfish`: 读取 Spatial Genomics seqFISH 数据
- `spatialdata_io.stereoseq`: 读取 BGI Stereo-seq 数据
- `spatialdata_io.dbit`: 读取 DBiT-seq 数据
- `spatialdata_io.curio`: 读取 Curio Seeker 数据

使用 `spatialdata-io` 读取的数据是 `SpatialData` 对象，可以通过 `sdata.tables["table"]` 提取 AnnData 对象用于后续分析。

### 数据集模块 (`squidpy.datasets`)

提供示例数据集用于测试和演示：

- `squidpy.datasets.visium_fluo_adata`: Visium 荧光数据示例
- `squidpy.datasets.imaging_mass_cytometry`: 成像质谱流式数据示例
- `squidpy.datasets.seqfish`: seqFISH 数据示例

## 数据读取方法对比

### 方法 1: 使用 squidpy.read（直接读取为 AnnData）

**适用平台**：
- 10x Visium（推荐）
- Vizgen MERFISH
- Nanostring CosMx

**优点**：
- 直接返回 AnnData 对象，与 scanpy 无缝集成
- 简单直接，适合快速分析

**缺点**：
- 支持的平台有限
- 图像和多模态数据处理能力较弱

### 方法 2: 使用 spatialdata-io（读取为 SpatialData，推荐用于大多数平台）

**适用平台**：
- 10x Xenium（强烈推荐）
- 10x Visium HD（推荐）
- Vizgen MERSCOPE / MERFISH（推荐）
- Nanostring CosMx（推荐）
- Akoya PhenoCycler (CODEX)（必须使用）
- Spatial Genomics seqFISH（推荐）
- BGI Stereo-seq（推荐）
- DBiT-seq（推荐）
- Curio Seeker（推荐）

**优点**：
- 统一的数据格式（SpatialData 对象）
- 更好的图像和多模态数据支持
- 支持更多平台
- 自动处理数据格式转换和坐标系统
- 支持多分辨率图像金字塔

**缺点**：
- 需要从 SpatialData 提取 AnnData（`sdata.tables["table"]`）

**使用 spatialdata-io skill**：
当需要读取上述平台的数据时，**强烈建议调用 spatialdata-io skill**，它提供了完整的文档和示例。spatialdata-io skill 包含：
- 所有 reader 函数的详细 API 文档
- 每个平台的具体使用示例
- 坐标系统和转换的详细说明
- 最佳实践和性能优化建议

## 不同测序平台的分析示例

### 10x Visium 数据分析

**方法 1: 使用 squidpy.read.visium（推荐）**

```python
import scanpy as sc
import squidpy as sq
import numpy as np

# 设置参数
sc.settings.verbosity = 3
sc.settings.set_figure_params(dpi=80, facecolor='white')
np.random.seed(42)

# 1. 加载 Visium 数据
adata = sq.read.visium(
    path="data/visium_data/",
    library_id="sample1",
    counts_file="filtered_feature_bc_matrix.h5",
    load_images=True
)

# 2. 标准预处理
sc.pp.calculate_qc_metrics(adata, percent_top=None, log1p=False, inplace=True)
sc.pp.normalize_total(adata, target_sum=1e4)
sc.pp.log1p(adata)
sc.pp.highly_variable_genes(adata, min_mean=0.0125, max_mean=3, min_disp=0.5)
adata = adata[:, adata.var.highly_variable]
sc.pp.scale(adata, max_value=10)
sc.tl.pca(adata, svd_solver='arpack')
sc.pp.neighbors(adata, n_neighbors=10, n_pcs=40)
sc.tl.umap(adata)
sc.tl.leiden(adata, resolution=0.5, random_state=42)

# 3. 空间分析（网格坐标）
sq.gr.spatial_neighbors(adata, coord_type="grid", n_neighs=6)
sq.gr.spatial_autocorr(adata, mode="moran", n_perms=100, n_jobs=1)
sq.gr.nhood_enrichment(adata, cluster_key="leiden", n_perms=100, seed=42)

# 4. 可视化
sq.pl.spatial_scatter(adata, color="leiden", library_id="sample1")
sq.pl.nhood_enrichment(adata, cluster_key="leiden")
```

**方法 2: 使用 spatialdata-io（适用于 Visium HD）**

```python
import scanpy as sc
import squidpy as sq
from spatialdata_io import visium_hd
from spatialdata import SpatialData

# 1. 加载 Visium HD 数据（必须使用 spatialdata-io）
sdata = visium_hd(
    path="data/visium_hd_data/",
    bin_size=[8, 16],  # 加载 8μm 和 16μm bins
    bins_as_squares=True
)

# 从 SpatialData 提取 AnnData
adata = sdata.tables["table"]

# 2-4. 后续分析与上述相同
```

### 10x Xenium 数据分析

**推荐方法: 使用 spatialdata-io（强烈推荐）**

```python
import scanpy as sc
import squidpy as sq
from spatialdata_io import xenium
from spatialdata import SpatialData
import numpy as np

# 设置随机种子
np.random.seed(42)

# 1. 加载 Xenium 数据（推荐使用 spatialdata-io）
sdata = xenium(
    path="data/xenium_data/",
    cells_boundaries=True,
    nucleus_boundaries=True,
    transcripts=True,
    morphology_focus=True,
    aligned_images=True
)

# 从 SpatialData 提取 AnnData 对象
adata = sdata.tables["table"]

# 2. 标准预处理（Xenium 是单细胞分辨率，数据质量通常较高）
sc.pp.calculate_qc_metrics(adata, percent_top=None, log1p=False, inplace=True)
sc.pp.normalize_total(adata, target_sum=1e4)
sc.pp.log1p(adata)
sc.pp.highly_variable_genes(adata, min_mean=0.0125, max_mean=3, min_disp=0.5)
adata = adata[:, adata.var.highly_variable]
sc.pp.scale(adata, max_value=10)
sc.tl.pca(adata, svd_solver='arpack')
sc.pp.neighbors(adata, n_neighbors=10, n_pcs=40)
sc.tl.umap(adata)
sc.tl.leiden(adata, resolution=0.5, random_state=42)

# 3. 空间分析（Xenium 使用通用坐标，单细胞分辨率）
# 使用 KNN 方法，根据细胞密度调整参数
sq.gr.spatial_neighbors(adata, coord_type="generic", n_neighs=10)
# 或使用半径方法（例如 50 微米）
# sq.gr.spatial_neighbors(adata, coord_type="generic", radius=50)

# 空间统计
sq.gr.spatial_autocorr(adata, mode="moran", n_perms=100, n_jobs=1)
sq.gr.nhood_enrichment(adata, cluster_key="leiden", n_perms=100, seed=42)
sq.gr.co_occurrence(adata, cluster_key="leiden")

# 4. 可视化
sq.pl.spatial_scatter(adata, color="leiden", size=1.0)
sq.pl.nhood_enrichment(adata, cluster_key="leiden")

# 5. 图像特征提取（如果可用）
if "morphology_focus" in sdata.images:
    img = sdata.images["morphology_focus"]
    sq.im.calculate_image_features(
        adata,
        img,
        features="summary",
        library_id="xenium"
    )
```

### Vizgen MERFISH / MERSCOPE 数据分析

**方法 1: 使用 squidpy.read.vizgen**

```python
import scanpy as sc
import squidpy as sq
import numpy as np

np.random.seed(42)

# 1. 加载 Vizgen MERFISH 数据
adata = sq.read.vizgen(
    path="data/vizgen_data/",
    library_id="sample1",
    counts_file="cell_by_gene.csv",
    meta_file="cell_metadata.csv",
    transformation_file="transformation_matrix.txt"  # 可选
)

# 2-4. 后续分析与上述相同
```

**方法 2: 使用 spatialdata-io（推荐用于 MERSCOPE）**

```python
import scanpy as sc
import squidpy as sq
from spatialdata_io import merscope
from spatialdata import SpatialData
import numpy as np

np.random.seed(42)

# 1. 加载 MERSCOPE 数据（推荐使用 spatialdata-io）
sdata = merscope(
    path="data/merscope_data/",
    transcripts=True,
    cells_boundaries=True
)

# 从 SpatialData 提取 AnnData 对象
adata = sdata.tables["table"]

# 2. 标准预处理
sc.pp.calculate_qc_metrics(adata, percent_top=None, log1p=False, inplace=True)
sc.pp.normalize_total(adata, target_sum=1e4)
sc.pp.log1p(adata)
sc.pp.highly_variable_genes(adata, min_mean=0.0125, max_mean=3, min_disp=0.5)
adata = adata[:, adata.var.highly_variable]
sc.pp.scale(adata, max_value=10)
sc.tl.pca(adata, svd_solver='arpack')
sc.pp.neighbors(adata, n_neighbors=10, n_pcs=40)
sc.tl.umap(adata)
sc.tl.leiden(adata, resolution=0.5, random_state=42)

# 3. 空间分析（MERFISH 使用通用坐标，单细胞分辨率）
# MERFISH 细胞密度较高，可以使用较小的半径或较多的邻居
sq.gr.spatial_neighbors(adata, coord_type="generic", n_neighs=15)
# 或使用半径方法
# sq.gr.spatial_neighbors(adata, coord_type="generic", radius=30)

# 空间统计
sq.gr.spatial_autocorr(adata, mode="moran", n_perms=100, n_jobs=1)
sq.gr.nhood_enrichment(adata, cluster_key="leiden", n_perms=100, seed=42)

# 4. 可视化
sq.pl.spatial_scatter(adata, color="leiden", size=0.5)
sq.pl.nhood_enrichment(adata, cluster_key="leiden")
```

### Nanostring CosMx 数据分析

**方法 1: 使用 squidpy.read.nanostring**

```python
import scanpy as sc
import squidpy as sq
import numpy as np

np.random.seed(42)

# 1. 加载 CosMx 数据
adata = sq.read.nanostring(
    path="data/cosmx_data/",
    library_id="sample1",
    counts_file="exprMat_file.csv",
    meta_file="metadata_file.csv",
    fov_file="fov_positions.csv"  # 可选
)

# 2-4. 后续分析与上述相同
```

**方法 2: 使用 spatialdata-io（推荐）**

```python
import scanpy as sc
import squidpy as sq
from spatialdata_io import cosmx
from spatialdata import SpatialData
import numpy as np

np.random.seed(42)

# 1. 加载 CosMx 数据（推荐使用 spatialdata-io）
sdata = cosmx(
    path="data/cosmx_data/",
    transcripts=True,
    cells=True
)

# 从 SpatialData 提取 AnnData 对象
adata = sdata.tables["table"]

# 2. 标准预处理
sc.pp.calculate_qc_metrics(adata, percent_top=None, log1p=False, inplace=True)
sc.pp.normalize_total(adata, target_sum=1e4)
sc.pp.log1p(adata)
sc.pp.highly_variable_genes(adata, min_mean=0.0125, max_mean=3, min_disp=0.5)
adata = adata[:, adata.var.highly_variable]
sc.pp.scale(adata, max_value=10)
sc.tl.pca(adata, svd_solver='arpack')
sc.pp.neighbors(adata, n_neighbors=10, n_pcs=40)
sc.tl.umap(adata)
sc.tl.leiden(adata, resolution=0.5, random_state=42)

# 3. 空间分析（CosMx 使用通用坐标）
sq.gr.spatial_neighbors(adata, coord_type="generic", n_neighs=10)
sq.gr.spatial_autocorr(adata, mode="moran", n_perms=100, n_jobs=1)
sq.gr.nhood_enrichment(adata, cluster_key="leiden", n_perms=100, seed=42)

# 4. 可视化
sq.pl.spatial_scatter(adata, color="leiden")
sq.pl.nhood_enrichment(adata, cluster_key="leiden")
```

### CODEX / Akoya PhenoCycler 空间蛋白质组学数据分析

**必须使用 spatialdata-io（squidpy 不直接支持）**

```python
import scanpy as sc
import squidpy as sq
from spatialdata_io import codex
from spatialdata import SpatialData
import numpy as np

np.random.seed(42)

# 1. 加载 CODEX 数据（必须使用 spatialdata-io）
codex_path = "path/to/codex_data/"
# 如果数据是 FCS 格式，使用 fcs=True；如果是 CSV，使用 fcs=False
sdata = codex(codex_path, fcs=True)

# 从 SpatialData 对象中提取 AnnData
adata = sdata.tables["table"]

# 2. 预处理（蛋白质组学数据）
# 过滤低质量细胞
sc.pp.filter_cells(adata, min_counts=1000)
# 对数转换
sc.pp.log1p(adata)
# 可选：标准化（z-score）
sc.pp.scale(adata)
# PCA 降维
sc.pp.pca(adata, n_comps=30)

# 3. 空间邻域图（CODEX 使用通用坐标，细胞不规则分布）
# 使用半径方法，根据细胞间距调整（例如 50 像素）
sq.gr.spatial_neighbors(adata, coord_type="generic", radius=50)

# 4. 聚类
sc.pp.neighbors(adata, use_rep="X_pca")
sc.tl.leiden(adata, resolution=1.0, random_state=42)
adata.obs["cluster"] = adata.obs["leiden"]

# 5. 空间统计分析
sq.gr.nhood_enrichment(adata, cluster_key="cluster", n_perms=1000, seed=42)
sq.gr.spatial_autocorr(adata, mode="moran", n_perms=100, n_jobs=1)

# 6. 可视化
sq.pl.spatial_scatter(adata, color="cluster", shape=None, size=20)
sq.pl.nhood_enrichment(adata, cluster_key="cluster")

# 7. 图像特征提取（如果可用）
if "image_name" in sdata.images:
    img = sdata.images["image_name"]
    sq.im.calculate_image_features(
        adata,
        img,
        features=["summary", "texture"],
        mask=None  # 如果有分割掩码，可以使用
    )
```

### seqFISH 数据分析

**推荐使用 spatialdata-io**

```python
import scanpy as sc
import squidpy as sq
from spatialdata_io import seqfish
from spatialdata import SpatialData
import numpy as np

np.random.seed(42)

# 1. 加载 seqFISH 数据（推荐使用 spatialdata-io）
sdata = seqfish(
    path="data/seqfish_data/",
    cells_as_shapes=True
)

# 从 SpatialData 提取 AnnData
adata = sdata.tables["table"]

# 2. 标准预处理
sc.pp.calculate_qc_metrics(adata, percent_top=None, log1p=False, inplace=True)
sc.pp.normalize_total(adata, target_sum=1e4)
sc.pp.log1p(adata)
sc.pp.highly_variable_genes(adata, min_mean=0.0125, max_mean=3, min_disp=0.5)
adata = adata[:, adata.var.highly_variable]
sc.pp.scale(adata, max_value=10)
sc.tl.pca(adata, svd_solver='arpack')
sc.pp.neighbors(adata, n_neighbors=10, n_pcs=40)
sc.tl.umap(adata)
sc.tl.leiden(adata, resolution=0.5, random_state=42)

# 3. 空间分析（seqFISH 使用通用坐标）
# seqFISH 通常具有较高的空间分辨率
sq.gr.spatial_neighbors(adata, coord_type="generic", delaunay=True)
# 或使用 KNN
# sq.gr.spatial_neighbors(adata, coord_type="generic", n_neighs=10)

sq.gr.spatial_autocorr(adata, mode="moran", n_perms=100, n_jobs=1)
sq.gr.nhood_enrichment(adata, cluster_key="leiden", n_perms=100, seed=42)

# 4. 可视化
sq.pl.spatial_scatter(adata, color="leiden")
sq.pl.nhood_enrichment(adata, cluster_key="leiden")
```

### Stereo-seq 数据分析

**推荐使用 spatialdata-io**

```python
import scanpy as sc
import squidpy as sq
from spatialdata_io import stereoseq
from spatialdata import SpatialData
import numpy as np

np.random.seed(42)

# 1. 加载 Stereo-seq 数据（推荐使用 spatialdata-io）
sdata = stereoseq(
    path="data/stereoseq_data/",
    cells=True,
    bins=None  # 或指定 bin 大小
)

# 从 SpatialData 提取 AnnData
adata = sdata.tables["table"]

# 2. 标准预处理
sc.pp.calculate_qc_metrics(adata, percent_top=None, log1p=False, inplace=True)
sc.pp.normalize_total(adata, target_sum=1e4)
sc.pp.log1p(adata)
sc.pp.highly_variable_genes(adata, min_mean=0.0125, max_mean=3, min_disp=0.5)
adata = adata[:, adata.var.highly_variable]
sc.pp.scale(adata, max_value=10)
sc.tl.pca(adata, svd_solver='arpack')
sc.pp.neighbors(adata, n_neighbors=10, n_pcs=40)
sc.tl.umap(adata)
sc.tl.leiden(adata, resolution=0.5, random_state=42)

# 3. 空间分析（Stereo-seq 使用通用坐标，可能具有非常高的分辨率）
# Stereo-seq 数据密度可能很高，需要根据实际情况调整参数
sq.gr.spatial_neighbors(adata, coord_type="generic", n_neighs=10)
# 或使用半径方法
# sq.gr.spatial_neighbors(adata, coord_type="generic", radius=100)

sq.gr.spatial_autocorr(adata, mode="moran", n_perms=100, n_jobs=1)
sq.gr.nhood_enrichment(adata, cluster_key="leiden", n_perms=100, seed=42)

# 4. 可视化
sq.pl.spatial_scatter(adata, color="leiden", size=0.1)
sq.pl.nhood_enrichment(adata, cluster_key="leiden")
```

### 通用空间数据格式分析

对于其他格式的空间数据，如果已经加载到 AnnData 对象中，可以按照以下步骤进行分析：

```python
import scanpy as sc
import squidpy as sq
import pandas as pd
import numpy as np

np.random.seed(42)

# 1. 准备数据
# 确保 adata 包含：
# - 基因表达矩阵在 adata.X
# - 空间坐标在 adata.obsm['spatial']
# - 空间坐标格式为 (x, y) 或 (x, y, z)

# 如果没有空间坐标，需要手动添加
# adata.obsm['spatial'] = np.array([[x, y] for x, y in zip(adata.obs['x'], adata.obs['y'])])

# 2. 标准预处理
sc.pp.calculate_qc_metrics(adata, percent_top=None, log1p=False, inplace=True)
sc.pp.normalize_total(adata, target_sum=1e4)
sc.pp.log1p(adata)
sc.pp.highly_variable_genes(adata, min_mean=0.0125, max_mean=3, min_disp=0.5)
adata = adata[:, adata.var.highly_variable]
sc.pp.scale(adata, max_value=10)
sc.tl.pca(adata, svd_solver='arpack')
sc.pp.neighbors(adata, n_neighbors=10, n_pcs=40)
sc.tl.umap(adata)
sc.tl.leiden(adata, resolution=0.5, random_state=42)

# 3. 空间分析
# 根据数据特点选择合适的方法：
# - 均匀分布：使用 Delaunay 三角剖分
sq.gr.spatial_neighbors(adata, coord_type="generic", delaunay=True)
# - 非均匀分布：使用 KNN
# sq.gr.spatial_neighbors(adata, coord_type="generic", n_neighs=10)
# - 已知空间尺度：使用半径方法
# sq.gr.spatial_neighbors(adata, coord_type="generic", radius=50)

# 空间统计
sq.gr.spatial_autocorr(adata, mode="moran", n_perms=100, n_jobs=1)
sq.gr.nhood_enrichment(adata, cluster_key="leiden", n_perms=100, seed=42)

# 4. 可视化
sq.pl.spatial_scatter(adata, color="leiden")
sq.pl.nhood_enrichment(adata, cluster_key="leiden")
```

## 标准工作流程

### 1. 数据加载

Squidpy 支持多种空间组学平台的数据读取。可以使用 `squidpy.read` 模块直接读取，也可以使用 `spatialdata-io` 包读取（推荐用于某些平台，提供更统一的数据格式）。

#### 选择读取方法的建议

- **Visium**: 使用 `sq.read.visium`（squidpy 原生支持）
- **Xenium, MERSCOPE, CosMx, Visium HD, seqFISH, Stereo-seq**: 推荐使用 `spatialdata-io`，提供更好的数据格式和图像支持
- **CODEX**: 必须使用 `spatialdata-io`（squidpy 不直接支持）
- **其他平台**: 需要手动准备数据，确保空间坐标存储在 `adata.obsm['spatial']` 中

### 2. 标准单细胞分析（使用 scanpy）

```python
import scanpy as sc
import numpy as np

np.random.seed(42)

# 质量控制和预处理
sc.pp.calculate_qc_metrics(adata, percent_top=None, log1p=False, inplace=True)
sc.pp.normalize_total(adata, target_sum=1e4)
sc.pp.log1p(adata)
sc.pp.highly_variable_genes(adata, min_mean=0.0125, max_mean=3, min_disp=0.5)
adata = adata[:, adata.var.highly_variable]

# 降维和聚类
sc.pp.scale(adata, max_value=10)
sc.tl.pca(adata, svd_solver='arpack')
sc.pp.neighbors(adata, n_neighbors=10, n_pcs=40)
sc.tl.umap(adata)
sc.tl.leiden(adata, resolution=0.5, random_state=42)
```

### 3. 构建空间邻域图

```python
import squidpy as sq

# 构建空间邻域图（使用 Delaunay 三角剖分）
sq.gr.spatial_neighbors(adata, coord_type="generic", delaunay=True)

# 或使用 KNN 方法
sq.gr.spatial_neighbors(adata, coord_type="generic", n_neighs=6)

# 或使用半径方法
sq.gr.spatial_neighbors(adata, coord_type="generic", radius=100)

# 对于网格坐标（如 Visium）
sq.gr.spatial_neighbors(adata, coord_type="grid", n_neighs=6)
```

### 4. 空间统计分析

```python
# 空间自相关分析（Moran's I）
sq.gr.spatial_autocorr(
    adata,
    mode="moran",
    n_perms=100,
    n_jobs=1
)

# 查看结果
print(adata.uns["moranI"])

# 共现分析
sq.gr.co_occurrence(adata, cluster_key="leiden")

# 邻域富集分析
sq.gr.nhood_enrichment(adata, cluster_key="leiden", n_perms=100, seed=42)

# 中心性得分
sq.gr.centrality_scores(adata, cluster_key="leiden")

# 相互作用矩阵
sq.gr.interaction_matrix(adata, cluster_key="leiden")
```

### 5. 空间生态位分析

```python
# 使用 neighborhood profile 方法
sq.gr.calculate_niche(
    adata,
    flavor="neighborhood",
    groups="leiden",
    n_neighbors=10,
    resolutions=[0.5, 1.0, 1.5]
)

# 使用 UTAG 方法
sq.gr.calculate_niche(
    adata,
    flavor="utag",
    n_neighbors=10,
    resolutions=[0.5, 1.0]
)

# 使用 CellCharter 方法
sq.gr.calculate_niche(
    adata,
    flavor="cellcharter",
    distance=2,
    aggregation="mean",
    random_state=42
)
```

### 6. 配体-受体分析

```python
# 执行配体-受体相互作用分析
sq.gr.ligrec(
    adata,
    cluster_key="leiden",
    n_perms=1000,
    threshold=0.01
)

# 查看结果
print(adata.uns["ligrec"])
```

### 7. 图像分析（如果可用）

```python
# 加载图像
img = sq.im.ImageContainer(adata.uns["spatial"]["sample1"]["images"]["hires"])

# 提取图像特征
sq.im.calculate_image_features(
    adata,
    img,
    features="summary",
    library_id="sample1"
)

# 或提取纹理特征
sq.im.calculate_image_features(
    adata,
    img,
    features="texture",
    library_id="sample1"
)

# 或使用自定义特征提取函数
def custom_feature(img):
    return np.mean(img, axis=(0, 1))

sq.im.calculate_image_features(
    adata,
    img,
    features="custom",
    feature_func=custom_feature,
    library_id="sample1"
)
```

### 8. 可视化

```python
# 空间散点图
sq.pl.spatial_scatter(adata, color="leiden", library_id="sample1")

# 邻域富集热图
sq.pl.nhood_enrichment(adata, cluster_key="leiden")

# 中心性得分可视化
sq.pl.centrality_scores(adata, cluster_key="leiden")

# 相互作用矩阵可视化
sq.pl.interaction_matrix(adata, cluster_key="leiden")

# Ripley's 统计量可视化
sq.pl.ripley(adata, cluster_key="leiden", mode="L")

# 配体-受体相互作用可视化
sq.pl.ligrec(adata, cluster_key="leiden")
```

## 与 scanpy 集成工作流程

Squidpy 与 scanpy 无缝集成，可以在同一个 AnnData 对象上执行标准单细胞分析和空间分析：

```python
import scanpy as sc
import squidpy as sq
import numpy as np

np.random.seed(42)

# 1. 加载数据
adata = sq.read.visium(path="data/visium_data/")

# 2. 使用 scanpy 进行标准预处理
sc.pp.calculate_qc_metrics(adata, percent_top=None, log1p=False, inplace=True)
sc.pp.normalize_total(adata, target_sum=1e4)
sc.pp.log1p(adata)
sc.pp.highly_variable_genes(adata, min_mean=0.0125, max_mean=3, min_disp=0.5)
adata = adata[:, adata.var.highly_variable]
sc.pp.scale(adata, max_value=10)
sc.tl.pca(adata, svd_solver='arpack')
sc.pp.neighbors(adata, n_neighbors=10, n_pcs=40)
sc.tl.umap(adata)
sc.tl.leiden(adata, resolution=0.5, random_state=42)

# 3. 使用 squidpy 进行空间分析
sq.gr.spatial_neighbors(adata, coord_type="grid", n_neighs=6)
sq.gr.spatial_autocorr(adata, mode="moran", n_perms=100, n_jobs=1)
sq.gr.nhood_enrichment(adata, cluster_key="leiden", n_perms=100, seed=42)

# 4. 可视化
sc.pl.umap(adata, color="leiden")
sq.pl.spatial_scatter(adata, color="leiden", library_id="sample1")
sq.pl.nhood_enrichment(adata, cluster_key="leiden")
```

## 最佳实践

### 1. 空间图构建方法选择

不同平台需要选择不同的空间图构建方法：

- **网格坐标（Visium）**：使用 `coord_type="grid"`，通常 `n_neighs=6`（六边形网格）

- **通用坐标**（单细胞分辨率平台）：
  - **Visium、Xenium、MERFISH、CosMx、MERSCOPE**：使用 `coord_type="generic"`
  - **Delaunay 三角剖分**：适用于均匀分布的点，`delaunay=True`（如 seqFISH）
  - **KNN**：适用于非均匀分布，`n_neighs=6-15`（根据细胞密度调整）
    - Xenium、MERFISH、CosMx：通常 `n_neighs=10-15`
    - MERSCOPE：通常 `n_neighs=10`
  - **半径方法**：适用于已知空间尺度的分析，`radius=30-100`（单位取决于坐标）
    - CODEX：通常 `radius=50`（像素单位）
    - Xenium：通常 `radius=50`（微米单位）
    - MERFISH：通常 `radius=30`（微米单位）

- **空间蛋白质组学（CODEX、IMC 等）**：
  - 使用 `coord_type="generic"`，通常使用半径方法
  - 根据细胞间距调整半径参数

### 2. 空间统计参数设置

- **Moran's I**：
  - `n_perms`: 通常 100-1000，取决于数据大小和计算资源
  - `mode`: "moran" 或 "geary"，Moran's I 更常用
- **邻域富集**：
  - `n_perms`: 通常 100-1000
  - `n_neighs`: 应与空间图构建时的邻居数一致
  - `seed`: 设置随机种子以确保结果可重现
- **Ripley's 统计量**：
  - `n_simulations`: 通常 100-1000
  - `n_observations`: 通常 1000
  - `n_steps`: 通常 50

### 3. 生态位分析方法选择

- **neighborhood profile**：适用于需要基于细胞类型邻域分布的分析
- **UTAG**：适用于快速、可扩展的生态位识别
- **CellCharter**：适用于需要基于图距离的生态位识别

### 4. 图像特征提取

- **summary**: 快速摘要统计（均值、中位数、分位数）
- **texture**: 纹理特征（GLCM、LBP 等）
- **histogram**: 直方图特征
- **segmentation**: 分割相关特征
- **custom**: 使用自定义函数提取特征

### 5. 内存和性能优化

- 对于大型数据集，使用 `n_jobs` 参数进行并行化
- 图像处理时使用 `lazy=True` 进行延迟加载
- 使用 `chunks` 参数控制 Dask 数组的块大小

### 6. 随机种子设置

**重要**：为了确保结果可重现，所有涉及随机性的函数都应该设置随机种子：

```python
import numpy as np
np.random.seed(42)

# 在函数调用中设置 seed 参数
sc.tl.leiden(adata, resolution=0.5, random_state=42)
sq.gr.nhood_enrichment(adata, cluster_key="leiden", n_perms=100, seed=42)
sq.gr.calculate_niche(adata, flavor="cellcharter", random_state=42)
```

## 常见问题排查

### 空间坐标未找到

确保空间坐标存储在 `adata.obsm['spatial']` 中：
```python
# 检查空间坐标
print(adata.obsm['spatial'])

# 如果没有，手动添加
import numpy as np
adata.obsm['spatial'] = np.array([[x, y] for x, y in zip(adata.obs['x'], adata.obs['y'])])
```

### 图像数据未找到

确保图像数据存储在 `adata.uns['spatial'][library_id]['images']` 中：
```python
# 检查图像数据
print(adata.uns['spatial'].keys())
print(adata.uns['spatial']['sample1']['images'].keys())
```

### 空间图构建失败

- 检查坐标类型是否正确（grid vs generic）
- 确保坐标不为空且格式正确
- 对于网格坐标，确保使用 `coord_type="grid"`

### 内存不足

- 使用 `n_jobs=1` 减少并行化
- 对于图像处理，使用 `lazy=True` 和适当的 `chunks`
- 考虑对数据进行下采样

## 与 scverse 生态系统集成

### 与 scanpy 集成

Squidpy 完全兼容 scanpy，可以在同一个 AnnData 对象上使用两个包的功能。

### 与 SpatialData 集成

Squidpy 支持 SpatialData 格式，提供更统一的空间数据表示。推荐使用 `spatialdata-io` 包读取数据，它返回 SpatialData 对象：

```python
from spatialdata_io import xenium, merscope, cosmx, codex
from spatialdata import SpatialData
import squidpy as sq

# 使用 spatialdata-io 读取数据（返回 SpatialData 对象）
sdata = xenium(path="data/xenium_data/")
# 或
# sdata = merscope(path="data/merscope_data/")
# sdata = cosmx(path="data/cosmx_data/")
# sdata = codex(path="data/codex_data/", fcs=True)

# 从 SpatialData 提取 AnnData 进行分析
adata = sdata.tables["table"]

# 使用 squidpy 进行空间分析（可以直接使用 SpatialData 或 AnnData）
sq.gr.spatial_neighbors(adata, coord_type="generic", n_neighs=10)
# 或直接使用 SpatialData 对象
sq.gr.spatial_neighbors(sdata, coord_type="generic", n_neighs=10)

# 如果 SpatialData 包含图像，可以访问
if "image_name" in sdata.images:
    img = sdata.images["image_name"]
    sq.im.calculate_image_features(adata, img, features="summary")
```

**spatialdata-io 的优势**：
- 统一的数据格式（SpatialData 对象）
- 更好的图像和多模态数据支持
- 支持更多平台（Xenium、MERSCOPE、CosMx、CODEX 等）
- 自动处理数据格式转换和坐标系统

**使用 spatialdata-io skill**：
当需要读取 Xenium、MERSCOPE、CosMx、CODEX、Visium HD、seqFISH、Stereo-seq 等平台的数据时，**强烈建议调用 spatialdata-io skill**，它提供了：
- 所有 reader 函数的详细 API 文档
- 每个平台的具体使用示例和最佳实践
- 坐标系统和转换的详细说明
- 性能优化建议

### 与 napari 集成（已弃用）

注意：原始的 napari 插件已移至 `napari-spatialdata`。建议使用新的插件进行交互式可视化。

## 资源

### references/

- **`api_reference.md`**: 完整的 API 参考文档，包含所有函数的详细说明
- **`workflows.md`**: 详细的工作流程示例和常见分析模式
- **`tutorials.md`**: 官方教程和示例 notebook 参考

### 官方资源

- **文档**: https://squidpy.readthedocs.io/
- **GitHub**: https://github.com/scverse/squidpy
- **教程和示例**: https://github.com/scverse/squidpy_notebooks
- **社区论坛**: https://discourse.scverse.org/
- **spatialdata-io**: https://spatialdata.scverse.org/projects/io/ - 用于读取多种空间组学平台数据（推荐用于 Xenium、MERSCOPE、CosMx、CODEX 等）

### 使用 MCP DeepWiki 获取最新信息

**重要**：本 skill 完全支持通过 **MCP DeepWiki** 获取 squidpy 的最新文档和信息。DeepWiki 提供了对 scverse/squidpy GitHub 仓库的深度访问，可以获取最新的 API 文档、教程和工作流程。**强烈建议在需要最新信息或遇到问题时使用 DeepWiki 查询功能**。

#### DeepWiki 工具使用

**可用的 DeepWiki MCP 工具**：

1. **`mcp_deepwiki_ask_question`** - 向 squidpy 仓库提问，获取详细答案
   - `repoName`: `"scverse/squidpy"`
   - `question`: 你的问题（用英文提问效果更好）
   - 用途：获取特定函数、工作流程、最佳实践的详细说明

2. **`mcp_deepwiki_read_wiki_structure`** - 获取 squidpy 的文档结构
   - `repoName`: `"scverse/squidpy"`
   - 用途：了解 squidpy 文档的组织结构

3. **`mcp_deepwiki_read_wiki_contents`** - 读取 squidpy 的文档内容
   - `repoName`: `"scverse/squidpy"`
   - 用途：获取完整的文档内容

#### 常见查询场景

**1. 查询特定函数的使用方法**：
```python
# 使用 mcp_deepwiki_ask_question
# repoName: "scverse/squidpy"
# question: "What is the sq.gr.spatial_neighbors function and how to use it? Please provide detailed API documentation, parameters, and usage examples."
```

**2. 获取所有数据读取方法**：
```python
# question: "What are all the data reading methods in squidpy.read module? Please list all readers with their parameters and usage examples for different sequencing technologies."
```

**3. 获取完整的 API 参考**：
```python
# question: "What is the complete API reference for squidpy? Please provide all functions in sq.gr, sq.im, sq.pl, and sq.read modules with detailed parameters and return values."
```

**4. 查询特定平台的分析方法**：
```python
# question: "How to analyze Xenium data using squidpy? Please provide complete workflow examples including data reading, preprocessing, spatial analysis, and visualization."
```

**5. 获取工作流程示例**：
```python
# question: "What is the complete workflow for analyzing spatial omics data using squidpy? Please provide step-by-step examples including data reading, spatial graph construction, spatial statistics, and visualization."
```

**6. 查询空间统计方法**：
```python
# question: "How does squidpy compute spatial statistics like Moran's I, co-occurrence, and neighborhood enrichment? Please provide detailed examples with parameter settings."
```

**7. 查询图像分析功能**：
```python
# question: "How to extract image features from tissue images using squidpy? Please provide examples for summary, texture, histogram, and custom feature extraction."
```

**8. 查询生态位分析方法**：
```python
# question: "What are the different niche analysis methods in squidpy (neighborhood profile, UTAG, CellCharter)? Please provide detailed examples and when to use each method."
```

**9. 查询最佳实践**：
```python
# question: "What are the best practices for using squidpy? Please provide recommendations for spatial graph construction, parameter settings, performance optimization, and reproducibility."
```

**10. 查询与 spatialdata-io 的集成**：
```python
# question: "How to integrate squidpy with spatialdata-io for reading spatial omics data? Please provide examples for Xenium, MERSCOPE, CosMx, and other platforms."
```

**使用建议**：

- **优先使用 DeepWiki**：当需要最新信息时，优先使用 DeepWiki 查询而不是静态文档
- **特定 API 查询**：对于特定函数的详细 API、参数说明，使用 DeepWiki 获取最新文档
- **复杂场景**：对于复杂的使用场景、集成问题，使用 DeepWiki 获取官方教程和工作流程
- **问题排查**：遇到错误或问题时，使用 DeepWiki 查询解决方案和最佳实践
- **时效性保证**：DeepWiki 提供的信息基于 GitHub 仓库的最新代码，确保信息的时效性和准确性

**示例使用场景**：

当你在使用 squidpy 时遇到问题或需要最新信息，可以这样使用 DeepWiki：

```python
# 场景 1: 需要了解特定函数的详细参数
# 使用 mcp_deepwiki_ask_question 工具
# repoName: "scverse/squidpy"
# question: "What are all the parameters for sq.gr.spatial_neighbors function? Please provide detailed parameter descriptions and default values."

# 场景 2: 需要完整的工作流程示例
# question: "What is the complete workflow for analyzing Visium data using squidpy? Please provide step-by-step code examples including data reading, preprocessing, spatial analysis, and visualization."

# 场景 3: 遇到错误需要解决方案
# question: "How to fix spatial coordinate errors when using squidpy? Please provide solutions and best practices."

# 场景 4: 需要了解不同平台的数据读取方法
# question: "What are the different methods to read spatial omics data in squidpy? Please compare squidpy.read and spatialdata-io methods with examples for Visium, Xenium, MERFISH, and CosMx."
```

## 关键注意事项

1. **AnnData 结构**：理解 `adata.obsm['spatial']`（空间坐标）和 `adata.uns['spatial']`（图像数据）的结构
2. **坐标类型**：区分 `grid`（网格，如 Visium）和 `generic`（通用坐标）
3. **空间图存储**：空间图存储在 `adata.obsp['spatial_connectivities']` 和 `adata.obsp['spatial_distances']`
4. **数据读取**：对于 Xenium、MERSCOPE、CosMx、CODEX、Visium HD、seqFISH、Stereo-seq 等平台，推荐使用 `spatialdata-io` 包读取数据，它提供更统一的数据格式（SpatialData 对象）和更好的图像支持。**强烈建议调用 spatialdata-io skill** 获取详细的文档和示例。
5. **版本兼容性**：注意 squidpy 版本与依赖包的兼容性（scanpy、anndata、numpy、pandas、spatialdata 等）
6. **随机性**：设置随机种子以确保结果可重现（`seed` 或 `random_state` 参数）
7. **并行化**：使用 `n_jobs` 参数控制并行化，注意内存使用
8. **MCP DeepWiki 集成**：充分利用 DeepWiki 获取最新文档和解决方案

## 引用

如果使用 Squidpy，请引用：

> **Squidpy: a scalable framework for spatial omics analysis**  
> Giovanni Palla, Hannah Spitzer, Michal Klein, David Fischer, Anna Christina Schaar, Louis Benedikt Kuemmerle, Sergei Rybakov, Ignacio L. Ibarra, Olle Holmberg, Isaac Virshup, Mohammad Lotfollahi, Sabrina Richter, Fabian J. Theis  
> _Nature Methods_ 2022. doi: 10.1038/s41592-021-01358-2.

