如何用gganimate实现彩虹糖华夫图的随机食用动画?
实现彩虹糖华夫图的随机食用动画
需求说明
已有代码可生成包含55颗彩虹糖(每种颜色11颗)的华夫图,需要用gganimate创建动画,模拟每次随机吃掉1颗彩虹糖的过程,直到所有糖都被吃完。
解决方案代码
library(tibble) library(dplyr) library(ggplot2) library(waffle) library(gganimate) # 生成初始彩虹糖数据:每种颜色11颗,共55颗 skittles_full <- tibble(colour = rep(c("purple", "pink", "red", "blue", "green"), 11)) # 生成每一步的数据集:从55颗到0颗,每次随机移除1颗 animation_data <- purrr::map(0:55, ~{ skittles_full %>% slice_sample(n = 55 - .x) %>% count(colour, name = "n") %>% # 确保所有颜色都存在(即使数量为0) right_join(tibble(colour = unique(skittles_full$colour)), by = "colour") %>% mutate(n = replace_na(n, 0)) }) %>% bind_rows(.id = "frame") %>% mutate(frame = as.integer(frame)) # 绘制动画 ggplot(animation_data, aes(label = colour, values = n, color = colour)) + geom_pictogram() + scale_label_pictogram(name = NULL, values = rep("circle", 5)) + scale_color_manual(name = NULL, values = c(purple = "purple", pink = "pink", red = "red", blue = "blue", green = "green")) + coord_equal() + theme_nothing() + guides(label = guide_legend(byrow = TRUE)) + theme(legend.spacing.y = unit(0.5, "cm")) + # 动画切换设置:逐帧过渡,每帧停留0.2秒 transition_states(frame, transition_length = 0, state_length = 0.2) + enter_fade() + exit_fade()
关键逻辑说明
- 逐帧数据构建:用
purrr::map遍历0到55的步数,每次从完整数据集中随机抽取对应剩余数量的彩虹糖,统计各颜色数量;通过right_join保证所有颜色在每一步都保留(避免某颜色吃完后从数据中消失)。 - 动画效果优化:
transition_states控制帧切换节奏,enter_fade和exit_fade让彩虹糖消失时带有淡入淡出效果,避免画面生硬跳转。 - 图例稳定性:即使某颜色糖被吃完,图例仍保留对应颜色条目,保证动画过程中图例一致。
内容的提问来源于stack exchange,提问作者luciano
相关产品推荐
相关产品推荐

