thomasp85 / gganimate

A Grammar of Animated Graphics
https://gganimate.com
Other
1.95k stars 310 forks source link

Inconsistent types for frame variables #339

Closed khailper closed 3 years ago

khailper commented 5 years ago
library(tidyverse)
library(gganimate)

diamonds %>% 
  filter(table <= 55) %>% 
  group_by(color, table) %>% 
  summarise(ave_price = mean(price), max_price = max(price)) %>% 
  ggplot(aes(color, ave_price)) + 
  geom_col() +
  transition_states(table, transition_length = 3, state_length = 1) +
  ggtitle("{next_state} is a number: {is.numeric(next_state)}",
          subtitle = "{next_state} is a character: {is.character(next_state)}")


is.numeric(diamonds$table)
#> [1] TRUE
# from transition_time() documentation (plus title)
ggplot(airquality, aes(Day, Temp)) +
  geom_point(aes(colour = factor(Month))) +
  transition_time(Day) + 
  ggtitle("{frame_time} is a number: {is.numeric(frame_time)}",
          subtitle = "{frame_time} is a character: {is.character(frame_time)}")


is.numeric(airquality$Day)
#> [1] TRUE

Created on 2019-07-17 by the reprex package (v0.3.0)

In my personal experience, transitition_reveal() also preserves frame_along's type, which makes it simpler to do things like title = "helper_function(frame_var)", where helper_function extracts summary statistics of a column other than the one you're transitioning over.

For example:

helper_function <- function(frame_var){
airquality %>%
filter(Day <= frame_time) %>% 
slice(n()) %>% pull(Ozone) %>% 
median()
}

to get the median ozone value on the day immediately before the interpolated value in frame_time.

I haven't checked any other transitions to see how they handle frame variable type

thomasp85 commented 3 years ago

The thinking is that transition_states() is discrete, so while you can use numerics they are treated as character/factor

Both transition_time() and transition_reveal() are continuous so they use numerics

khailper commented 3 years ago

Thanks, that makes a lot of sense.