空间转录组对比:Squidpy/Giotto/STutility
一句话概述:Squidpy是Python空间组学的全能框架(与Scanpy无缝集成),Giotto是R/Python双语言空间分析平台(功能最全面),STutility是R语言Visium数据的轻量级工具——空间转录组学正在快速发展,工具选择取决于你的技术平台和编程语言偏好。
核心知识点速查表
| 概念 | 说明 |
|---|
| Squidpy | Python空间分析框架(白话:Scanpy的空间版) |
| Giotto | R+Python空间分析全平台(功能最丰富) |
| STutility | R语言Visium数据分析工具(轻量级) |
| Visium | 10x Genomics的空间转录组平台(最常用) |
| 空间邻域 | 空间上相邻的细胞/点的关系网络 |
| 空间自相关 | 基因表达是否在空间上聚集(Moran's I) |
一、三大工具对比
| 特性 | Squidpy | Giotto | STutility |
|---|
| 语言 | Python | R + Python | R |
| 数据格式 | AnnData | giotto对象 | Seurat对象 |
| 支持平台 | Visium/MERFISH/等 | 几乎所有平台(★) | Visium为主 |
| 空间统计 | ★丰富 | ★最丰富 | 基本 |
| 图像分析 | ★有 | 有 | 有(★H&E) |
| 细胞通信 | CellPhoneDB集成 | 内置多方法 | 需外部工具 |
| 去卷积 | 支持 | ★内置多方法 | 支持 |
| 可视化 | matplotlib | ggplot2/plotly | ggplot2 |
| 与单细胞集成 | Scanpy(★) | 独立生态 | Seurat(★) |
| 学习曲线 | 中等 | 较陡 | 简单 |
| 社区活跃 | ★高 | 高 | 中等 |
二、Squidpy实操
# === Squidpy 标准流程 ===
import squidpy as sq
import scanpy as sc
# 读取Visium数据
adata = sq.datasets.visium_hne_adata() # 示例数据
# 或从10x输出读取:
# adata = sc.read_visium("spaceranger_output/")
# 标准Scanpy预处理
sc.pp.normalize_total(adata) # 标准化
sc.pp.log1p(adata) # log转换
sc.pp.highly_variable_genes(adata) # 高变基因
sc.tl.pca(adata) # PCA
sc.pp.neighbors(adata) # KNN
sc.tl.leiden(adata, resolution=0.5) # 聚类
sc.tl.umap(adata) # UMAP
# ★空间分析(Squidpy特有)
# 空间邻域图
sq.gr.spatial_neighbors(adata,
coord_type="grid", # 网格型(Visium)
n_neighs=6 # 六角形邻域
)
# 空间自相关(Moran's I)
sq.gr.spatial_autocorr(adata,
mode="moran", # Moran's I统计量
genes=adata.var_names[:100] # 前100个基因
)
# 结果在 adata.uns["moranI"]
# I值高→空间聚集 | I≈0→随机分布 | I值低→空间分散
# 邻域富集分析
sq.gr.nhood_enrichment(adata,
cluster_key="leiden" # 聚类结果
)
sq.pl.nhood_enrichment(adata, cluster_key="leiden") # 可视化
# 共现分析
sq.gr.co_occurrence(adata,
cluster_key="leiden" # 哪些细胞类型倾向共同出现
)
# 空间可视化
sq.pl.spatial_scatter(adata,
color="leiden", # 空间聚类图
size=1.5
)
sq.pl.spatial_scatter(adata,
color=["CD3D", "CD68"], # 基因空间表达
size=1.5
)
三、Giotto实操
# === Giotto 标准流程 ===
library(Giotto)
# 创建Giotto对象(Visium数据)
my_giotto <- createGiottoObject(
expression = expr_matrix, # 表达矩阵
spatial_locs = spatial_coords # 空间坐标
)
# 或从10x Visium输出:
# my_giotto <- createGiottoVisiumObject(
# visium_dir = "spaceranger_output/",
# h5_visium_path = "filtered_feature_bc_matrix.h5"
# )
# 预处理
my_giotto <- normalizeGiotto(my_giotto) # 标准化
my_giotto <- calculateHVG(my_giotto) # 高变基因
my_giotto <- runPCA(my_giotto) # PCA
my_giotto <- createNearestNetwork(my_giotto) # KNN
my_giotto <- doLeidenCluster(my_giotto) # Leiden聚类
my_giotto <- runUMAP(my_giotto) # UMAP
# ★空间分析
# 空间网络
my_giotto <- createSpatialNetwork(my_giotto,
method = "kNN", # 方法: kNN/Delaunay
k = 6 # 邻居数
)
# 空间基因检测
spatial_genes <- detectSpatialCorGenes(
my_giotto,
method = "network", # 基于空间网络
spatial_network_name = "kNN_network"
)
# 空间域检测(HMRF)
my_giotto <- doHMRF(my_giotto,
spatial_genes = spatial_genes$gene, # 空间基因
spatial_network_name = "kNN_network",
k = 5 # 空间域数
)
# 可视化
spatPlot(my_giotto,
cell_color = "leiden_clus", # 聚类着色
point_size = 2
)
spatFeatPlot2D(my_giotto,
feats = c("CD3D", "CD68"), # 基因空间图
point_size = 2
)
四、STutility实操
# === STutility(Seurat扩展) ===
library(STutility)
library(Seurat)
# 从Visium读取(基于Seurat)
infoTable <- data.frame(
samples = "spaceranger_output/filtered_feature_bc_matrix.h5",
spotfiles = "spaceranger_output/spatial/tissue_positions_list.csv",
imgs = "spaceranger_output/spatial/tissue_hires_image.png",
json = "spaceranger_output/spatial/scalefactors_json.json"
)
se <- InputFromTable(infotable = infoTable) # 创建Seurat对象+空间信息
# Seurat标准流程
se <- se %>%
SCTransform() %>% # SCT标准化
RunPCA() %>%
FindNeighbors(dims=1:30) %>%
FindClusters(resolution=0.5) %>%
RunUMAP(dims=1:30)
# ★空间可视化(STutility优势:H&E叠加)
ST.FeaturePlot(se,
features = c("CD3D", "CD68"), # 基因表达叠加到H&E上
ncol = 2
)
ST.DimPlot(se,
group.by = "seurat_clusters", # 聚类叠加到H&E
ncol = 1
)
五、面试高频考点
Q1: 三种工具怎么选?
| 场景 | 推荐 | 原因 |
|---|
| Python用户 | Squidpy | 与Scanpy无缝集成 |
| R用户+Visium | STutility | 基于Seurat最简单 |
| 多平台分析 | Giotto | 支持平台最多 |
| 空间统计深入 | Squidpy/Giotto | 统计方法丰富 |
| H&E图像分析 | STutility | H&E叠加最方便 |
| 细胞去卷积 | Giotto | 内置多种去卷积方法 |
Q2: 什么是空间去卷积?
- Visium的每个spot不是单个细胞,而是包含多个细胞的混合
- 去卷积就是推断每个spot中不同细胞类型的比例
- 需要单细胞参考数据作为"字典"
- 常用方法:RCTD、SPOTlight、cell2location、Tangram
Q3: 空间自相关(Moran's I)怎么解读?
- Moran's I ≈ 1:基因表达高度空间聚集(如肿瘤区域的标记基因)
- Moran's I ≈ 0:随机分布(无空间模式)
- Moran's I ≈ -1:空间分散(棋盘格模式,罕见)
六、常见报错
| 报错 | 原因 | 解决 |
|---|
No spatial coordinates | 空间坐标缺失 | 检查spaceranger输出 |
Squidpy: spatial_key not found | AnnData中缺少空间信息 | 检查adata.obsm['spatial'] |
Giotto: cannot create network | 坐标格式错误 | 检查坐标是否为数值型 |
STutility: image not found | 图片路径错误 | 确认路径和文件名 |
速查表
# === 空间分析速查 ===
# Squidpy (Python)
import squidpy as sq
sq.gr.spatial_neighbors(adata) # 空间邻域
sq.gr.spatial_autocorr(adata, mode="moran") # 空间自相关
sq.gr.nhood_enrichment(adata, cluster_key="leiden") # 邻域富集
# Giotto (R)
createSpatialNetwork(obj, method="kNN", k=6)
detectSpatialCorGenes(obj, method="network")
# STutility (R, 基于Seurat)
ST.FeaturePlot(se, features="gene") # H&E叠加
# 选择: Python→Squidpy | R+简单→STutility | 全面→Giotto