基于变量关系绘制二元热图:ggplot2绘图异常排查求助
解决你的热图绘制问题
嘿,我来帮你搞定这个热图的问题!你遇到的两个异常——多出一列、颜色映射不对——其实都是代码细节和数据格式的小问题,咱们一步步修正:
问题根源分析
为什么会出现3列?
你连续调用了两次geom_tile(),第一次没有指定任何填充映射,ggplot会自动生成一个默认图层,第二次又叠加了带fill=value映射的图层,两者叠加后就出现了多余的列,完全是重复图层导致的。颜色映射为什么不对?
你的原始数据是长格式(每个药物只对应一个靶标),但热图需要显示所有药物-靶标的组合(包括无关联的),才能画出白色的空白方块。另外你直接把fill映射到value,却没明确指定每个value对应的颜色,逻辑也不对——你需要的是“有=黑,无=白”,而不是按靶标类别上色。
修正后的完整方案
我们先把数据补全为所有药物-靶标的组合,再标记是否存在关联,最后用这个标记来控制颜色:
步骤1:加载工具包并处理数据
library(ggplot2) library(tidyr) # 用来生成所有组合,没有的话可以先运行 install.packages("tidyr") # 你的原始数据 DrugName <- c("as","df","fg","gh","jk") value <- c("AD","AD","AD","AD","SEL") MELT <- data.frame(DrugName, value) # 给原始数据添加"是否关联"的标记,然后生成所有药物-靶标的组合 MELT <- MELT %>% mutate(has_association = TRUE) MELT_full <- complete(MELT, DrugName, value, fill = list(has_association = FALSE))
步骤2:绘制正确的热图
ggplot(MELT_full, aes(x = value, y = DrugName)) + geom_tile(aes(fill = has_association), colour = "white") + # 用关联标记控制填充色,白色边框分隔网格 scale_fill_manual(values = c("FALSE" = "white", "TRUE" = "black")) + # 明确指定真假状态对应的颜色 labs(x = "靶标符号", y = "药物名称") + # 设置坐标轴标签 theme_minimal() # 可选:用简洁的主题优化视觉效果
不用tidyr的替代方案
如果你不想安装tidyr,也可以用基础R的expand.grid生成所有组合:
# 生成所有药物-靶标的组合 all_combinations <- expand.grid(DrugName = unique(MELT$DrugName), value = unique(MELT$value)) # 合并原始数据,标记关联状态 MELT_full <- merge(all_combinations, MELT, by = c("DrugName", "value"), all.x = TRUE) MELT_full$has_association <- !is.na(MELT_full$value.y)
然后用同样的ggplot代码绘图即可。
关键要点总结
- 不要重复调用
geom_tile(),避免图层冲突导致的异常列; - 必须包含所有药物-靶标组合,才能显示无关联的白色方块;
- 把
fill映射到“是否关联”的逻辑标记,而不是直接用靶标类别,这样颜色逻辑更清晰。
内容的提问来源于stack exchange,提问作者firmo23
相关产品推荐
相关产品推荐

