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

如何在R语言ggplot2中平滑geom_ribbon绘图曲线?

问题描述

制作昆虫丰度图时遇到以下问题:

  • 用geom_line()+geom_ribbon绘制的图存在大量尖锐转折
  • 尝试用geom_smooth(默认loess平滑)调整,效果不理想,添加SE后仍无法满足需求
  • 需求:不使用stat=smooth,仅平滑ribbon曲线,且保留geom_line+geom_ribbon的呈现方式

现有初始代码:

Y2_insect_time%>% ggplot(aes(x = Date.num, y =total, colour = Treatment))+
    geom_line(aes(alpha= 1))  + 
    geom_ribbon(aes(ymax = total + seY2t, ymin = total - seY2t,alpha = 0.01 , fill =  Treatment)) +
    guides(alpha="none") +
    theme_bw() +
    xlab(NULL) +
    ylab("macroinvertebrates collected") +
    ggtitle("Number of Macroinvertebrates Over Time in Year Two")

尝试的geom_smooth代码:

Y2_insect_time%>% ggplot(aes(x = Date.num, y =total, colour = Treatment))+ 
geom_smooth(data=Y2_insect_time,n=8,span=0.8,se=FALSE, aes(x=Date.num, y=total,  alpha=0.1,weight=1,fill = Treatment)) + 
guides(alpha="none") +
theme_bw() +
xlab(NULL) +
ylab("macroinvertebrates collected") +
ggtitle("Number of Macroinvertebrates Over Time in Year Two")
可行解决方案

核心思路是先对原始数据的趋势线(total)和误差范围(seY2t)进行平滑预处理,再用处理后的数据绘制geom_line和geom_ribbon,既能保留你偏好的图结构,又能消除尖锐转折。

方法1:用loess手动平滑分组数据

按Treatment分组,对total、total+seY2t、total-seY2t分别做loess平滑,生成新的平滑后变量:

library(dplyr)
library(ggplot2)

# 分组平滑数据
smoothed_data <- Y2_insect_time %>%
  group_by(Treatment) %>%
  mutate(
    # 平滑趋势线total
    smooth_total = predict(loess(total ~ Date.num, span = 0.8), newdata = .),
    # 平滑上限:total+seY2t
    smooth_ymax = predict(loess((total + seY2t) ~ Date.num, span = 0.8), newdata = .),
    # 平滑下限:total-seY2t
    smooth_ymin = predict(loess((total - seY2t) ~ Date.num, span = 0.8), newdata = .)
  ) %>%
  ungroup()

# 用平滑后的数据绘图
smoothed_data %>%
  ggplot(aes(x = Date.num, colour = Treatment, fill = Treatment)) +
  geom_line(aes(y = smooth_total), alpha = 1) +
  geom_ribbon(aes(ymax = smooth_ymax, ymin = smooth_ymin), alpha = 0.1) +
  guides(alpha = "none") +
  theme_bw() +
  xlab(NULL) +
  ylab("采集到的大型无脊椎动物数量") +
  ggtitle("第二年大型无脊椎动物数量随时间变化")
  • 调整span参数控制平滑程度:值越大曲线越平缓,值越小越贴近原始数据
  • 若数据量较大,可改用gam(广义加性模型)替代loess提升效率:
library(mgcv)
smoothed_data <- Y2_insect_time %>%
  group_by(Treatment) %>%
  mutate(
    smooth_total = predict(gam(total ~ s(Date.num, k = 8)), newdata = .),
    smooth_ymax = predict(gam((total + seY2t) ~ s(Date.num, k = 8)), newdata = .),
    smooth_ymin = predict(gam((total - seY2t) ~ s(Date.num, k = 8)), newdata = .)
  ) %>%
  ungroup()
  • k参数控制样条曲线自由度,值越大曲线越灵活

方法2:用zoo包的滑动平均平滑

如果偏好简单平滑方式,可使用滑动平均处理变量:

library(zoo)
smoothed_data <- Y2_insect_time %>%
  group_by(Treatment) %>%
  arrange(Date.num) %>%
  mutate(
    smooth_total = rollmean(total, k = 3, fill = "extend"),
    smooth_ymax = rollmean(total + seY2t, k = 3, fill = "extend"),
    smooth_ymin = rollmean(total - seY2t, k = 3, fill = "extend")
  ) %>%
  ungroup()
  • k为滑动窗口大小,值越大平滑效果越强;fill = "extend"用于填充首尾缺失值

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.01 15:52:28