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

如何强制ggplot2中geom_smooth曲线起始点保持一致?

问题描述

请问能否强制ggplot2的geom_smooth曲线起始点相同?我有如下数据集:

Year_start avg_start_salary adjusted_wage
   1979         7.000000         8.000  
   1980         7.000000         9.080  
   1981         8.000000         9.080  
   1982         8.500000         9.080  
   1984         8.900000        11.000  
   1985         9.000000        11.288  
   1986         9.100000        11.440  
   1987         9.000000        11.728  
   1988         8.800000        12.056  
   1989        11.000000        12.440 

我尝试修改下面的ggplot代码,让两条曲线起始点一致,但geom_smooth函数自动调整了它们:

ggplot(plot_data, aes(x = Year_start)) +
  # Smoothed trend line for avg_start_salary
  geom_smooth(aes(y = avg_start_salary, color = "Start Salary"), method = "loess", se = FALSE, size = 1.2) +
  # Smoothed trend line for adjusted_wage
  geom_smooth(aes(y = adjusted_wage, color = "Adjusted Salary"), method = "loess", se = FALSE, size = 1.2) +
  labs(title = "Average Starting Salary and Adjusted Salary Over Time",
       x = "Year", y = "Salary") +
  scale_color_manual(name = "Caption", values = c("Adjusted Salary" = "blue", "Start Salary" = "red")) +
  theme_minimal()

解决方法

问题核心是geom_smooth默认会针对每条曲线的拟合数据自动生成x轴预测范围,导致两条曲线的起始/结束点错位。要强制起始点一致,最可靠的方式是手动拟合loess模型,用统一的x序列生成预测值,再用geom_line绘制曲线,具体步骤如下:

1. 生成统一的x预测序列

先提取数据的时间范围,生成连续的年份序列,确保两条曲线用完全相同的x值做预测:

# 生成从最早到最晚年份的连续序列(1979到1989)
pred_x <- seq(min(plot_data$Year_start), max(plot_data$Year_start), by = 1)

2. 分别拟合模型并生成预测值

对两个薪资变量各自拟合loess模型,用统一的x序列生成预测结果:

# 拟合起始薪资的loess模型
model_start <- loess(avg_start_salary ~ Year_start, data = plot_data)
pred_start <- predict(model_start, newdata = data.frame(Year_start = pred_x))

# 拟合调整后薪资的loess模型
model_adjusted <- loess(adjusted_wage ~ Year_start, data = plot_data)
pred_adjusted <- predict(model_adjusted, newdata = data.frame(Year_start = pred_x))

# 合并成绘图用的数据框
plot_pred <- data.frame(
  Year_start = pred_x,
  Start_Salary = pred_start,
  Adjusted_Salary = pred_adjusted
)

3. 绘制对齐后的曲线

用预测数据框绘图,两条曲线的x轴范围完全一致,起始点自然对齐:

ggplot() +
  # 绘制起始薪资平滑曲线
  geom_line(data = plot_pred, aes(x = Year_start, y = Start_Salary, color = "Start Salary"), size = 1.2) +
  # 绘制调整后薪资平滑曲线
  geom_line(data = plot_pred, aes(x = Year_start, y = Adjusted_Salary, color = "Adjusted Salary"), size = 1.2) +
  # 可选:添加原始数据点用于对比
  geom_point(data = plot_data, aes(x = Year_start, y = avg_start_salary), color = "red", size = 2) +
  geom_point(data = plot_data, aes(x = Year_start, y = adjusted_wage), color = "blue", size = 2) +
  labs(title = "Average Starting Salary and Adjusted Salary Over Time",
       x = "Year", y = "Salary") +
  scale_color_manual(name = "Caption", values = c("Adjusted Salary" = "blue", "Start Salary" = "red")) +
  theme_minimal()

额外说明

  • 如果想简化操作,也可以给geom_smooth加上xlim = c(1979, 1989)固定x轴范围,但这只是视觉截断,曲线的拟合逻辑还是各自独立,可靠性不如手动拟合。
  • loess默认span = 0.75,手动拟合时保持这个参数,就能和原geom_smooth的平滑程度一致。

内容的提问来源于stack exchange,提问作者Abner Mácola

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 19:37:11