如何将4种表型的绘图合并为带共用连续刻度图例的2×2组合图?
解决R中多表型2×2组合图共用统一图例的方案
方案一:长数据分面法(最优,从根源避免图例不一致)
这是最直接高效的方法,通过数据格式转换+ggplot分面实现,自动共用统一图例,彻底规避单独绘图后合并的图例偏差问题。
- 数据整理:宽格式转长格式
把分散在不同列的四个表型数据,合并到同一数据框,新增phenotype列标记表型类型(WHR/BMI/BF/WC)。假设原数据框wide_df包含各表型对应的Estimate、p_value、sig_mark(显著性标记)及横轴变量(如SNP):
library(tidyr) library(dplyr) # 转换为长格式(适配多表型统一绘图) long_df <- wide_df %>% # 拆分表型相关列,生成phenotype标记列 pivot_longer( cols = ends_with(c("_Est", "_p", "_sig")), names_pattern = "(.*)_(.*)", names_to = c("phenotype", ".value") )
注:如果原数据是每个表型单独占一列,可根据实际列名调整pivot_longer的参数,核心是让所有表型的Estimate、p值、显著性标记对应到同一列下,用phenotype区分。
- 绘制2×2分面组合图
用ggplot2的facet_wrap实现2列布局,所有表型自动共用Estimate填充色和p值区间点大小的图例:
library(ggplot2) # 统一p值区间分组(和你单表型绘图的分组逻辑完全一致) long_df <- long_df %>% mutate(p_group = case_when( p < 1e-6 ~ "p < 1e-6", p < 1e-4 ~ "1e-6 ≤ p < 1e-4", p < 0.05 ~ "1e-4 ≤ p < 0.05", TRUE ~ "p ≥ 0.05" )) # 绘制组合图 combined_plot <- ggplot(long_df, aes(x = SNP, y = 你的纵轴变量)) + # 点:填充色绑定Estimate,大小绑定p值区间 geom_point(aes(fill = Estimate, size = p_group), shape = 21, color = "black") + # 添加显著性标记(如星号) geom_text(aes(label = sig_mark), vjust = -1, size = 3) + # 统一设置Estimate色阶(和单表型绘图保持一致) scale_fill_gradient2(low = "blue", mid = "white", high = "red", midpoint = 0) + # 统一设置点大小的顺序和范围 scale_size_discrete(breaks = c("p ≥ 0.05", "1e-4 ≤ p < 0.05", "1e-6 ≤ p < 1e-4", "p < 1e-6"), range = c(1, 4)) + # 2×2分面布局 facet_wrap(~ phenotype, ncol = 2) + # 主题调整,优化图例位置 theme_bw() + theme(legend.position = "bottom", legend.box = "vertical") print(combined_plot)
方案二:单独绘图后用patchwork合并(适需单独定制每个图的场景)
如果每个表型的图需要单独调整(比如不同坐标轴标签),可用patchwork包合并,统一提取一个图例避免不一致:
- 绘制单个表型图(隐藏各自图例)
library(patchwork) # 绘制WHR图,隐藏自身图例 p_whr <- ggplot(whr_df, aes(x = SNP, y = 纵轴变量)) + geom_point(aes(fill = Estimate, size = p_group), shape = 21) + geom_text(aes(label = sig_mark)) + scale_fill_gradient2(low = "blue", mid = "white", high = "red", midpoint = 0) + scale_size_discrete(breaks = c("p ≥ 0.05", "1e-4 ≤ p < 0.05", "1e-6 ≤ p < 1e-4", "p < 1e-6"), range = c(1,4)) + theme_bw() + theme(legend.position = "none") + labs(title = "WHR") # 同理绘制BMI、BF、WC图,命名为p_bmi, p_bf, p_wc,均隐藏图例
- 提取统一图例并合并
# 从任意一个图提取标准图例(比如p_whr) legend <- get_legend(p_whr + theme(legend.position = "bottom")) # 合并四个图为2×2布局,自动收集统一图例 final_plot <- (p_whr + p_bmi) / (p_bf + p_wc) + plot_layout(guides = "collect") + # 关键:统一收集图例 plot_annotation(tag_levels = 'A') # 可选:添加A/B/C/D分图标签 print(final_plot)
关键注意事项
- 无论用哪种方案,必须保证四个表型的
Estimate色阶范围、p值区间分组规则完全一致,否则即使合并图例也会出现偏差; - 分面法代码更简洁,自动同步所有映射规则,是优先推荐的方案;
- 用patchwork合并时,务必使用
plot_layout(guides = "collect")统一图例,不要手动调整每个图的图例参数。
内容的提问来源于stack exchange,提问作者Dovini Jayasinghe
相关产品推荐
相关产品推荐

