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

如何将ggplot2绘图的图例拆分为两行?

解决ggplot2图例拆分为两行的问题

你的代码里图例无法换行的核心原因是重复调用guides()导致设置被覆盖,同时当前的绘图方式没有用统一的分组映射,增加了图例管理的复杂度。以下是具体的修正方案:

关键问题分析

  • 先后调用guides(color = guide_legend(nrow = 2, byrow = T))和guides(col = guide_legend(...)),后者会完全覆盖前者的设置,导致图例换行的nrow=2参数未生效。
  • 直接给不同子集单独添加geom_point/geom_smooth,未通过aes映射统一分组变量,图例元素对应关系混乱。
  • scale_colour_manual的labels参数写法错误,无需加col=前缀,直接传入字符向量即可。

修正后的完整代码

先规范整理数据,添加分组列,让ggplot通过映射处理不同组的点和拟合线:

library(tidyverse)
library(ggpmisc)
library(ggpubr)

# 为数据添加分组变量(假设data已加载)
data <- data %>%
  mutate(
    group = case_when(
      Nu < 53 ~ "Pot",
      Nu %in% 53:64 ~ "Pot liming",
      Nu %in% 65:76 ~ "Incubation",
      Nu > 76 ~ "Incubation liming",
      TRUE ~ NA_character_
    ),
    line_group = case_when(
      group %in% c("Pot", "Incubation liming") ~ group,
      TRUE ~ "Dashed lines"
    )
  ) %>%
  drop_na(group)

my.formula = y ~ exp(1.5*-x)

p1 <- ggplot(data = data, aes(x = pH, y = Cd_ppm)) +
  # 统一映射分组到颜色和形状
  geom_point(aes(col = group, shape = group), size = 3.5) +
  # 拟合线按分组映射颜色和线型
  geom_smooth(aes(col = line_group, linetype = line_group),
              formula = my.formula, method = "lm", se = F, level = 0.95, size = 0.5) +
  # 添加R²标注
  stat_poly_eq(data = subset(data, group == "Pot"),
               formula = my.formula, aes(label = paste(..rr.label..)),
               label.x.npc = "left", label.y.npc = 0.03, parse = T, size = 6, col = "black") +
  stat_poly_eq(data = subset(data, group == "Pot liming"),
               formula = my.formula, aes(label = paste(..rr.label..)),
               label.x.npc = "left", label.y.npc = 0.1, parse = T, size = 6, col = "black") +
  stat_poly_eq(data = subset(data, group == "Incubation liming"),
               formula = my.formula, aes(label = paste(..rr.label..)),
               label.x.npc = "right", label.y.npc = 0.8, parse = T, size = 6, col = "black") +
  stat_poly_eq(data = subset(data, group == "Incubation"),
               formula = my.formula, aes(label = paste(..rr.label..)),
               label.x.npc = "right", label.y.npc = 0.9, parse = T, size = 6, col = "black") +
  # 坐标轴标签
  labs(x = "pH", y = expression(Cd~~~mg~(kg~soil)^{-1})) +
  # 手动设置颜色、形状、线型
  scale_colour_manual(
    name = "",
    values = c("Pot" = "black", "Pot liming" = "black", 
               "Incubation" = "black", "Incubation liming" = "black",
               "Dashed lines" = "black"),
    labels = c("Pot", "Pot liming", "Incubation", "Incubation liming", "")
  ) +
  scale_shape_manual(
    name = "",
    values = c("Pot" = 16, "Pot liming" = 17, "Incubation" = 2, "Incubation liming" = 1)
  ) +
  scale_linetype_manual(
    name = "",
    values = c("Pot" = "solid", "Incubation liming" = "solid", "Dashed lines" = "dashed")
  ) +
  # 主题与图例设置
  theme(
    legend.text = element_text(colour = "black", size = 17, face = 1),
    legend.position = "bottom",
    legend.box = "vertical",
    legend.margin = margin(t = 0, r = 0, b = 0, l = 0)
  ) +
  guides(
    col = guide_legend(nrow = 2, byrow = TRUE, 
                       override.aes = list(linetype = c("solid", "dashed", "dashed", "solid"), shape = c(16,17,2,1))),
    shape = guide_legend(nrow = 2, byrow = TRUE),
    linetype = "none"
  )

# 保存图片
png(file = "grafic1.png", height = 125, width = 150, unit = "mm", res = 300)
print(p1)
dev.off()

核心修改点说明

  1. 数据整理:添加group和line_group列,将子集筛选转换为分组变量,让ggplot通过映射自动处理不同组的元素,避免重复调用geom层。
  2. 合并guides设置:将图例换行的nrow=2参数放到最终的guides(col=...)中,同时设置byrow=TRUE让图例按行排列,避免被覆盖。
  3. 统一图例元素:通过override.aes在guides中统一设置每个图例项的形状和线型,确保点线样式对应正确,同时隐藏多余的线型图例,只保留一个合并后的图例。

内容的提问来源于stack exchange,提问作者Shohnazar Hazratqulov

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 00:10:47