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

ggplot2中为第二个geom_smooth设置颜色/线型并自定义图例

问题描述

我正在制作包含多组数据的图表,每组数据分别拟合两种线性模型:等权重模型、按分组区间内点数加权的模型。

模拟数据代码:

test_data <- 
  bind_rows(
  tibble(test_x=rbeta(500,0.05,0.05),
         test_y=5*test_x+4+runif(length(test_x),0,3),
         group="group-a" ),
  tibble(test_x=rbeta(500,0.05,0.05),
         test_y=3*test_x+3+runif(length(test_x),0,3),
         group="group-b" ),
  ) |>
  mutate(test_x=floor(test_x * 20)/20 + 1/(2*20) ) |>
  group_by(test_x,group) |> summarise(n=n(),test_y=mean(test_y))

当前绘图代码:

test_data |> ggplot(aes(x=test_x,y=test_y,group=group,color=group)) + 
  geom_point() +geom_smooth(method = lm,se=FALSE) + 
  geom_smooth(aes(weight=n),method = lm,se=FALSE)

尝试给加权拟合线添加linetype="dashed"后,线型未显示在图例中。需求如下:

  • 让线型信息显示在图例中
  • 更理想的是,自定义图例,分别展示「group-a加权拟合」「group-a未加权拟合」「group-b加权拟合」「group-b未加权拟合」,每条线对应匹配的颜色/样式。

解决方案

方法1:分组与拟合类型联动,保留双图例

这种方式保留「分组」和「拟合类型」两个独立图例,颜色对应分组,线型对应加权/未加权状态:

library(ggplot2)
library(dplyr)

test_data |> 
  ggplot(aes(x = test_x, y = test_y)) +
  # 原始数据点,按分组着色
  geom_point(aes(color = group)) +
  # 未加权拟合线:实线,绑定分组颜色
  geom_smooth(
    aes(group = paste(group, "unweighted"), color = group, linetype = "unweighted"),
    method = lm, se = FALSE
  ) +
  # 加权拟合线:虚线,绑定分组颜色,使用n作为权重
  geom_smooth(
    aes(group = paste(group, "weighted"), color = group, linetype = "weighted", weight = n),
    method = lm, se = FALSE
  ) +
  # 自定义线型图例
  scale_linetype_manual(
    name = "拟合类型",
    values = c("unweighted" = "solid", "weighted" = "dashed"),
    labels = c("未加权", "加权")
  ) +
  # 自定义分组颜色图例
  scale_color_discrete(name = "分组") +
  labs(title = "分组加权/未加权线性拟合", x = "test_x", y = "test_y") +
  theme_minimal()

方法2:拆分所有拟合线为独立图例项

如果需要把每个组的两种拟合都作为单独的图例条目,可通过创建「分组+拟合类型」的组合变量实现:

# 预处理数据,复制并添加拟合类型标识
test_data_combined <- bind_rows(
  test_data |> mutate(model = "unweighted"),
  test_data |> mutate(model = "weighted")
)

test_data_combined |> 
  ggplot(aes(x = test_x, y = test_y)) +
  # 原始数据点,按分组着色
  geom_point(aes(color = group)) +
  # 拟合线:按组合变量分组,颜色对应组合,线型对应拟合类型
  geom_smooth(
    aes(
      group = interaction(group, model),
      color = interaction(group, model),
      linetype = model,
      weight = ifelse(model == "weighted", n, 1)
    ),
    method = lm, se = FALSE
  ) +
  # 自定义组合图例的标签
  scale_color_discrete(
    name = "拟合组合",
    labels = c(
      "group-a.unweighted" = "group-a 未加权",
      "group-a.weighted" = "group-a 加权",
      "group-b.unweighted" = "group-b 未加权",
      "group-b.weighted" = "group-b 加权"
    )
  ) +
  # 自定义线型图例
  scale_linetype_manual(
    name = "拟合类型",
    values = c("unweighted" = "solid", "weighted" = "dashed"),
    labels = c("未加权", "加权")
  ) +
  labs(title = "分组加权/未加权线性拟合", x = "test_x", y = "test_y") +
  theme_minimal()

核心逻辑说明

  • 让ggplot识别每条拟合线为独立分组:通过paste(group, model)或interaction(group, model)生成唯一标识
  • 权重绑定:加权模型使用n作为权重,未加权模型使用默认等权重(或显式指定weight=1)
  • 图例自定义:通过scale_*_manual或scale_color_discrete调整图例的名称、标签和样式,确保所有元素正确显示

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 12:47:36