第1节:Visium技术原理与数据特点
好,咱们正式开始聊Visium。这部分内容,我希望能帮你把Visium这个东西的“根”摸清楚。很多人在跑后面的归一化、批次校正时,代码咔咔一顿敲,但数据为什么会表现出那些怪毛病,心里其实没底。说白了,你不理解数据是怎么来的,就很难选对处理它的方法。
Visium是10x Genomics推出的空间转录组技术。它跟单细胞测序最大的区别,就是保留了组织切片里每个点的空间位置信息。你想想看,一张组织切片,切下来之后,它原来的组织形态、细胞排列、区域之间的相互作用,这些信息都是无价的。Visium能让你在拿到基因表达数据的同时,还能在图像上看到这些基因到底在哪里表达。
1.1 空间条形码:Visium的“身份证”
Visium的核心是那块捕获芯片。芯片表面铺满了捕获点(spots),每个点都带有一段独一无二的序列——空间条形码(Spatial Barcode)。
可能有人会问:5000个点够用吗?这得看你的研究目的。如果你关心的是组织区域的整体表达模式,比如肿瘤微环境里的不同区域,那足够了。但如果你想精细到单个细胞的分辨率,那Visium的每个点其实覆盖了1到10个细胞左右。我在一个脑切片项目里就踩过这个坑——想用Visium去做细胞类型精细注释,结果每个点混了好几种神经元,后面解卷积搞得我头大。
数据生成的流程,我这里简单画了个图,能直观看到从组织到数据的完整链条:
1.2 数据结构的四个层次
Visium的数据,我个人习惯把它拆成四个层次来理解。你后面做所有预处理,其实都是在操作这四层东西:
- 原始图像:H&E染色后的组织切片高清扫描图。这个图是你做空间对齐的基准,也是判断组织区域是否完整的依据。
- 空间坐标:每个Spot在图像上的(x, y)坐标。记住,这个坐标是像素级的,不是物理距离。芯片会把图像坐标映射到捕获点的排布上。
- 基因表达矩阵:行是基因,列是Spot,值是UMI计数。这就是个典型的稀疏矩阵,大部分格子都是0。
- 组织掩膜:标记哪些Spot落在组织区域内。没落在组织上的Spot,表达量基本是背景噪声,后面要过滤掉。
1.3 批次效应:为什么会发生?
到了归一化和批次校正这一步,必须先承认一个现实:Visium的批次效应非常常见。原因其实不难理解:
| 批次因素 | 具体影响 |
|---|---|
| 不同切片 | 切片厚度差异、组织RNA降解程度不同,导致捕获效率不一样 |
| 不同芯片批次 | 芯片上的捕获点密度、条形码浓度可能存在批次差异 |
| 实验日期间隔 | 试剂批次、操作人员、环境温度湿度变化 |
| 测序深度 | 不同样本的测序通量不同,直接反映在UMI计数上 |
你想想看,三个不同时间做的切片,跑到同一个PCA里,如果按样本来源一看就分群了——这大概率是批次效应,不一定是真正的生物学差异。我最早做多切片分析的时候,就吃过这个亏。明明都是同一类肿瘤组织,结果聚类分成了三群,后来才发现原来是不同批次的芯片造成的。
1.4 归一化:为什么不能直接用原始UMI?
原始UMI计数,说白了就是测序仪给你报的数字。但这个数字不能直接用来比较不同Spot之间的基因表达水平。原因有两条:
- 测序深度差异:有的Spot被测了5万条reads,有的只有1万条。深的Spot所有基因看起来都高,这显然不是生物学真相。
- 捕获效率差异:组织不同区域的RNA质量不同,裂解效率不同,导致同样的细胞数可能捕获到的RNA量差好几倍。
# 一个极简的归一化思路:CPM(Counts Per Million)
# 公式:每个基因的UMI数 / 该Spot总UMI数 × 1,000,000
# 但这只是最基础的,后面我们还会讲更高级的SCTransform等方法。
# 实际操作中,直接跑Seurat或scanpy的NormalizeData就能搞定
import scanpy as sc
adata = sc.read_visium("path/to/spaceranger/output")
sc.pp.normalize_total(adata, target_sum=1e4) # 每Spot归一化到1万
sc.pp.log1p(adata) # log转换
但要注意,这种全局归一化有一个隐含假设:所有Spot的总表达量应该一样。在组织内部,这个假设其实不太站得住脚——肿瘤核心区域和正常组织区域的细胞密度和代谢活性能一样吗?这就是为什么后面我们要做更精细的归一化和批次校正。
好,Visium的技术原理和数据特点就先聊到这里。记住我上面提到的几个关键点:空间条形码、四层数据结构、批次效应的来源、以及为什么不能直接用原始UMI。这些都是后续所有操作的基石。你要是对这些基础概念还不太清晰,建议回过头再看看我前面画的图。