Any way to pause at specific frames/time points with transition_reveal in gganimate?

一世执手 提交于 2019-12-04 08:16:07

问题


Utilising this example from the package's wiki on Github:

airq <- airquality
airq$Month <- format(ISOdate(2004,1:12,1),"%B")[airq$Month]

ggplot(airq, aes(Day, Temp, group = Month)) + 
  geom_line() + 
  geom_segment(aes(xend = 31, yend = Temp), linetype = 2, colour = 'grey') + 
  geom_point(size = 2) + 
  geom_text(aes(x = 31.1, label = Month), hjust = 0) + 
  transition_reveal(Month, Day) + 
  coord_cartesian(clip = 'off') + 
  labs(title = 'Temperature in New York', y = 'Temperature (°F)') + 
  theme_minimal() + 
  theme(plot.margin = margin(5.5, 40, 5.5, 5.5))

Produces something like:

I wanted to know if there is any way to define pausing in the animation at specific points. For e.g. at Day 10, then 20, then when the animation is finished, before looping again. geom_reveal has no state_length or transition_length arguments available so I'm not sure if this is possible.

Edit: the package author mentions it's possible on twitter but I don't know what 'reveal timing' argument he is referring to.


回答1:


From OP:

Edit: the package author mentions it's possible [to do this] but I don't know what 'reveal timing' argument he is referring to.

On Twitter, Thomas Lin Pedersen was referring to how the transition_reveal line is driving the frames of the animation. So we can feed it one variable to be the "heartbeat" of the animation, while leaving the original variables for the plots.

My first approach was to make a new variable, reveal_time, which would be the heartbeat. I would increment it more at pause points, so that the animation would spend more time on those data points. Here I did that by adding 10 at the pause point days, and only 1 on other days.

library(dplyr)
airq_slowdown <- airq %>%
  group_by(Month) %>%
  mutate(show_time = case_when(Day %in% c(10,20,31) ~ 10,
                                     TRUE           ~ 1),
         reveal_time = cumsum(show_time)) %>%
  ungroup()

Then I fed that into the animation, changing the source data frame and the transition_reveal line.

library(gganimate)
a <- ggplot(airq_slowdown, aes(Day, Temp, group = Month)) + 
  geom_line() + 
  geom_segment(aes(xend = 31, yend = Temp), linetype = 2, colour = 'grey') + 
  geom_point(size = 2) + 
  geom_text(aes(x = 31.1, label = Month), hjust = 0) + 
  transition_reveal(reveal_time) +  # Edit, previously had (Month, reveal_time)
  coord_cartesian(clip = 'off') + 
  labs(title = 'Temperature in New York', y = 'Temperature (°F)') + 
  theme_minimal() + 
  theme(plot.margin = margin(5.5, 40, 5.5, 5.5))    
animate(a, nframe = 50)

But when I did that, I realized that it wasn't pausing -- it was just slowing down the tweening. Sort of a "bullet time" effect -- cool but not quite what I was looking for.

So my second approach was to actually copy the paused lines of the animation. By doing so, there would be no tweening and there would be real pauses:

airq_pause <- airq %>%
  mutate(show_time = case_when(Day %in% c(10,20,31) ~ 10,
                               TRUE           ~ 1)) %>%
  # uncount is a tidyr function which copies each line 'n' times
  uncount(show_time) %>%
  group_by(Month) %>%
  mutate(reveal_time = row_number()) %>%
  ungroup()



来源:https://stackoverflow.com/questions/53092216/any-way-to-pause-at-specific-frames-time-points-with-transition-reveal-in-gganim

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!