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

R pheatmap隐藏列名时自定义行名颜色报错原因及实现方法

问题背景

Windows 10系统RStudio环境下,使用R语言pheatmap包绘制热图时,参考公开实现方案可在同时展示行名、列名的热图中完成行名选择性着色;但设置参数隐藏列名、仅对指定行名设置自定义颜色时,会触发如下报错:
Error in set.gpar(x$gp, grob = x) : argument must be a 'gpar' object

测试数据构造代码

构造测试用表达矩阵的代码如下:

library(pheatmap)
test = matrix(rnorm(200), 20, 10)
test[1:10, seq(1, 10, 2)] = test[1:10, seq(1, 10, 2)] + 3
test[11:20, seq(2, 10, 2)] = test[11:20, seq(2, 10, 2)] + 2
test[15:20, seq(2, 10, 2)] = test[15:20, seq(2, 10, 2)] + 4
colnames(test) = paste("Test", 1:10, sep = "")
rownames(test) = paste("Gene", 1:20, sep = "")

可正常运行的参考实现

同时显示行名、列名时,指定行名标红的着色代码可正常运行,代码如下:

library(grid)
library(gridExtra)
library(pheatmap)
hm <- pheatmap(test, silent = TRUE)
hm$gtable$grobs[[5]]$gp$col <- rep(c("black", "red"), each = 10)
leg <- legendGrob(c("Exp1", "Exp2"), nrow = 2, pch = 15, gp = gpar(fontsize = 10, col = c("black", "red")))
hm2 <- arrangeGrob(hm$gtable, leg, ncol = 2, widths = c(5,1))
grid.draw(hm2)

报错场景复现

设置show_colnames=FALSE参数隐藏列名,运行如下代码时会触发前述gpar对象报错:

# 注:原复现代码存在笔误,漏写了hm <- 变量赋值
hm <- pheatmap(test, show_colnames=FALSE, silent=TRUE)
hm$gtable$grobs[[5]]$gp$col <- rep(c("black", "red"), each = 10)
leg <- legendGrob(c("Exp1", "Exp2"), nrow = 2, pch = 15, gp = gpar(fontsize = 10, col = c("black", "red")))
hm2 <- arrangeGrob(hm$gtable, leg, ncol = 2, widths = c(5,1))
grid.draw(hm2)
问题解答

1. 报错根本原因

  • 参考代码硬编码了行名对应的图形对象(grob)索引为[[5]],这个索引仅在同时显示行名、列名时成立:此时pheatmap生成的gtable组件排布顺序固定,行名文本刚好是第5个grob对象。
  • 当设置show_colnames=FALSE隐藏列名后,pheatmap不会生成列名对应的grob,gtable内所有组件的索引整体前移,此时第5位的grob不再是行名文本,而是聚类树、热图主体这类没有文本颜色属性的组件,强行修改它的gp$col参数时,就会触发「传入参数不是合法gpar对象」的报错。
  • 补充:复现代码第一行漏了hm <-赋值,直接调用pheatmap()不会把绘图结果存入hm变量,也会导致后续对象不存在的报错,但这不是gpar报错的核心诱因。

2. 隐藏列名时实现行名选择性着色的方案

核心思路是放弃硬编码grob索引,先遍历hm$gtable$grobs定位到真正对应行名的文本grob,再修改它的颜色属性即可,全程仅依赖pheatmap、grid、gridExtra包,不需要替换其他热图包。
可直接运行的代码如下:

library(grid)
library(gridExtra)
library(pheatmap)

# 绘制热图,设置隐藏列名
hm <- pheatmap(test, show_colnames = FALSE, silent = TRUE)

# 动态查找行名对应的grob:匹配text类型、标签与矩阵行名完全一致的对象
row_name_grob_idx <- which(sapply(hm$gtable$grobs, function(g){
  inherits(g, "text") && identical(g$label, rownames(test))
}))

# 给行名设置自定义颜色,示例为前10个行名黑色、后10个行名红色
hm$gtable$grobs[[row_name_grob_idx]]$gp$col <- rep(c("black", "red"), each = 10)

# 添加分类图例并输出图像
leg <- legendGrob(c("Exp1", "Exp2"), nrow = 2, pch = 15, gp = gpar(fontsize = 10, col = c("black", "red")))
hm2 <- arrangeGrob(hm$gtable, leg, ncol = 2, widths = c(5,1))
grid.draw(hm2)

该方案不受show_colnames、是否显示聚类树等参数影响,只要行名正常显示,就能准确定位到对应组件完成颜色修改。如果需要自定义其他行的颜色,只需要调整传给gp$col的颜色向量,保证长度、顺序和行名一一对应即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 05:30:47