R ggplot2按分组展示数据与趋势线对应图例的实现问题
问题原因
你的原代码仅将color映射到分组变量,ggplot会自动把使用相同color映射的geom_line和geom_smooth合并为同一个图例项,因此无法区分实线的实际值和虚线的趋势线。
解决方案
基础ggplot实现(无需额外包)
通过新增linetype映射区分实际值和趋势线,调整图例合并规则即可接近预期效果:
# 加载包 library(ggplot2) # 原有数据保持不变 week <- c(1,2,3,4,5,1,2,3,4,5) hits <- c(262,698,239,195,122,160,746,283,557,239) rate <- c(116, 134, 154, 185, 167, 216, 178, 242, 267, 234) lower <- c(94, 111, 123, 145, 138, 196, 147, 204, 216, 176) upper <- c(126, 167, 176, 225, 191, 245, 199, 287, 292, 267) group <- c("A","A","A","A","A","B","B","B","B","B") df <- data.frame(week = week, hits=hits, rate=rate, lower=lower, upper=upper,group=group) # 修改后的绘图代码 ggplot(df, aes(x = week)) + geom_line(aes(y = rate, color = group, linetype = "实际rate值")) + geom_ribbon(aes(ymin = lower, ymax = upper, fill = group), alpha = 0.2, show.legend = FALSE) + geom_smooth(aes(y = rate, color = group, linetype = "线性趋势线"), method = 'lm', size = 0.5, se = FALSE) + scale_color_manual(values = c("A" = "red", "B" = "black"), name = "分组") + scale_fill_manual(values = c("A" = "red", "B" = "black")) + scale_linetype_manual(values = c("实际rate值" = "solid", "线性趋势线" = "dashed"), name = NULL) + theme( legend.title = element_text(face = "bold"), legend.spacing.y = unit(0.2, "cm") )
嵌套式图例实现(和预期效果完全一致)
如果需要严格实现「分组作为标题、对应线条放在分组下方」的嵌套效果,可以借助ggh4x包的嵌套图例功能:
# 首次使用先安装包 # install.packages("ggh4x") library(ggplot2) library(ggh4x) # 数据部分和上面一致,直接用前面构造的df即可 ggplot(df, aes(x = week)) + geom_line(aes(y = rate, color = group, linetype = "实际rate值")) + geom_ribbon(aes(ymin = lower, ymax = upper, fill = group), alpha = 0.2, show.legend = FALSE) + geom_smooth(aes(y = rate, color = group, linetype = "线性趋势线"), method = 'lm', size = 0.5, se = FALSE) + scale_color_manual(values = c("A" = "red", "B" = "black")) + scale_fill_manual(values = c("A" = "red", "B" = "black")) + scale_linetype_manual(values = c("实际rate值" = "solid", "线性趋势线" = "dashed"), name = NULL) + guides( color = "none", linetype = guide_nested( nest = c(group = "A", group = "B"), data = df, title = "分组" ) )
内容的提问来源于stack exchange,提问作者AstraOK
相关产品推荐
相关产品推荐

