求助:用ggplot2绘制带MAX行热图向量与MEAN列数值向量的热图
热图优化实现方案
需求回顾
基于给定的敏感性数值表绘制热图,要求:
- 主热图展示
rm500/rm500dropout/rf/knn四种方法在各癌症类型的敏感性 - 主热图下方添加
MAX行的热图向量 - 主热图左侧添加
MEAN列的数值标签 - 统一颜色标尺,优化布局与可读性
优化后的完整代码
# 加载并安装必要包 if(!require('ggheatmapper')) { install.packages('ggheatmapper') library('ggheatmapper') } if(!require('tidyverse')) { install.packages('tidyverse') library('tidyverse') } if(!require('RColorBrewer')) { install.packages('RColorBrewer') library('RColorBrewer') } # 构造数据(替代读取文件,方便直接运行) sensi <- tibble::tribble( ~method, ~`Adrenal gland`, ~`Bladder urothelium`, ~Breast, ~`Cervical tissue`, ~`Colorectal tissue`, ~Esophagus, ~Kidney, ~Lung, ~Pancreas, ~Prostate, ~Stomach, ~Thyroid, ~Uterus, ~MEAN, "rm500", 1, 1, 0.99562363238512, 0.411764705882353, 0.381136950904393, 0.549485352335709, 1, 0.99822695035461, 1, 0.638297872340426, 0.224719101123595, 0.996825396825397, 0.50354609929078, 0.746125081649414, "rm500dropout", 1, 1, 0.99781181619256, 0.647058823529412, 0.723735408560311, 0.294754371357202, 1, 1, 1, 0.424242424242424, 0.166112956810631, 0.98159509202454, 0.492753623188406, 0.748312655069653, "rf", 1, 0.80952380952381, 0.945414847161572, 0.105263157894737, 0.987163029525032, 0.98961937716263, 1, 0.998269896193772, 1, 0.991803278688525, 0.972144846796657, 0.996927803379416, 0.97887323943662, 0.905769483520213, "knn", 1, 0.857142857142857, 0.925925925925926, 0.315789473684211, 0.985879332477535, 0.987543252595156, 1, 0.998269896193772, 1, 0.97119341563786, 0.974930362116992, 0.996927803379416, 0.971830985915493, 0.921956408082248, "MAX", 1, 1, 0.99781181619256, 0.647058823529412, 0.987163029525032, 0.98961937716263, 1, 1, 1, 0.991803278688525, 0.974930362116992, 0.996927803379416, 0.97887323943662, 0.966475979233168 ) %>% column_to_rownames("method") # 分离主热图数据和MAX行数据 main_data <- sensi %>% filter(!rownames(.) == "MAX") %>% select(-MEAN) max_data <- sensi %>% filter(rownames(.) == "MAX") %>% select(-MEAN) %>% t() %>% as.data.frame() %>% rownames_to_column("cancer_type") %>% rename(MAX = V1) mean_data <- sensi %>% filter(!rownames(.) == "MAX") %>% select(MEAN) %>% rownames_to_column("method") # 绘制主热图 hm <- ggheatmap(main_data, colv = colnames(main_data), rowv = rownames(main_data), cluster_rows = FALSE, cluster_cols = FALSE, # 若需要聚类可改为TRUE,这里保持原始列顺序 colors_title = "Sensitivity", hm_color_limits = c(0,1), hm_colors = brewer.pal(7, "Blues"), fontsize = 18, show_dend_row = FALSE, show_dend_col = FALSE, show_colnames = FALSE) # 绘制下方MAX热图轨道 max_track <- max_data %>% mutate(cancer_type = factor(cancer_type, levels = get_colLevels(hm))) %>% ggplot(aes(x = cancer_type, y = 1, fill = MAX)) + geom_tile(color = "white") + scale_fill_gradientn(colors = brewer.pal(7, "Blues"), limits = c(0,1)) + labs(x = NULL, y = NULL) + guides(fill = "none") + theme_minimal(base_size = 14) + theme(axis.text.x = element_text(angle = 90, hjust = 1, vjust = 0.5, face = "bold"), axis.text.y = element_blank(), panel.grid = element_blank()) # 绘制左侧MEAN数值轨道 mean_track <- mean_data %>% mutate(method = factor(method, levels = get_rowLevels(hm))) %>% ggplot(aes(x = 1, y = method, label = sprintf("%.3f", MEAN))) + geom_text(size = 5, hjust = 1) + labs(x = NULL, y = NULL) + scale_x_discrete(position = "top") + theme_void(base_size = 14) + theme(axis.text.x = element_text(face = "bold", hjust = 0), plot.margin = margin(r = 5)) # 组合图表并导出 png("sensitivity_optimized.png", width = 1200, height = 800, res = 120) hm %>% align_to_hm(mean_track, newplt_size_prop = 0.15, pos = "left") %>% align_to_hm(max_track, newplt_size_prop = 0.1, pos = "bottom", legend_action = "collect") dev.off()
核心优化点说明
- 数据处理简化:使用
dplyr的column_to_rownames/rownames_to_column替代手动绑定,逻辑更清晰,避免列索引错误 - 轨道位置修正:将MEAN数值轨道移至主热图左侧(符合需求),MAX轨道固定在下方
- 主题与样式统一:
- 主热图与MAX轨道使用完全一致的颜色标尺,避免视觉冲突
- 移除冗余主题叠加,统一使用
theme_minimal/theme_void,减少样式混乱 - 调整字体大小、边距,提升可读性
- 布局协调:增大图表分辨率,调整各轨道的占比(
newplt_size_prop),让整体布局更均衡 - 列顺序对齐:强制MAX轨道的列顺序与主热图完全一致,避免错位
最终效果描述
- 主热图清晰展示四种方法在13种癌症类型的敏感性数值,蓝色渐变对应0-1的敏感性范围
- 左侧MEAN列精准标注每种方法的平均敏感性,与主热图行完全对齐
- 下方MAX行热图向量用相同颜色标尺展示各癌症类型的最大敏感性,列顺序与主热图一致
- 底部显示旋转90度的癌症类型名称,便于阅读
- 右侧仅保留一个统一的敏感性颜色图例,简洁明了
内容的提问来源于stack exchange,提问作者Legmi
相关产品推荐
相关产品推荐

