跳到主要内容

04 火山图、热图与富集可视化

前三章把数据、差异和富集跑完,这一章只做一件事:把结果变成能直接用于论文和汇报的图。每张图都配一个最常见的用途,源码一起放出来。

配套脚本 bulk04_visualization_sci.R 把 DESeq2 + 富集的流程重跑一次(继承自 02 和 03),然后输出 6 张可视化成品:

Rscript scripts/bulk04_visualization_sci.R

图 1:火山图

Volcano plot

火山图是每篇转录组文章的标配 —— 横轴是 log2 fold change,纵轴是 -log10(padj)。每个点是一个基因,颜色表示它在哪个象限。两条虚线标出 padj = 0.05 和 |LFC| = 1 的阈值。

这张图的关键是标注:默认标全部显著基因会完全盖掉点云。脚本里只标 top 10 up + top 10 down(按 padj 排序),用 ggrepel 自动避让。

核心代码:

ggplot(vol, aes(x = log2FoldChange, y = -log10(padj), color = sig)) +
geom_point(size = 0.6, alpha = 0.5) +
geom_text_repel(data = label_df, aes(label = SYMBOL), ...) +
geom_vline(xintercept = c(-1, 1), linetype = "dashed") +
geom_hline(yintercept = -log10(0.05), linetype = "dashed")

sig 列的阈值、head(10) 的数量、颜色都很方便。

图 2:Top DE 基因热图

Heatmap of top 40 DE genes

取 padj 最小的 40 个基因,在 VST 归一化后做 row z-score,画热图。列注释标出了处理状态和细胞系。

这张图在报告里的作用是给火山图"补一刀" —— 火山图只能看统计显著性,热图能直接看到"这些基因在每个样本里到底是什么表达水平"。列聚类会把处理样本和对照样本各自聚到一起;行聚类会把上调和下调基因分开。

pheatmap

mat_z <- t(scale(t(mat))) # row z-score
pheatmap(mat_z,
annotation_col = anno_col,
color = colorRampPalette(c("blue", "white", "red"))(100),
breaks = seq(-3, 3, length.out = 101))

breaks 参数很重要:限制颜色范围能避免个别极端基因把色阶拉歪。[-3, 3] 是 z-score 的常用范围。

图 3:精选基因的表达分布

Curated glucocorticoid response panel

选几个已知的糖皮质激素响应基因(DUSP1 / FKBP5 / ANGPTL4 / KLF15 / SPARCL1 / ZBTB16)画 boxplot + jitter,y 轴是 log10 的 normalized counts。

这种"已知通路验证"的图在讨论部分特别有用:文献说这些基因是地塞米松响应基因,我们的数据里也确实看到了这个响应,能直接把自己的数据和已有知识对接上。

ggplot(count_long, aes(x = dex, y = count, fill = dex)) +
geom_boxplot() + geom_jitter() +
facet_wrap(~ symbol, scales = "free_y") + scale_y_log10()

图 4:KEGG 富集气泡图

KEGG enrichment bubble plot

dotplot(ekegg) 的默认版本更有信息量:点大小是 gene count,颜色是 -log10(p.adj),横轴是 gene ratio。一张图同时显示"通路覆盖度"、"显著性"、"通路里命中了多少基因"三个维度。

这个 bubble 是纯 ggplot 写的,不依赖 enrichplot,完全可以移植到任何富集结果(enrichGOenrichPathwayGSEA 都行)。

ggplot(ekegg_df,
aes(x = GeneRatio_num, y = reorder(Description, GeneRatio_num),
size = Count, color = -log10(p.adjust))) +
geom_point() +
scale_color_gradient(low = "blue", high = "red") +
scale_size_continuous(range = c(3, 9))

图 5:cnetplot 基因-通路网络

Gene-term cnetplot network

enrichplot::cnetplot 把 GO term 和驱动这些 term 的基因画成二部图:浅灰色大圆点是 term,彩色小点是基因,颜色按 log2FC 着色。

这张图的价值是一眼看到"哪些基因被多条通路共享" —— 共享基因往往是生物学上最关键的 master regulator。讨论部分里可以直接点出"图里 A 基因被 3 条通路共享,说明它很可能是这次处理的上游枢纽"。

图 6:GSEA NES forest 图

GSEA NES forest plot

GSEA 的瀑布图能表达排序,但多个 term 一起看、带显著性的信息,forest 图更合适。横轴是 NES,纵轴是 term 名字,点大小是 -log10(p.adj),颜色区分激活 / 抑制。

相比 waterfall,这张图额外能读出 NES 到 0 的距离(segment 线段)和 显著性强度(点大小),信息密度更高。

常见坑

  • 颜色:火山图用蓝 / 红 / 灰三色是惯例,别换成 viridis 这种连续色;读者会困惑"到底哪边是上调"
  • 标注:标签超过 30 个就没法读;能标 top 10-20 就够了
  • 基因 ID:热图 / 火山图要标 SYMBOL 不是 Ensembl。一定要在最后可视化之前把 SYMBOL 映射上
  • 坐标轴范围:火山图如果有极端 padj(比如 1e-300),用 pmax(padj, 1e-300) 封顶避免压扁整张图
  • 导出:论文图建议 dpi = 300 直接存 PNG;不要存 JPG(有压缩伪影);有时需要 TIFF / PDF 向量图,见 ggsave()device 参数

下载资源

bulk04_visualization_sci.R16 KB

下载 airway 可视化完整脚本

下一步

bulk RNA-seq 专栏目前到这一章为止。后面会补:

  • 多时间点或剂量响应的差异分析(LRT vs Wald
  • 批次效应更复杂的场景(RUVseq、SVA)
  • 面向发表的结果组织(fgsea + MSigDB Hallmarks + Reactome)
  • 单细胞 vs bulk 的方法学对照

参考资源

静态文件

离线资料下载

手册 HTML / PDF 已在后台预生成,点击后直接下载网站静态资源。