使用ggarrange合并含不同元素的绘图图例及分组图例需求
解决ggarrange合并图例缺失及图例分组问题
一、修复缺失的图例元素
问题根源是两个子图的gear因子水平未统一,且ggplot默认会隐藏无对应数据的图例项。按以下步骤处理:
- 统一因子水平:先将原始数据的
gear转换为包含所有目标水平(3、4、5)的因子,确保子图保留完整的因子集合:
library(tidyverse) library(ggpubr) library(grid) data("mtcars") # 统一gear的因子水平,包含3、4、5三个取值 mtcars$gear <- factor(mtcars$gear, levels = c("3", "4", "5"))
- 修改绘图代码:在
scale_color_manual中指定所有三个水平的颜色,并设置drop=FALSE强制显示所有图例项:
mtcars1 <- mtcars %>% filter(gear %in% c("3", "4")) p1 <- ggplot(mtcars1, aes(x=wt, y=mpg, color = gear))+ geom_point()+ scale_color_manual( values = c("3"="red", "4"="blue", "5"="green"), drop = FALSE # 强制保留所有因子水平的图例 ) mtcars2 <- mtcars %>% filter(gear %in% c("3", "5")) p2 <- ggplot(mtcars2, aes(x=wt, y=mpg, color = gear))+ geom_point()+ scale_color_manual( values = c("3"="red", "4"="blue", "5"="green"), drop = FALSE )
- 合并绘图与完整图例:此时使用
ggarrange的common.legend=TRUE就能得到包含所有元素的公共图例:
ggarrange(p1, p2, common.legend = TRUE, legend = "right")
二、实现图例分组标注
要给图例添加分组(gear3/4归为"low",gear5归为"medium")及大括号标注,可通过自定义图例grob实现:
- 移除子图图例并提取完整图例:
# 移除子图自带的图例 p1_noleg <- p1 + theme(legend.position = "none") p2_noleg <- p2 + theme(legend.position = "none") # 提取包含所有元素的完整图例 full_legend <- get_legend(p1)
- 创建分组标注元素:用
grid包生成分组文字和模拟大括号的线条:
# 分组标签文字 low_label <- textGrob("low", x = 0.12, y = 0.78, gp = gpar(fontsize = 10)) medium_label <- textGrob("medium", x = 0.12, y = 0.38, gp = gpar(fontsize = 10)) # 模拟大括号的线条 low_bracket <- linesGrob( x = c(0.05, 0.05, 0.25, 0.25), y = c(0.75, 0.7, 0.7, 0.75), gp = gpar(lwd = 1) ) medium_bracket <- linesGrob( x = c(0.05, 0.05, 0.25, 0.25), y = c(0.35, 0.3, 0.3, 0.35), gp = gpar(lwd = 1) )
- 组合自定义图例与绘图:将分组元素与原图例合并,再和子图组合:
# 组合图例与分组标注元素 custom_legend <- gTree(children = gList(full_legend, low_label, low_bracket, medium_label, medium_bracket)) # 最终组合绘图与自定义图例 ggarrange( p1_noleg, p2_noleg, custom_legend, ncol = 2, nrow = 2, heights = c(4, 1), # 调整绘图区和图例区的高度比例 align = "hv" )
说明
- 若需要更逼真的大括号效果,可使用
gridExtra包的bracketGrob函数替代linesGrob。 - 所有颜色、位置、字体大小等参数可根据需求自行调整。
内容的提问来源于stack exchange,提问作者Elliot
相关产品推荐
相关产品推荐

