在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)
关键逻辑说明
- 数据预处理:通过
group_map生成每个动画帧对应的数据集,每个帧包含当前及之前所有年份的数据,从根源保证已生长的柱子持续保留 - transition_reveal:按自定义的
frame_year顺序递进展示,严格遵循年份的先后生长顺序 - enter_grow:控制新加入的年份柱子从x轴底部向上生长,完全匹配"向上生长"的视觉需求
- ease_aes:设置缓动函数,让柱子生长的动画过渡更自然流畅
内容的提问来源于stack exchange,提问作者K.D.
相关产品推荐
相关产品推荐

