如何为ggplot中同色异线型的lm拟合线条添加图例?
解决ggplot拟合曲线的图例生成问题
你的问题核心在于:把颜色、线型这类需要生成图例的属性直接写在了aes()外面,这属于手动设置图形属性,而非映射数据到图形属性,所以ggplot无法自动生成图例。要解决这个问题,我们需要调整数据格式并把映射关系放到aes()内部,具体步骤如下:
1. 把宽格式数据转换为长格式
ggplot对长格式数据的支持更好,我们可以用tidyr::pivot_longer()把full里的DU/DUR列转成长格式,方便后续分组映射:
library(ggplot2) library(tidyr) # 保留你原来的数据构建代码 empty_list <- vector(mode = "list", length = 2) test1 <- data.frame(matrix(ncol = 2, nrow = 0)) x <- c("DU", "DUR") colnames(test1)<-x test1[1,1] = 2 test1[2,1] = 4 test1[1,2] = 6 test1[2,2] = 8 test2 <- data.frame(matrix(ncol = 2, nrow = 0)) colnames(test2)<-x test2[1,1] = 3 test2[2,1] = 5 test2[1,2] = 7 test2[2,2] = 9 empty_list[[1]] <- test1 empty_list[[2]] <- test2 for (i in 1 : length(empty_list)){ colnames(empty_list[[i]]) = c( paste("DU", i, sep = ""), paste("DUR", i, sep = "")) } full <- cbind(empty_list[[1]], empty_list[[2]]) x <- 1:nrow(full) full <- cbind(x, full) colnames(full)[1] <- "num" # 转换为长格式 full_long <- pivot_longer(full, cols = starts_with(c("DU", "DUR")), names_to = c("type", "group"), names_pattern = "(DU|DUR)(\\d)")
2. 用映射方式绘制拟合曲线并生成图例
现在我们可以在aes()里映射group(对应颜色分组)、color(对应组1/组2)和linetype(对应DU/DUR),然后手动指定想要的颜色和线型:
ggplot(full_long, aes(x = num, y = value)) + # 用stat_smooth统一拟合lm曲线,把分组映射放到aes内部 stat_smooth(aes(color = group, linetype = type), method = "lm", formula = y ~ x, se = FALSE) + # 手动设置分组颜色:组1用颜色1,组2用颜色2 scale_color_manual(values = c("1" = 1, "2" = 2), labels = c("Group 1", "Group 2"), name = "分组") + # 手动设置线型:DU用实线,DUR用虚线 scale_linetype_manual(values = c("DU" = "solid", "DUR" = "dashed"), labels = c("DU", "DUR"), name = "类型") + labs(x = "num", y = "数值") + theme_minimal()
代码解释
pivot_longer()把原来的宽列(DU1、DUR1、DU2、DUR2)拆分成了type(DU/DUR)和group(1/2)两个分组变量,让ggplot能清晰识别不同线条的分组规则。stat_smooth()里的aes(color = group, linetype = type)把颜色和线型与数据变量绑定,这是生成图例的关键——只有映射到数据变量的属性,ggplot才会自动创建图例。scale_color_manual()和scale_linetype_manual()用来指定你想要的颜色、线型,同时可以自定义图例的名称和标签,完全匹配你的需求。
这样修改后,不仅能生成符合要求的图例,代码也更简洁易维护,后续如果要添加更多分组(比如DU3、DUR3),只需要修改数据部分,绘图代码不需要大改。
内容的提问来源于stack exchange,提问作者Ziqin He
相关产品推荐
相关产品推荐

