Search code examples
rgganimate

Using alternative variables in title expression in gganimate's transition_reveal?


I'm interested in using alternative variables beyond the time tweening variable for title label information for each frame.

The package Maintainer mentions it usually isn't possible, but offered a small work-around example here. However in his example, it only works if the time variable used conveniently matches up as the index for each element in the data frame.

For most other applications, this isn't realistic. e.g.

library(gganimate)
library(tidyverse)

stock <- bind_cols(date = round(as.numeric(time(EuStockMarkets)), 3),
                   EuStockMarkets) ## built-in dataset

stock %>% ggplot(aes(date, FTSE)) +
  geom_line() +
  transition_reveal(date) +
  labs(title = "{stock$FTSE[frame_along]}")

enter image description here

You can see only NAs are shown as my time variable can't be coerced into integers. Even if I were to coerce it, it wouldn't show anything as the first element 1991.496 in my time vector is greater than the total of rows in my data frame (1860).

So I thought about doing something like this as a filter:

stock %>% ggplot(aes(date, FTSE)) +
  geom_line() +
  transition_reveal(date) +
  labs(title = "{stock$FTSE[which(stock$date == frame_along)]}")

What I get is a bunch of flashing frames, but from the frames which are visible I can see the filter does work for getting the correct variable to display in the title. I'm not sure what the issue is here, but I'm keen to get this working.

enter image description here

Edit:

After playing around some more I thought my issue was that I was using which to match on a double type vector:

stock <- bind_cols(date = as.integer(time(EuStockMarkets)),
                   EuStockMarkets)
stock <- stock %>% group_by(date) %>% summarise(ftse_sum = sum(FTSE))

stock %>% ggplot(aes(date, ftse_sum)) +
  geom_line() +
  transition_reveal(date) +
  labs(title = "{stock$ftse_sum[which(stock$date == frame_along)]}")

enter image description here

Works but this summarised dataset isn't what I'm interested in.

I thought about transforming my time varible to integer (say by multiplying by 1000), and then just converting it back to its proper scale in scale_x_continuous.

stock <- bind_cols(date = as.integer(round(as.numeric(time(EuStockMarkets)), 3)*1000),
                   EuStockMarkets)

stock %>% ggplot(aes(date, FTSE)) +
  geom_line() +
  scale_x_continuous(labels = function(x) x/1000) +
  transition_reveal(date) +
  labs(title = "{stock$FTSE[which(stock$date == as.integer(frame_along))]}")

enter image description here

Goes back to a flashing animation again despite my now filtering specifically on an integer vector and integer values from frame_along.

Marco's suggestion:

enter image description here


Solution

  • Maybe this is what you are looking for.

    stock %>% ggplot(aes(date, FTSE)) +
      geom_line() +
      transition_reveal(date) +
      labs(title = "{stock$FTSE[which.min(abs(stock$date-frame_along))]}")
    

    enter image description here