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

如何将ggplot2中geom_smooth拟合线按Y=0截线分色(红上绿下)

实现loess拟合线分色显示的方法

要实现loess拟合线在Y=0上方红、下方绿的效果,不能直接用geom_smooth()的默认参数,得先手动计算拟合值,再拆分数据分别绘制。具体步骤如下:

1. 准备示例数据(可替换成你的真实数据)

先模拟一个和你结构一致的数据集,方便测试:

set.seed(123) # 固定随机种子,结果可复现
df <- data.frame(
  SL = 1:100,
  log = rnorm(100, mean = 0, sd = 1) + seq(-2, 2, length.out = 100)
)

2. 计算loess拟合的预测值

用loess()函数拟合模型,然后生成包含SL、拟合值的数据集,同时根据拟合值是否大于0标记分组:

# 拟合loess模型
loess_model <- loess(log ~ SL, data = df)
# 生成预测数据,按SL排序避免线条错乱
pred_df <- data.frame(SL = df$SL)
pred_df$fit <- predict(loess_model, newdata = pred_df)
# 添加分组列:区分拟合值在Y=0上下的部分
pred_df$color_group <- ifelse(pred_df$fit > 0, "above_zero", "below_zero")

3. 用ggplot绘制图形

先画散点图和Y=0的水平线,再用geom_line()绘制拆分后的拟合线:

library(ggplot2)

ggplot(df, aes(x = SL, y = log)) +
  geom_point(alpha = 0.5) + # 散点图,alpha设小点避免重叠
  geom_hline(yintercept = 0, linetype = "dashed", color = "gray50") + # Y=0截距线
  geom_line(data = pred_df, aes(y = fit, color = color_group), linewidth = 1) + # 分色拟合线
  scale_color_manual(
    values = c("above_zero" = "red", "below_zero" = "green"),
    guide = "none" # 不需要显示图例的话加这行
  ) +
  labs(x = "序号(SL)", y = "表达值(log)") +
  theme_minimal()

关键说明

  • 手动计算拟合值是核心:geom_smooth()内部也是用loess拟合,但不会返回拆分后的拟合数据,所以必须手动生成预测集。
  • 一定要按SL排序:如果预测数据的SL顺序乱了,绘制的线条会出现交叉,所以确保pred_df的SL和原数据一致。
  • 若需要保留geom_smooth()的置信区间:可以先画默认的置信区间(用geom_smooth(se=TRUE, color=NA)),再叠加分色的拟合线,这样置信区间不受颜色影响。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 09:04:53