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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 04:36:04