R ggplot2 geom_ribbon()分组绘制置信区间出现尖刺锯齿异常
问题根因
geom_ribbon()绘制出带尖刺的锯齿状填充,核心是绘图逻辑和数据粒度不匹配:
- 你通过
predictInterval()得到的upr、lwr是**单条原始观测(单个被试单个时间点)**的预测区间边界,同一Time、同一Treatment分组下,不同被试的上下界值是分散的 - 你画拟合线、上下界虚线时用了
stat_summary(),会自动按Treatment分组对y值求均值后再绘制,所以虚线显示正常 - 但
geom_ribbon()默认使用stat="identity",直接逐行读取原始观测的lwr/upr连线填充,相当于把所有被试的独立区间挨个串起来填充,自然会出现尖刺 - 按Subject分组绘图时能正常显示,是因为每个分组下每个Time点仅对应单个被试的一组lwr/upr值,不存在多观测混排,所以填充效果正常
解决方案
两种可直接复用的实现方式,按需选择即可:
方案1:提前聚合数据再绘图
先按绘图维度对数据分组求均值,再用聚合后的数据集绘图,从根源避免逐观测连线的问题:
library(dplyr) library(ggplot2) # 按绘图维度提前聚合指标 GCA_agg <- GCA3 %>% filter(Experiment == "Blocking", Time <= 10) %>% group_by(Experiment, Treatment, Time) %>% summarise( GCA_Full = mean(GCA_Full, na.rm = TRUE), upr = mean(upr, na.rm = TRUE), lwr = mean(lwr, na.rm = TRUE), .groups = "drop" ) # 直接用聚合后的数据绘图,无需嵌套stat_summary mplot2 <- ggplot(GCA_agg, aes(Time, GCA_Full, group = Treatment, fill = Treatment, color = Treatment))+ geom_line(linewidth = 1) + # 模型拟合线 geom_ribbon(aes(ymin = lwr, ymax = upr), color = NA, alpha = 0.1) + # 置信区间填充 geom_line(aes(y = upr), linetype = "dashed") + # 上界虚线 geom_line(aes(y = lwr), linetype = "dashed") + # 下界虚线 theme_bw(base_size = 10) + facet_wrap(~Experiment) + labs(x = "Item", y = "Accuracy (elogit)") + scale_x_continuous(breaks = seq(0, 10, 1))
方案2:在geom_ribbon中指定汇总统计逻辑
不提前聚合数据,直接给geom_ribbon添加统计汇总参数,让它和stat_summary逻辑一致,先按分组求均值再绘制填充区域:
mplot2 <- filter(GCA3, Experiment == "Blocking", Time <= 10) %>% ggplot(aes(Time, GCA_Full, group = Treatment, fill = Treatment, color = Treatment))+ stat_summary(aes(y = GCA_Full), fun = mean, geom = "line")+ stat_summary(aes(y = upr), fun = mean, geom = "line", linetype = "dashed")+ stat_summary(aes(y = lwr), fun = mean, geom = "line", linetype = "dashed")+ # 给ribbon添加stat和fun参数,自动按分组聚合上下界 geom_ribbon(aes(ymin = lwr, ymax = upr), stat = "summary", fun = mean, na.rm = TRUE, color = NA, alpha = 0.1) + theme_bw(base_size = 10) + facet_wrap(~Experiment) labels <- labs(x = "Item", y = "Accuracy (elogit)") mplot2 + labels + scale_x_continuous(breaks = seq(0, 10, 1))
补充说明
注意:上述方法是对逐观测预测区间求均值得到分组区间,本质上不是严格的总体均值置信区间。如果需要更严谨的群体水平置信区间,建议在predictInterval阶段就构建仅包含Treatment、Experiment、Time维度(剔除Subject随机效应)的新数据框做预测,不要对原始逐被试数据的预测结果直接求均值。
内容的提问来源于stack exchange,提问作者Nick
相关产品推荐
相关产品推荐

