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

在R中用GGAnimate实现堆叠柱状图按年份逐次生长动画

堆叠柱状图按年份逐次生长的动画实现

需求说明

  • 按年份顺序逐次生长:先完成第一年柱子的生长,再启动第二年的生长
  • 已生长完成的年份柱子持续保留在画面中

问题分析

原示例代码存在两个核心问题:

  • 使用transition_states时,旧年份的柱子会随动画切换消失,无法保留
  • 使用transition_layers时,柱子按类别而非年份顺序生长,不符合需求

解决方案

通过数据预处理结合gganimate的专属动画函数,可完美实现需求,具体代码如下:

library(ggplot2) 
library(gganimate)
library(dplyr)

# 准备原始数据
year <- as.numeric(c(rep(1996:2015,3))) 
cat <- as.factor(as.character(c(rep("out", 20), rep("in", 20), rep("other", 20)))) 
c_val <- c(39, 40, 67, 80, 30, 140, 90, 23, 100, 123, 140, 160, 100, 89, 173, 200, 32, 90, 100, 211, 1, 2, 1, 13, 3, 3, 30, 1, 3, 3, 1, 1, 20, 2, 1, 10, 1, 2, 1, 1, 1, 3, 1, 2, 1, 3, 1, 3, 6, 1, 1, 30, 1, 1, 8, 9, 1, 32, 1, 1) 

static_df_test <- data.frame(year, cat, c_val) %>% 
    arrange(year, cat)

# 预处理数据:为每个年份生成包含之前所有年份的数据集
# 确保动画帧逐步累加显示年份,已生长的柱子不会消失
animate_df <- static_df_test %>%
  group_by(year) %>%
  group_map(function(.x, .y) {
    static_df_test %>% filter(year <= .y$year)
  }) %>%
  bind_rows(.id = "frame_year") %>%
  mutate(frame_year = as.numeric(frame_year))

# 绘制静态基础图
static_plot <- ggplot(animate_df) +
  geom_bar(stat="identity",
           aes(x = as.factor(year), y = c_val, fill = cat)) +
  scale_y_continuous(breaks = seq(0, 250, 25),
                     expand = c(0,0),
                     limits = c(0,250)) +
  labs(x = "年份", y = "数值") +
  theme_minimal()

# 添加动画效果
ani <- static_plot +
  transition_reveal(frame_year) +  # 按帧顺序递进展示年份
  enter_grow() +  # 新进入的柱子从x轴底部向上生长
  ease_aes('cubic-in-out')  # 缓动函数让动画过渡更平滑

# 播放动画(可调整fps和duration控制速度)
animate(ani, fps = 10, duration = 15)

关键逻辑说明

  1. 数据预处理:通过group_map生成每个动画帧对应的数据集,每个帧包含当前及之前所有年份的数据,从根源保证已生长的柱子持续保留
  2. transition_reveal:按自定义的frame_year顺序递进展示,严格遵循年份的先后生长顺序
  3. enter_grow:控制新加入的年份柱子从x轴底部向上生长,完全匹配"向上生长"的视觉需求
  4. ease_aes:设置缓动函数,让柱子生长的动画过渡更自然流畅

内容的提问来源于stack exchange,提问作者K.D.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 03:05:54