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

如何在ggplot中平滑带fill填充的时间序列geom_area图形?

问题说明

当前已绘制9T、9C两类就诊占比的堆叠百分比面积图,原始效果如下:
原始堆叠百分比面积图

原始绘图代码:

ggplot(long2, aes(x = DATA, y = value, fill = variable)) + geom_area(position="fill", alpha=0.75) +
      scale_y_continuous(labels = scales::comma,n.breaks = 5,breaks = waiver()) +
      scale_fill_viridis_d() +
      scale_x_date(date_labels = "%b/%Y",date_breaks = "6 months") +
      ggtitle("Proporcions de les visites, només 9T i 9C") +
      xlab("Data") + ylab("% visites") + 
      theme_minimal() + theme(legend.position="bottom") + guides(fill=guide_legend(title=NULL)) +

        annotate("rect", fill = "white", alpha = 0.3, 
        xmin = as.Date.character("2020-03-16"), xmax = as.Date.character("2020-06-22"),
        ymin = 0, ymax = 1)

当前图形存在明显锯齿状波动,需要做平滑处理。

可用平滑方案

以下三种方案可根据数据粒度和展示需求选择:

  • 方案1:ggplot图层内直接平滑(代码改动最小)
    直接在现有绘图代码中叠加平滑图层,指定位置参数为position="fill"与原面积图对齐,选择适合时间序列的局部加权回归(loess)方法,关闭置信区间避免干扰视觉。新增代码片段如下:
    geom_smooth(method = "loess", se = FALSE, 
                position = "fill", span = 0.2, linewidth = 0)
    
    其中span参数控制平滑程度,值越大曲线越平滑;linewidth=0用于关闭平滑线描边,让平滑填充区域和原面积图自然融合。
  • 方案2:数据预处理做滚动平均(结果最稳定,适合业务场景)
    这类锯齿大多来自单日就诊数据的随机波动,先按类别分组做滚动平均再绘图,不会出现比例失真问题。需要加载dplyr和zoo包做数据处理:
    library(dplyr)
    library(zoo)
    # 按类别分组做7天滚动平均,窗口大小k可根据波动幅度调整
    long2_smooth <- long2 %>%
      arrange(DATA) %>%
      group_by(variable) %>%
      mutate(smooth_value = rollmean(value, k = 7, fill = NA, align = "center")) %>%
      ungroup()
    
    后续绘图只需要将原代码中aes里的y = value替换为y = smooth_value即可,其余代码完全不用改动。
  • 方案3:样条插值顺滑边缘(适合展示类可视化)
    如果需要完全无锯齿的顺滑曲线,可以对每个分组的时间序列做三次样条插值,生成密度更高的时间点拟合值后再绘图,生成的面积边缘会完全平滑。

注意:所有平滑操作后都需要校验每个时间节点的两类占比之和是否为1,避免平滑算法导致比例失真;原有疫情时段的白色半透明标注矩形放在所有图层最上层即可,不需要调整。

内容的提问来源于stack exchange,提问作者José Ángel Vicente Gómez

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 06:57:16