作者,Evil Genius
今天我们需要讨论一个问题,那就是关于邻域的问题,目前有两种思路,如下:
一种是选择某个点(cell)一定范围内距离最近的几个细胞,例如下面就是距离最近的10个细胞
另外一种是将一定范围内的所有细胞均纳入分析范围,如下图:
对于那种spot类型的数据,点之间的大小是固定的,自然也就没有什么区别,那如果是原位的分析,大家觉得哪种更好呢?尤其其中关键的问题,如果选择第二种,距离设置成多远呢?
其实大家应该都倾向于第二种的空间邻域分析方法,因为做了图像细胞分割的原因,对于原位数据有以下特点:
那就是细胞的分布密度不同,有的地方密度大,固定大小包含多个细胞,有的地方密度小,细胞分布就比较少了。
所有我们基于原位的数据需要优化,同时兼容像visium的数据。
我们先以visium 的数据为例,范围设置成100(注意这里的范围是像素),同时要做了单细胞空间的联合分析。
import scanpy as sc
import squidpy as sq
# 读取空间转录组数据 (例如 10X Visium 数据)
adata = sc.read_visium('/home/samples/DB/Spatial/visium_data/HCC_1L')
# 预处理数据
sc.pp.normalize_total(adata, inplace=True)
sc.pp.log1p(adata)
sc.pp.highly_variable_genes(adata, flavor="seurat", n_top_genes=2000)
adata = adata[:, adata.var.highly_variable]
# 计算邻域信息 (必要时设置邻域大小)
sq.gr.spatial_neighbors(adata, coord_type="grid", radius=100)
# 进行细胞通讯分析
sq.gr.interaction_matrix(adata)
# 可视化通讯网络
sq.pl.spatial_interaction(adata, cluster_key="cluster")
高精度的原位数据同理,需要做好细胞类型的注释
import spatialdata as sd
from spatialdata_io import xenium
import matplotlib.pyplot as plt
import seaborn as sns
import scanpy as sc
import squidpy as sq
xenium_path = "./Xenium"
zarr_path = "./Xenium.zarr"
sdata = xenium(xenium_path)
sc.pp.filter_cells(adata, min_counts=10)
sc.pp.filter_genes(adata, min_cells=5)
adata.layers["counts"] = adata.X.copy()
sc.pp.normalize_total(adata, inplace=True)
sc.pp.log1p(adata)
sc.pp.pca(adata)
sc.pp.neighbors(adata)
sc.tl.umap(adata)
sc.tl.leiden(adata)
sq.gr.spatial_neighbors(adata, coord_type="generic", delaunay=True, radius=100)
sq.pl.nhood_enrichment(
adata,
cluster_key="leiden",
figsize=(8, 8),
title="Neighborhood enrichment adata",
ax=ax[0],
)
sq.pl.spatial_scatter(adata_subsample, color="leiden", shape=None, size=2, ax=ax[1])