Tdebeus
Tdebeus

Reputation: 1599

gganimate a stacked bar chart per bar color

I've seen the same question but without a working solution. And this one looks the same at first but doesn't really cover my question.

I would like to first plot and animate the bottom purple bars, then the light blue ones on top for the finishing stacked result and then loop. How can this be done with the gganimate package.

First my animated bar chart with the stacks per year at the same time.

enter image description here

Here's my the data:

example_df <- structure(list(jaar = c(2019, 2019, 2018, 2018, 2017, 2017, 2016, 
2016, 2015, 2015, 2014, 2014, 2013, 2013, 2012, 2012, 2011, 2011, 
2010, 2010), type = c("purple", "blue", "purple", "blue", "purple", 
"blue", "purple", "blue", "purple", "blue", "purple", "blue", 
"purple", "blue", "purple", "blue", "purple", "blue", "purple", 
"blue"), aantal = c(322L, 338L, 328L, 354L, 303L, 302L, 257L, 
245L, 223L, 185L, 183L, 128L, 141L, 80L, 121L, 58L, 104L, 46L, 
94L, 38L)), class = c("tbl_df", "tbl", "data.frame"), row.names = c(NA, 
-20L))

Here's my code:

library(tidyverse)
library(gganimate)

anim_bar <- example_df %>%
  ggplot(aes(jaar, aantal)) +
  geom_col(aes(fill = type)) +
  scale_fill_manual(values = c("#1beaae", "#6b38e8")) +
  theme(legend.position = "top") +
  transition_time(jaar) +
  shadow_mark() +
  enter_grow() +
  enter_fade()

animate(anim_bar, fps = 20)

Upvotes: 1

Views: 522

Answers (1)

Jon Spring
Jon Spring

Reputation: 66765

Here's an approach using some manipulation beforehand to specify the order of appearance and what each bar should look like when it appears. I had more luck by precalculating the stacking location and specifying the coordinates with geom_tile.

example_df %>%
  arrange(desc(type), jaar) %>%
  mutate(frame_num = row_number()) %>%
  group_by(jaar) %>%
  mutate(space_below = cumsum(lag(aantal, default = 0))) %>%
  ungroup() %>%

  ggplot() +
  geom_tile(aes(jaar, space_below + aantal/2, 
                width = 0.9, height = aantal,
                fill = type)) +
  scale_fill_manual(values = c("#1beaae", "#6b38e8")) +
  theme(legend.position = "top") +
  transition_time(frame_num) +
  shadow_mark() +
  enter_grow() +
  enter_fade() ->   anim_bar

animate(anim_bar, fps = 20)

enter image description here

Upvotes: 1

Related Questions