Search code examples
ranimationggplot2geom-bargganimate

How can I animate geom_bar to "add data" using a filter function?


Ok, we all know this is not my real data or question, but, for the sake of a reproducible example...

Let's say that I'm trying to get enough flowers for my daughter's wedding.

My friend Anna has 25 plants of each species in the iris dataset at her house. I want to impress the maid of honor by showing her I found an EXTRA 25 plants of each species at my friend Jay's. In the graph, I'm also going to show the condition of the plants, because maybe we don't want to use crappy flower's at my daughter's wedding.

  • First, I want to show her the graph of JUST Anna's flowers.
  • Then, I'm going to wow her by smoothly "growing" the bar chart upwards to show her that we actually have 50 of each species.

I'm stumped on how to achieve this simple animation using gganimate!

Here's the code to create the "starting point" (left-most graph) and the "end point" (right hand graph). How can I animate between the two?

library(tidyverse)
library(gganimate)

House <- rep(c(rep(c("Anna's", "Jay's"), each = 25)))
Houses <- c(House, House, House)

Plant_Condition <- rnorm(150, mean = 20, sd = 10)
Plant_Condition <- ifelse(Plant_Condition > 25, "good", "poor")

iris_mod <- iris %>% 
  mutate(House = Houses,
         Condition = Plant_Condition)

p <- ggplot(iris_mod %>% filter(House == "Anna's"), aes(Species, fill = Condition)) +
  geom_bar() +
  coord_cartesian(ylim = c(0, 50))

p2 <- ggplot(iris_mod, aes(Species, fill = Condition)) +
  geom_bar()  +
  coord_cartesian(ylim = c(0, 50))

Iris plots


Solution

  • I find the easiest way to do this kind of thing with gganimate is to imagine you are creating a plot with facets. If you can achieve the two frames you want as facets, you can instead transition between them. So here we can do:

    iris_mod <- rbind(iris_mod %>% filter(House == "Anna's"), 
                      within(iris_mod, House <- "Everything"))
    
    ggplot(iris_mod, aes(Species, fill = Condition)) +
      geom_bar() +
      coord_cartesian(ylim = c(0, 50)) +
      transition_states(House,
                        transition_length = 2,
                        state_length = 2)
    

    enter image description here