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
相关产品推荐
相关产品推荐

