如何将共享图例置于2×2绘图网格的右下角空位?
解决方案
要实现把共用图例放在2×2网格的右下角空位,不需要额外的包,用ggplot2和patchwork就能搞定,核心思路是单独提取图例,把它当作第四块图来布局,而不是用plot_spacer()占位。
具体修改步骤
- 隐藏所有单个子图的图例,避免重复显示
- 从任意一个带图例规则的图中提取共用图例对象
- 将提取的图例作为第四个组件,和三个子图按2×2结构组合
修改后的完整代码
library(ggplot2) library(patchwork) set.seed(123) dummy_data <- data.frame( month = rep(c(0, 6, 18, 30), 4), value = c(100, 70, 50, 30, 100, 75, 55, 35, 100, 65, 45, 25, 100, 80, 60, 40), treatment = rep(c("true", "false"), each = 8), group = rep(c("A", "B"), each = 4, times = 2) ) a <- ggplot(dummy_data[dummy_data$group == "A", ], aes(x = month, y = value, color = treatment, group = treatment)) + geom_line(size = 1) + geom_point(size = 2) + theme_minimal() + labs(title = "Plot A (Group A)") + theme(legend.position = "none") # 隐藏单个图的图例 b <- ggplot(dummy_data[dummy_data$group == "B", ], aes(x = month, y = value, color = treatment, group = treatment)) + geom_line(size = 1) + geom_point(size = 2) + theme_minimal() + labs(title = "Plot B (Group B)") + theme(legend.position = "none") # 隐藏单个图的图例 c <- ggplot(dummy_data, aes(x = month, y = value, color = treatment, group = interaction(treatment, group))) + geom_line(size = 1) + geom_point(size = 2) + theme_minimal() + labs(title = "Plot C (All Groups)") + theme(legend.position = "none") # 隐藏单个图的图例 # 自定义函数提取图例对象 get_legend <- function(my_plot) { tmp <- ggplot_gtable(ggplot_build(my_plot)) leg_index <- which(sapply(tmp$grobs, function(x) x$name) == "guide-box") legend <- tmp$grobs[[leg_index]] return(legend) } # 生成临时图提取共用图例 tmp_plot <- ggplot(dummy_data, aes(x = month, y = value, color = treatment)) + geom_line() shared_legend <- get_legend(tmp_plot) # 按2×2布局组合图与图例 combined_plot <- (a + b) / (c + shared_legend) + plot_annotation(tag_levels = "A") combined_plot
关键说明
- 给每个子图添加
theme(legend.position = "none"),确保子图单独显示时不出现图例 - 通过
get_legend()函数从ggplot底层对象中提取图例组件,保证图例样式与原图一致 - 布局时直接将图例替换原
plot_spacer()的位置,即可让图例填充右下角的空位
内容的提问来源于stack exchange,提问作者Gabriel
相关产品推荐
相关产品推荐

