Search code examples
rgganimate

Is there a transition function to keep old bars and add on new ones? Transition_reveal just moves the singular bar


Trying to make it so that I can add the bars on one by one for a bar chart in R. I know that there is a function called transition_layers, but haven't been able to make it work for the life of me. In the reproducible example below I have the bar moving over the years, but what I want is a new bar added one by one over the years and for each older bar to stay.

Libraries:

library(magrittr)
library(broom)
library(purrr)
library(gganimate)
library(gifski)
library(ggthemes)
library(png)
library(jpeg)
library(ggimage)
library(grid)

Cost <- c(1, 2, 4)
Year <- c(2016, 2017, 2018)


example <- data.frame(Year, Cost)
example_bar <-ggplot(data = example, mapping = aes(Year))+
  geom_bar(aes(weight = Cost))+
  theme_stata()+
  transition_reveal(Year)

Solution

  • You need to explicitly tell gganimate that each column in the x-axis is in a different group by setting group=Year inside geom_col (I changed geom_bar to geom_col because I think it is more intuitive, but it is basically the same thing). Otherwise, gganimate will treat all of them as the same group and the column will slide through the x-axis. This has happened to me before with other types of animations. Explicitly setting the group parameter is generally a good idea.

    ggplot(data = example)+
      geom_col(aes(x=Year, y = Cost, group=Year)) +
      transition_reveal(Year)
    anim_save(filename = 'gif1.gif', anim1, nframes=30, fps=10, end_pause=5)
    

    enter image description here

    However, I could not set transition times and configure how new columns appear using transition_reveal. The animation looks strange and each column stays there a long time before the other one. I could make it a little better using animate/anim_save...

    So another solution is to change the data frame by keeping "past" rows, create a new column with current year, and work with transition_states

    library(dplyr)
    
    df.2 <- plyr::ldply(.data= example$Year, 
                        .fun = {function(x){
                          example %>% dplyr::filter(Year <= x) %>%
                            dplyr::mutate(frame=x)}})
    
    # add row with data for dummy empty frame
    df.2 <- rbind(data.frame(Year=2016, Cost=0, frame=2015), df.2)
    
    anim2 <- ggplot(data = df.2) +
      geom_col(aes(x=Year, y = Cost, group=Year)) + 
      transition_states(frame, transition_length = 2, state_length = 1, wrap=FALSE) +
      enter_fade() + enter_grow()
    
    anim_save(filename = 'gif2.gif', anim2)
    

    enter image description here