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

如何用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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 15:00:05