什么时候用它
矩阵热图和上一族的相关性热图形态相同,但回答的问题不同:相关性热图的矩阵是算出来的(两两相关系数),这里的矩阵是测出来的(表达量、丰度、强度)。
它的核心能力是双向聚类:行和列同时重排,把模式相似的挤到一起。所以图上出现的块状结构不是数据自带的顺序,是算法找出来的。
用 ComplexHeatmap 而不是 pheatmap 或 ggplot,图省的是两件事:注释条,和横向拼接——同一批行可以把表达、甲基化、突变几个矩阵用 ht1 + ht2 + ht3 并排接起来,行顺序由第一个热图的聚类决定、其余自动跟着对齐。这是它名字里那个 "Complex" 的实际含义。
怎么读
- 先看色阶方向。 高低两端和中间锚点各是什么色。
- 看块。 聚类后出现的连续色块就是"一起动"的行列组合。
- 对照注释条。 这是整张图最要紧的一步——如果 Tumor 样本恰好聚成一块,说明矩阵里确实有和样本类型相关的信号;如果没聚在一起,那也是结论,而且往往更重要。
- 看树状图的高度。 分支越早分开,两簇差别越大。
- 看缺失格。 灰格是 NA,不是低值。
常见陷阱
- 注释表的行名必须和矩阵对齐。 错位了照样能画出来,只是注释贴到了别的基因或样本上。这是这张图最危险的一个坑,因为图看起来完全正常。
- 聚类方法会改变结论。
complete和ward.D2给出的分块可能完全不同。方法要写进图注,不然这张图不可复现。 - 没标准化就聚类。 表达量量级差几个数量级时,聚类会被高表达基因主导。多数情况下该先按行做 z-score。
- 色阶范围被离群值拉爆。 一个极端值会把整张图压成一片中性色。用分位数截断(比如 1%–99%)而不是最大最小值。
- 行太多标签就没法看。 超过五六十行就该关掉行名——但关掉之后读者就不知道哪一行是谁了,所以得把重点那几个单独引出来:
rowAnnotation(mark = anno_mark(at = which(rownames(expr_mat) %in% genes), labels = genes)),它会在侧边用连线把标签牵到对应的行上。这比全开行名干净得多,也是关掉行名之后的必要配套,不是可选装饰。 - 导出走"开设备 →
draw()→dev.off()"。Heatmap()返回的是对象不是 ggplot,ggsave()存不了;也不像 base graphics 那样画完就已经在设备上。另有两件事只在导出时才暴露:画布一大图例容易被裁,draw()时补padding = unit(c(2, 20, 2, 20), "mm");而use_raster = TRUE的主体是按设备尺寸栅格化的,导 300 dpi 时raster_quality = 2会糊,要往上调。 - 块状结构不等于生物学。 聚类只是把相似的排到一起,它总能找出"块",哪怕数据是纯噪声——这一页的矩阵就是
rnorm()生成的。
配色
主体是连续量,用发散色阶:低端暖红 #B1615C、中间白、高端冷紫 #5A5A83,锚点落在中位数上。发散而不是渐进,是因为表达数据关心的是"比中间水平高还是低",有天然的两侧。
注释条则用定性色——样本类型、性别、通路都是分类变量,深浅没有意义。这个分工必须清楚:主体连续、注释定性,混了读者就分不清哪个通道在编码什么。


