如何将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()
核心修改点说明
- 数据整理:添加
group和line_group列,将子集筛选转换为分组变量,让ggplot通过映射自动处理不同组的元素,避免重复调用geom层。 - 合并guides设置:将图例换行的
nrow=2参数放到最终的guides(col=...)中,同时设置byrow=TRUE让图例按行排列,避免被覆盖。 - 统一图例元素:通过
override.aes在guides中统一设置每个图例项的形状和线型,确保点线样式对应正确,同时隐藏多余的线型图例,只保留一个合并后的图例。
内容的提问来源于stack exchange,提问作者Shohnazar Hazratqulov
相关产品推荐
相关产品推荐

