You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何拆分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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 03:23:21