02平滑线、分组与线型

理解 geom_smooth 如何继承分组映射,并用颜色、线型和图例控制多组趋势。

2026-03-03
Rggplot2geom_smoothGroupingRegression
本章目录 · 5

geom_smooth() 根据数据拟合趋势线。画一条还是多条线,首先由分组决定;颜色和线型则决定这些组是否能在视觉上区分。

一条全局趋势线

没有分组映射时,所有观测共同拟合一条线:

library(ggplot2)

ggplot(mpg, aes(displ, hwy)) +
  geom_point() +
  geom_smooth()

默认会同时显示拟合线与置信带。探索数据时可以保留置信带;只想突出趋势线时设置 se = FALSE

只分组,不改变外观

group 可以让各类别分别拟合,但不会自动为线条设置不同颜色:

ggplot(mpg, aes(displ, hwy)) +
  geom_point() +
  geom_smooth(aes(group = drv))

这里每个 drv 类别都有一条趋势线,但所有线使用同一种默认外观。这适合分组本身有意义、却不希望建立颜色图例的特殊场景;多数组别比较中,可辨识度并不好。

使用颜色同时完成分组

将离散变量映射给 color 时,ggplot2 会据此分组,并用颜色区分趋势线:

ggplot(mpg, aes(displ, hwy, color = drv)) +
  geom_point() +
  geom_smooth()

如果图中已经直接标注类别,或图例确实多余,可以只在指定图层隐藏:

ggplot(mpg, aes(displ, hwy)) +
  geom_smooth(aes(color = drv), show.legend = FALSE)

隐藏图例不会取消分组或颜色映射,只改变图例显示。

点用 shape,线用 linetype

shape 只对点等具有形状的几何对象生效。把它映射给 geom_smooth() 不会让线条出现不同点形:

ggplot(mpg, aes(displ, hwy, shape = drv)) +
  geom_smooth()

区分线条应使用 linetype

ggplot(mpg, aes(displ, hwy, linetype = drv)) +
  geom_smooth(se = FALSE)

点与趋势线可以分别使用适合自身几何结构的属性:

ggplot(mpg, aes(displ, hwy, color = drv)) +
  geom_point(aes(shape = drv)) +
  geom_smooth(aes(linetype = drv), se = FALSE)

颜色同时建立共同分组,点使用形状,线使用线型。这种冗余编码在黑白打印或色觉差异场景中更稳健,但类别过多时会让图例变得拥挤。

全局映射与图层映射

写在 ggplot() 中的映射会被后续图层继承:

ggplot(mpg, aes(displ, hwy, color = drv)) +
  geom_point() +
  geom_smooth()

如果只希望平滑线分组,而散点保持统一颜色,就把映射放进该图层:

ggplot(mpg, aes(displ, hwy)) +
  geom_point(color = "grey60") +
  geom_smooth(aes(color = drv), se = FALSE)

反过来,如果散点按组着色但只需要一条总趋势线,可以在平滑层中明确覆盖分组:

ggplot(mpg, aes(displ, hwy, color = drv)) +
  geom_point() +
  geom_smooth(
    aes(group = 1),
    color = "black",
    se = FALSE
  )

设计多图层时,应逐层问:它使用哪些数据、继承哪些映射、需要怎样分组、哪些属性固定。这样比反复试参数更容易预测结果。