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

如何在ggplot中获取loess拟合线与y=0交点的x值并标记红点?

解决方案

要给每个分面的loess拟合线和y=0的交点加红点,关键是先按id分组算出每个子图的交点x值,再把这些点加到图里。具体步骤如下:

1. 计算每个id对应的交点x值

用dplyr分组处理,给每个id单独拟合loess模型,然后找到y=0对应的x:

library(dplyr)
library(ggplot2)

# 按id分组计算交点
intersection_points <- SF01_05 %>%
  group_by(id) %>%
  summarise(
    # 拟合当前id的loess模型
    loess_fit = loess(Mean.T2 ~ number$x, data = cur_data()),
    # 生成密集的x序列用于预测,保证交点精度
    x_seq = seq(min(number$x), max(number$x), length.out = 1000),
    # 预测对应x的y值
    y_pred = predict(loess_fit, newdata = data.frame(`number$x` = x_seq))
  ) %>%
  # 找到y_pred最接近0的那个x值,作为交点
  mutate(threshold = x_seq[which.min(abs(y_pred - 0))]) %>%
  # 只保留需要的id和threshold列
  select(id, threshold)

2. 修改绘图代码,添加红点

把计算好的交点数据用geom_point加到分面图里,注意要匹配每个分面的id:

ggplot(SF01_05, aes(x = number$x, y = Mean.T2, color = Month)) +
  geom_point() +
  geom_smooth(method = loess) +
  # 添加红色交点,指定数据来源是我们计算的intersection_points
  geom_point(data = intersection_points, aes(x = threshold, y = 0), color = "red", size = 3) +
  # 保留你原来的辅助线(如果需要的话)
  geom_segment(data = intersection_points, aes(x = threshold, xend = threshold, y = -Inf, yend = 0), col = 2, linetype = 1) +
  geom_segment(aes(x = -Inf, xend = Inf, y = 0, yend = 0), col = 2, linetype = 1) +
  ggtitle("Daily Average Air-temperature (-2cm)") +
  theme_bw() +
  xlab("Days") +
  ylab("Temperature ( ºC )") +
  theme(legend.position = "none") +
  scale_y_continuous(breaks = seq(-10, 16, 2), limits = c(-10, 16)) +
  scale_x_continuous(breaks = seq(0, 200, 50), limits = c(0, 200)) +
  facet_wrap(. ~ id)

几点说明

  • 分组计算是核心,确保每个id用自己的数据拟合模型,得到专属的交点x值
  • 生成1000个x值预测y,能保证找到的交点足够接近真实值
  • 添加红点时必须指定data = intersection_points,否则会用主数据框的所有数据重复绘制
  • 把原来的x轴辅助线改成xend = Inf,这样每条子图的y=0线能贯穿整个x轴范围

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 20:11:09