如何为分组ggplot组合图添加统一图例及分组标题?
解决ggplot分组组合图的统一图例与分组标题问题
可复现数据集与基础绘图代码
先构造模拟数据集,再生成4个需要组合的子图:
library(ggplot2) library(patchwork) library(dplyr) # 构造可复现数据集 set.seed(123) data <- mtcars %>% mutate( sex = rep(c("Men", "Women"), each = 16), subgroup = rep(c("Subplot 1", "Subplot 2"), times = 16), value = rnorm(nrow(mtcars), mean = mpg, sd = 2) ) # 生成4个子图,隐藏单个图例避免重复 p_men1 <- ggplot(data %>% filter(sex == "Men", subgroup == "Subplot 1"), aes(x = wt, y = value, color = factor(cyl))) + geom_point() + theme_bw() + theme(legend.position = "none") p_men2 <- ggplot(data %>% filter(sex == "Men", subgroup == "Subplot 2"), aes(x = wt, y = value, color = factor(cyl))) + geom_point() + theme_bw() + theme(legend.position = "none") p_women1 <- ggplot(data %>% filter(sex == "Women", subgroup == "Subplot 1"), aes(x = wt, y = value, color = factor(cyl))) + geom_point() + theme_bw() + theme(legend.position = "none") p_women2 <- ggplot(data %>% filter(sex == "Women", subgroup == "Subplot 2"), aes(x = wt, y = value, color = factor(cyl))) + geom_point() + theme_bw() + theme(legend.position = "none")
最优解决方案:使用patchwork包
patchwork能同时实现分组标题添加和统一图例收集,且不会挤压子图:
# 组合男女分组子图并添加分组标题 men_group <- p_men1 + p_men2 + plot_annotation(title = "Men", theme = theme(plot.title = element_text(hjust = 0.5, size = 14, face = "bold"))) women_group <- p_women1 + p_women2 + plot_annotation(title = "Women", theme = theme(plot.title = element_text(hjust = 0.5, size = 14, face = "bold"))) # 整体布局:上下排列分组,自动收集统一图例 final_plot <- (men_group / women_group) + plot_layout(guides = "collect") + # 自动合并所有子图的共同图例 plot_annotation(theme = theme(plot.margin = margin(10, 10, 10, 10))) # 微调边距避免图例拥挤 print(final_plot)
代码说明
- 隐藏单个图例:每个子图设置
theme(legend.position = "none"),避免重复显示图例。 - 分组标题:用
plot_annotation给男女分组的子图组合添加标题,并居中对齐。 - 统一图例:
plot_layout(guides = "collect")会自动提取所有子图的共同图例,默认放置在右侧,不会挤压绘图区域。 - 边距调整:通过
plot.margin微调整体边距,让布局更美观。
备选方案:手动提取图例并放置
如果需要更灵活的图例位置,可手动提取图例后嵌入布局:
# 提取统一图例 shared_legend <- get_legend( ggplot(data, aes(x = wt, y = value, color = factor(cyl))) + geom_point() + theme_bw() + guides(color = guide_legend(title = "Number of Cylinders")) ) # 组合布局:左右分栏,左侧放分组图,右侧放图例 final_plot_custom <- (men_group / women_group) + shared_legend + plot_layout(widths = c(4, 1)) # 控制绘图区与图例区的宽度比例 print(final_plot_custom)
内容的提问来源于stack exchange,提问作者Vicki Latham
相关产品推荐
相关产品推荐

