Search code examples
rgganimate

gganimate in R: animating point 1 to split into point2a and point2b


In a dataset, observation 1 has one value in stage 1 and 2 values in stage 2. For instance, observation 1 is the median US income across all workers in stage 1 and the median US income across (a) women and (b) men in stage 2.

I want to animate the data point splitting into two data points.

Here are some data.

library(tidyverse)
library(gganimate)

dat = tibble(
  id = 0,
  y = 0,
  a = 0,
  b = a - 2,
  c = a + 2
) |> 
  pivot_longer(-c(id,y)) |> 
  mutate(stage = ifelse(name == 'a', 'first', 'second'))

dat

# A tibble: 3 × 5
     id     y name  value stage 
  <dbl> <dbl> <chr> <dbl> <chr> 
1     0     0 a         0 first 
2     0     0 b        -2 second
3     0     0 c         2 second

All rows belong to observation 0. It has one value, 0, for the first stage, named "a". It has two values, -2 and +2, for the second stage, named "b" and "c", respectively.

The first plot looks like this.


p1 = dat[dat$stage == 'first',] |> 
  ggplot(aes(value,y)) +
  geom_point()

p1

The second plot looks like this.


p1 = dat[dat$stage == 'second',] |> 
  ggplot(aes(value,y)) +
  geom_point()

p2

I'd like to animate a transition using gganimate between p1 and p2, preserving the identity of the observation (this becomes relevant w/ multiple observations).


Solution

  • We could pad the data so that each stage gets the same number of observations per id as that id has in its most prevalent stage:

    library(tidyverse); library(gganimate)
    {dat |>
      mutate(obs_num = row_number(), .by = c(id, stage)) |>
      complete(stage, nesting(id, obs_num)) |>
      group_by(id) |> fill(y, value) |> ungroup() |>
      
      ggplot(aes(value, y)) +
      geom_point() +
      theme_void() +
      transition_states(stage, state_length = 0) +
      ease_aes("cubic-in-out") } |>
      animate(fps = 25, height = 10)
    

    enter image description here