software

Squidpy 说两类细胞相邻富集,先看看哪两点算邻居

作者:发布于 2026-11-14约 7 分钟阅读
半径一改,邻域富集为何也会改。教学算例|四个细胞每隔十微米一个,类型依次为甲乙甲乙。10 µm,三条边,全是异类邻居,固定四个标签随机置换,异类边预期为两条。21 µm,五条边,其中三条异类,新纳入的两条都是同类边。31 µm,六条边,其中四条异类,图完全连通,随机置换后这个计数始终相同。

一张空间图显示肿瘤细胞与巨噬细胞相邻富集。把建图半径从十微米调到三十微米,原来的红色区域却几乎消失。两组结果未必矛盾,十微米和三十微米可能在回答两个不同的组织学问题。判断之前,最好先从真实坐标画出一小块邻居边,算清用了多大的邻近尺度,再回来看富集分数的分母。下面用排成一行的四个点,重现仅改变半径就足以改变结果的原因。

先决定邻近指细胞接触、局部共居还是同处一个区域

在成像数据里,细胞质轮廓真正接触,细胞中心未必特别近。大细胞和小细胞的中心距离恰好一样,也可能有完全不同的边界关系。若要研究接触依赖的信号,质心半径只能作为近似,有边界时可进一步核对轮廓。若问题是某类细胞是否聚在同一血管周围,则较大的物理半径可能更贴近问题。先根据组织尺度确定要描述什么,后面改变半径才有解释对象。

从空间对象读取坐标后要查单位。图像像素和微米之间需要实际校准,缩略图上的像素也未必等于原图像素。多个切片经常各自把左上角记为零,直接拼接坐标会造成不同切片的细胞变成近邻。建图时让每张切片独立,检查最终邻接矩阵中是否有跨切片边。即使将不同切片在画布上平移开,也应该把来源字段保存下来,不能依赖一张临时排版图的坐标间距来定义真实组织邻居。Squidpy 半径建图的参数与距离定义

用四个点手算邻居边与随机基线

设一行四个细胞中心分别在零、十、二十、三十微米处,类型从左到右为甲、乙、甲、乙。设半径包含恰好等于阈值的点,不保留自环,每对无向邻居只数一次。十微米时只有三对相邻位置,每一对都是甲乙。二十一微米时还会加上第一与第三、第二与第四这两对同类细胞,总边数从三变成五,甲乙边数仍为三。

半径 无向边数 甲乙边数 甲乙边占比
10 微米 3 3 100%
21 微米 5 3 60%
31 微米 6 4 约 67%
半径一改,邻域富集为何也会改。教学算例|四个细胞每隔十微米一个,类型依次为甲乙甲乙。10 µm,三条边,全是异类邻居,固定四个标签随机置换,异类边预期为两条。21 µm,五条边,其中三条异类,新纳入的两条都是同类边。31 µm,六条边,其中四条异类,图完全连通,随机置换后这个计数始终相同。
教学算例|四个细胞每隔十微米一个,类型依次为甲乙甲乙。

四个点中两甲两乙,如果将四个现有标签随机分配到四个固定位置,两两任选共有六种配对,其中四种跨类型。对于固定图里的任何一条无向边,随机时异类的预期概率都是三分之二。因此十微米图的随机预期是两条甲乙边,实际观察到三条,二十一微米图的预期为五乘三分之二,实际只有三条,到三十一微米时图已经完全连通,无论如何打乱标签,甲乙边都恰好四条。这个极端情况下置换标准差为零,不能再靠标准化分数区分任何空间排列。

手算的是无向总体边。软件输出按来源类型与邻居类型组织,某些读法还会区分甲到乙与乙到甲,以及同类型边在对称矩阵中的两端。作核对时始终保持计数口径一致。置换标准分反映观测与置换均值之间相差多少个置换标准差,绝不是“相邻概率为多少”。同一份数据里稀有群和丰富群拥有的可用边数差很多,两张都为深红色的格子也可能对应截然不同的绝对边数。Squidpy 邻域富集的计数与置换输出

建图后先查有没有跨片的边

下例假设所用 Squidpy 版本提供半径建图接口,坐标已换为微米,切片编号和类型已设为类别列。示范半径用二十一,与上表对应。邻接是按切片构造的,随后统计时仍提供切片编号,以便在相应切片内对标签作置换。代码先检查边的两个端点是否真的来自同一张切片,再计算富集。

import squidpy as sq

sq.gr.spatial_neighbors_radius(adata, spatial_key="spatial_um", radius=21,
                               library_key="slide")
graph = adata.obsp["spatial_connectivities"].tocoo()
slide = adata.obs["slide"].to_numpy()
assert (slide[graph.row] == slide[graph.col]).all()
sq.gr.nhood_enrichment(adata, cluster_key="cell_type", library_key="slide")

另一项检查是每张切片的度分布,也就是每个细胞有多少条邻居边。组织边缘和切割孔洞附近的细胞容易天然少邻居,密集肿瘤巢的中心则可能有很多。若图连线显著跨过空腔或组织裂隙,欧氏距离虽短,生物学路径却未必存在。画几块组织实景,把边覆盖在掩膜上检查,再决定需不需要排除跨空白的连线,或改用能够反映组织结构的邻接定义。

实跑经验|漏填切片列,十条跨片边进入了结果

我们安装 Squidpy 1.8.4,把前面四点的视野复制成两张坐标完全重合的模拟切片。先传入切片编号分别构图,再用稀疏矩阵上三角数无向边。半径为十、二十一和三十一微米时,两片合计分别有六条、十条和十二条边,异类边分别是六条、六条和八条。半径二十一时,软件返回的有向计数矩阵两行分别为“四、六”和“六、四”,四个格子加起来为二十,正好是十条无向边的两倍。与手算比对时,只取一个三角的总边或先说明计数方向,便不会把这个倍数当成软件多连了边。

在各片内部置换标签,固定种子三十七,做二百五十六次。甲到乙的标准分从半径十时约 1.76,变为半径二十一时约 −1.09,最大半径下四个格子全都得到非有限值。此时每片已经完全连通,换标签确实改变不了甲乙边总数。最后只改一个参数,拿掉切片编号,在半径十重新构图。总边数增加到十六条,其中十条跨越了两张物理上互不接触的切片。同一坐标出现大量近邻时,检查边两端的样本编号比目测平面散点图更直接。

区分组织结构和同一组织区内部的偏好

如果甲乙都偏爱肿瘤边缘,即使它们在边缘内部并不特别靠近,拿整张切片随机打乱标签也可能得到明显富集。把问题改成“在同一组织区域内部,两者是否仍然彼此接近”,就需要在合适的区域内比较或设计保留组织分区的置换。若单独裁出区域,应说明是否保留跨区域的边、边缘点如何处理。不同空模型保留的结构不同,得到不同结论正好有助于辨认信号是由大尺度组织分布,还是更局部的相互邻近推动。

最后逐张切片汇总真实边数、预期边数、细胞类型占比及候选方向,再核对不同供体是否复现。拥有十万枚细胞的一张切片也只代表其实际取材来源。若要推广到某一类患者,把独立供体和组织区域交代清楚,比只报告一个很高的置换分数更能让读者判断证据。需要在多切片上反复构图、共享坐标和置换流程时,可了解云生信的生物信息分析服务器。

把知识用于当前任务

下一步可以直接开始分析

按研究目标查找在线工具、课程、计算资源或完整分析服务。

按目标找方案仍有疑问,联系客服 ↗