You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ComplexHeatmap注释数据缺失问询:大样本与barplot结果不一致

ComplexHeatmap大样本热图注释数据缺失问题解析

问题复现

先看你提供的复现代码,用1000列的矩阵搭配仅含少量1的注释数据:

set.seed(0)
mm = matrix(data = rnorm(1000 * 8), nrow = 8)
rownames(mm) = letters[1:8]
annodf = data.frame(var1=rbinom(1000, 1, .01))
library(ComplexHeatmap)
ha = HeatmapAnnotation(df=annodf, col=list("var1"=c("0"="white","1"="red")))
ht = Heatmap(mm, show_column_dend = F, show_column_names = F, bottom_annotation = ha)
draw(ht)

出现的矛盾现象:

  • 实际统计sum(annodf$var1)得到12个1
  • 用barplot(annodf$var1[column_order(ht)])能看到正确的红色条数量,但热图底部注释仅显示9条
  • 小样本(如5×5矩阵)下,热图注释和barplot结果完全一致

核心原因:大样本下的像素合并优化

这其实是ComplexHeatmap的默认性能优化机制——当热图列数极多(比如这里的1000列),每一列在绘图区域分配到的宽度会小于1像素。为了避免绘制大量极小色块导致的性能下降,同时让注释视觉上更整洁,包会自动把相邻的同色注释块合并成一个连续色块。这就导致视觉上看到的红色线条数量比实际数据中的1少,但底层数据是完全正确的,只是显示层面做了合并处理。

而小样本时每列宽度足够,不需要触发这种合并逻辑,所以注释显示和实际数据完全匹配。

解决办法

根据你的需求,有几种处理方式:

  • 强制关闭合并优化:创建HeatmapAnnotation时添加simple_anno_size_adjust = FALSE参数,让注释严格按每一列绘制,不合并同色块:
ha = HeatmapAnnotation(df=annodf, col=list("var1"=c("0"="white","1"="red")), simple_anno_size_adjust = FALSE)

这样能完整显示所有1的位置,但列数极多时可能会有轻微卡顿。

  • 加宽注释区域:通过annotation_width参数给注释分配更大的宽度,让每一列能分到足够像素,自然就不需要合并了:
ha = HeatmapAnnotation(df=annodf, col=list("var1"=c("0"="white","1"="red")), annotation_width = unit(10, "cm"))

你可以根据绘图尺寸调整unit里的数值,比如改成unit(8, "cm"),直到所有红色条清晰显示。

  • 验证数据正确性:如果只是想确认注释数据没问题,无需修改绘图,可提取热图列顺序后统计:
# 提取热图的列顺序
col_order = column_order(ht)
# 统计注释数据中1的数量
table(annodf$var1[col_order])

结果会显示实际1的数量,确认数据本身无问题,只是显示优化导致视觉差异。

内容的提问来源于stack exchange,提问作者highBandWidth

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 08:07:09