4、批次效应可视化:用眼睛发现批次结构
数据跑完了,差异基因也筛了,但总觉得结果不太对?别急着下结论。我个人习惯,拿到整合后的表达矩阵,第一步不是做差异分析,而是先画个散点图看看。批次效应这玩意儿,光靠统计指标不够直观,眼睛往往比任何检验都更早发现问题。
这一章咱们聊聊怎么用降维可视化来“看见”批次结构。说白了,就是给你的数据拍张合照,按批次涂上颜色——如果某几个批次的细胞各自抱团,那就是批次效应在作祟。
4.1 为什么可视化是批次诊断的第一站?
想象一下,你做了两个批次的实验,一个在A试剂,一个在B试剂。如果你直接把所有细胞混在一起分析,聚类结果很可能被试剂差异主导,而不是真正的生物学差异。可视化能让你在几分钟内判断:批次分离得有多严重?是全局偏移还是局部混淆?
常用的降维方法有三个:PCA、tSNE、UMAP。它们各有侧重,我一般这么用——先PCA快速扫一眼,再拿UMAP精细观察。tSNE呢?嗯,它计算慢、随机性大,我平时用得少,但有些人特别喜欢用它做最终展示图。
关键点:无论用哪种方法,必须按批次着色。否则你看到的任何结构都可能是伪迹。
4.2 PCA散点图——第一步诊断
PCA是线性降维,计算快,重现性好。我通常取前两个主成分(PC1 vs PC2),每个点代表一个细胞,颜色按批次标注。
举个代码例子(这里用Python的scanpy库,R的Seurat也类似):
import scanpy as sc
import matplotlib.pyplot as plt
# 读取数据,假设已合并
adata = sc.read("merged.h5ad")
# PCA计算
sc.tl.pca(adata, n_pcs=50)
# 画图,按批次着色
sc.pl.pca(adata, color="batch", title="PCA - Batch-colored")
plt.show()
画出来的图通常有两种情况:
- 批次混合良好:不同颜色点相互交织,没有明显分群。
- 批次分离明显:某个批次的细胞聚成一团,与其他批次隔开。这时候就需要做批次校正了。
我还记得有一次,PCA图上PC1和PC2刚好把两个批次分开,但PC3却显示出某个亚群的差异。这说明批次效应可能只影响少数维度,这时候只看前两个PC容易被骗。所以我也建议你多检查几个PC组合,比如PC3 vs PC4。
4.3 UMAP / tSNE——高维降维的细节
PCA看的是“大趋势”,但单细胞数据往往包含很多非线性结构。这时候UMAP和tSNE的优势就体现出来了——它们能保留局部邻域关系,把相似细胞拉得更近。
| 特征 | PCA | tSNE | UMAP |
|---|---|---|---|
| 线性/非线性 | 线性 | 非线性 | 非线性 |
| 速度 | 快 | 慢(尤其大样本) | 较快 |
| 重现性 | 高 | 低(需固定随机种子) | 中(受参数影响大) |
| 对批次效应敏感性 | 全局分离明显 | 局部结构清晰 | 兼顾全局与局部 |
| 参数敏感度 | 低 | 高(perplexity) | 中(n_neighbors, min_dist) |
我个人强烈建议:先用PCA看全局,再用UMAP看细节。画UMAP时,一定要注意 n_neighbors 这个参数。我见过有人把这个值设成5,结果每个批次都碎成小团,看起来像完美分离——其实是过拟合了。默认15~30是个稳妥区间。
# 计算UMAP
sc.tl.umap(adata, n_neighbors=20, min_dist=0.3)
# 画图,按批次和生物学分组同时着色
sc.pl.umap(adata, color=["batch", "cell_type"],
wspace=0.5, title=["UMAP by batch", "UMAP by cell type"])
tSNE呢?我只有在数据量小于1万个细胞时才用它。而且一定要设置 random_state 或 seed,否则每次运行结果都不一样,无法复现。这是避坑指南里一定要写的:永远固定随机种子。
4.4 如何解读这些图?
画完图,看什么?我列个清单:
- 按批次着色,看分群:不同颜色是否各自成团?如果是,批次效应明显。
- 按细胞类型着色,看生物学信号:同一个细胞类型是否跨批次混合?如果是,说明整合效果不错。
- 检查离群批次:有没有一个批次完全脱离主体?可能是技术原因(如测序深度不同)。
- 对比校正前后:如果把校正前的图和校正后的图并排放置,能直观看到批次效应被消除。
警告:不要在UMAP/tSNE图上过度解读“小团块”。这些非线性方法会把随机噪声也放大。如果你看到一个只有3-5个细胞的“新群体”,先检查这是否是一个低质量的细胞簇(高线粒体、低基因数),或者是否来自同一个批次的单个样本。
4.5 常见陷阱(避坑)
画图本身不难,难的是不犯低级错误。我把自己踩过的坑分享给你:
- 颜色盲:我曾经用红绿配色区分两个批次,结果合作者恰好是红绿色盲。现在我都用
tab10或viridis色板,或者用形状/透明度辅助区分。 - 忽略了杂乱的图例:批次太多时,默认图例挤成一团。记得调大
legend_loc或单独保存图例。 - 过度依赖tSNE的“云团”:tSNE的全局距离没有意义,两个远距离的团未必在生物学上不同。UMAP相对好一些,但也不完美。
- 忘记检查PCA的载荷图:如果某些批次在PC1上分离,可以去看看是哪些基因贡献最大。有时候批次效应是由一两个高表达基因引起的。
一个小技巧:在Python里用sc.pl.pca(adata, color="batch")时,可以加参数show=False,然后plt.savefig("batch_pca.png", dpi=300),保存高清图方便汇报。
4.6 可视化流程总结
为了让你对整个可视化诊断流程有整体印象,我画了一张流程图:从原始数据到降维,再到按批次着色,最后判断是否需要校正。注意,这些步骤不是一次性的——你校正完应该再画一次,对比前后效果。
这张图覆盖了核心流程:
- 从合并后的表达矩阵出发,先做PCA(线性、快速)。
- 然后分支到PCA散点图和UMAP/tSNE,两者各有侧重。
- 最后综合判断:如果看到清晰批次分离,就需要进行批次校正;如果混合良好,就可以进入下游聚类和差异分析。
我的原则:校正前后各画一张图,放一起对比。如果校正后批次分离消失了,但细胞类型分群还在,才算校正成功。否则就得调参数或者换方法。