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

ggplot2中为geom_smooth()指定自定义置信区间及分组实现

自定义geom_smooth置信区间上下限实现方案

核心逻辑

geom_smooth()本身不支持直接传入自定义值替换默认计算的标准误置信区间,要实现自定义上下限的平滑填充带,搭配geom_ribbon()即可完成:先对上下限变量做与平滑线同参数的非参数拟合,再将拟合值作为ymin/ymax传入geom_ribbon()绘制填充层,最后叠加关闭默认se的geom_smooth()线条即可。

单组数据实现

参考代码如下,效果与默认geom_smooth()结构完全一致,仅填充区间替换为自定义的高低温平滑范围:

library(ggplot2)
set.seed(123)
mean_temp <- runif(365, min = 10, max = 25)
max_temp <- runif(365, min = 26, max = 35)
min_temp <- runif(365, min = 0, max = 9)

temp <- data.frame(day = 1:365, mean = mean_temp, max = max_temp, min = min_temp)

# 提前拟合高低温的平滑值,loess参数与geom_smooth默认保持一致
temp$smooth_low <- predict(loess(min ~ day, data = temp, span = 0.75))
temp$smooth_high <- predict(loess(max ~ day, data = temp, span = 0.75))

ggplot(temp, aes(x = day, y = mean)) +
  geom_ribbon(aes(ymin = smooth_low, ymax = smooth_high),
              alpha = 0.2, fill = "grey50") +
  geom_smooth(se = FALSE, color = "#2166ac", linewidth = 1)

注意:不建议直接使用min/max这类R内置函数名作为变量名,容易触发函数调用冲突。

多分组数据问题修复

原有代码填充带无法按分组匹配的两个核心原因:

  • 仅用group_by()给数据打分组标签时,在aes()内部直接调用predict(loess(...))不会自动按分组建模,会使用全量数据拟合出一套全局上下限,所有分组共用
  • geom_ribbon()需要映射fill美学与分组变量绑定,仅映射color无法生成独立的分组填充区域,还会出现多余的填充带边框
    修复后可正常生成各分组独立的平滑线+匹配填充带:
library(tidyverse)
set.seed(123)
# 构造示例数据
temp <- rbind(
  data.frame(day = 1:365, 
             mean = runif(365, 10, 25), 
             max = runif(365, 26, 35), 
             min = runif(365, 0, 9), 
             label = 'A'),
  data.frame(day = 1:365, 
             mean = runif(365, 10, 25), 
             max = runif(365, 200, 220), 
             min = runif(365, -10, 9), 
             label = 'B'),
  data.frame(day = 1:365, 
             mean = runif(365, 10, 25), 
             max = runif(365, 30, 40), 
             min = runif(365, -5, 5), 
             label = 'C')
)

# 按分组分别拟合高低温平滑值
temp <- temp %>% 
  group_by(label) %>% 
  group_modify(~{
    .x$smooth_low <- predict(loess(min ~ day, data = .x, span = 0.75))
    .x$smooth_high <- predict(loess(max ~ day, data = .x, span = 0.75))
    .x
  }) %>% 
  ungroup()

# 绘图
ggplot(temp, aes(x = day, y = mean, color = label, fill = label)) +
  geom_ribbon(aes(ymin = smooth_low, ymax = smooth_high),
              alpha = 0.1, color = NA) +
  geom_smooth(se = FALSE, linewidth = 1)

绘制注意事项

  • 图层顺序遵循“先下层后上层”:geom_ribbon()要放在geom_smooth()之前调用,避免填充带遮挡平滑线
  • 拟合上下限的模型参数(如loess的span值)要与geom_smooth()使用的参数保持一致,避免填充带与中间曲线的平滑度不匹配
  • 多分组场景下geom_ribbon()设置color = NA可以去掉填充区域的外边框,视觉效果与默认geom_smooth(se=TRUE)的样式完全统一

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 10:00:59