如何拆分ggplot2单个图例使其显示两个独立标题
给ggplot图例添加分组标题
要实现单个图例下包含两个分组标题(Group 1对应line1/line2,Group 2对应line3/line4),可以通过以下步骤操作:
1. 预处理数据
先给数据框新增分组变量,明确每个type所属的分组,同时调整type的顺序保证分组内的线条放在一起:
set.seed(1993) years <- 2017:2022 ngroups <- 4 df <- expand.grid( year = rep(years, each = ngroups), value = rep(runif(length(years), min = 0, max = 100), each = ngroups) + rnorm(length(years) * ngroups, sd = 10), type = factor(rep(1:ngroups, length(years))), stringsAsFactors = FALSE ) df$type <- unlist(lapply(split(df$type, df$year), function(x) sample(x))) # 新增分组变量 df$group <- ifelse(df$type %in% c(1,2), "Group 1", "Group 2") # 调整type的层级顺序,确保Group1的线条排在前面 df$type <- factor(df$type, levels = c(1,2,3,4))
2. 绘制带分组标题的图例
我们可以通过修改ggplot的底层绘图对象,在图例中插入分组标题,实现单个图例下的分组展示:
library(ggplot2) library(grid) library(gtable) # 绘制基础折线图 p <- ggplot(df, aes(x = year, y = value, linetype = type, color = type)) + geom_line() + # 调整图例布局为2行2列,按行排列,隐藏默认标题 guides( linetype = guide_legend(title = "", nrow = 2, byrow = TRUE), color = guide_legend(title = "", nrow = 2, byrow = TRUE) ) + theme( legend.position = "right", legend.spacing.y = unit(10, "pt") # 增加图例项垂直间距 ) # 提取绘图对象并修改图例部分 grob <- ggplotGrob(p) legend_index <- which(grob$layout$name == "guide-box") legend <- grob$grobs[[legend_index]] # 给图例添加标题行 legend <- gtable_add_rows(legend, unit(10, "pt"), 0) legend <- gtable_add_rows(legend, unit(10, "pt"), 3) # 插入Group 1和Group 2标题 legend <- gtable_add_grob(legend, textGrob("Group 1", x = 0, hjust = 0, gp = gpar(fontface = "bold")), t = 1, l = 1, r = 2 ) legend <- gtable_add_grob(legend, textGrob("Group 2", x = 0, hjust = 0, gp = gpar(fontface = "bold")), t = 4, l = 1, r = 2 ) # 替换原图例并输出图表 grob$grobs[[legend_index]] <- legend grid.draw(grob)
内容的提问来源于stack exchange,提问作者Sharif Amlani
相关产品推荐
相关产品推荐

