如何用gganimate实现geom_col柱状图逐个显示动画
柱状图逐柱动画实现:从问题到解决
需求
使用geom_col()制作动画柱状图,实现柱子逐个显示且保留已显示的柱子。
示例数据
fr <- structure(list(HOME = c("Verona", "Atalanta", "Genk"), AWAY = c("Inter", "Fiorentina", "Gent"), Domicile = c(5.7034e-08, 0.9916, 0.37966 ), Nul = c(0.0015489, 0.0083796, 0.39583), Défaite = c(0.99845, 2.0228e-05, 0.22451)), row.names = c(NA, -3L), class = c("tbl_df", "tbl", "data.frame"))
初始尝试与问题
初始数据处理代码
fr <- fr %>% slice(1:nrow(.), row_number()) %>% mutate(across(c((ncol(.)-3+1):(ncol(.))),~base::as.numeric(ifelse(row_number() <= 0.5*n(), 0, .x)))) %>% group_by(HOME,AWAY) %>% mutate(ID = seq_along(HOME)) %>% pivot_longer( cols=c(Domicile, Nul, Défaite), values_to="prob", names_to = "type") %>% mutate(game=paste0(HOME," - ", AWAY)) fr$type <-factor(fr$type,levels=c("Domicile","Nul","Défaite"))
初始绘图代码
f <- ggplot(fr, aes(x = type, y = prob)) f <- f + geom_col(aes(fill = type,group=game)) + geom_text(aes(label=ifelse(prob > 0,sprintf("%0.2f%%",prob*100),""), y=prob+0.15,color=type),fontface = "bold",family="Oswald", size=4)+ facet_wrap(~game, scale="fixed",axes = "all_x",as.table = TRUE)+ labs(subtitle = "Estimations après simulation de Monte Carlo sur un paramètre interne")+ transition_states(type, wrap=FALSE)+ enter_grow()+ shadow_mark(past = TRUE) f
遇到的问题
- 第一个对应
Domicile的柱子提前显示,无法观察其生长过程; - 柱子并非从底部生长,百分比文本标签直接显示最终值,不随柱子高度变化。
最终解决方案
数据处理调整
添加frame2变量匹配transition_states(),确保动画序列正确:
fr <- fr %>% mutate(type=factor(type,levels=c("Domicile","Nul","Défaite"))) %>% ungroup() %>% arrange(ID, type) %>% mutate(frame2 = letters[rep(1:nrow(.), each = 3, length.out = nrow(.))]) %>% mutate(prob = round(prob, 4))
绘图代码优化
使用新的frame2变量过渡,添加enter_fly()让文本标签跟随柱子生长,调整Y轴适配文本显示:
f <- ggplot(fr, aes(x = type, y = prob,fill = type, group = type)) f <- f + geom_col() + geom_text(aes(label = ifelse(prob > 0,paste0(" ", scales::percent(prob, accuracy = 0.01)),""), color = type),fontface = "bold",family = "Oswald", size = 4,vjust = -1)+ scale_y_continuous(labels = scales::percent_format(accuracy = 1),expand = expansion(add = c(0,0.05)))+ facet_wrap(~game, scale = "fixed",axes = "all_x",as.table = TRUE)+ labs(subtitle = "Estimations après simulation de Monte Carlo sur un paramètre interne")+ transition_states(frame2, wrap = FALSE)+ shadow_mark(past = TRUE)+ enter_fly(y_loc = 0) f
效果说明
最终实现预期效果:柱子逐个从底部生长,百分比文本标签随柱子同步出现,已显示的柱子持续保留在画面中。
内容的提问来源于stack exchange,提问作者M.O
相关产品推荐
相关产品推荐

