Любой способ сделать паузу в определенных кадрах/точках времени с transition_reveal в gganimate? - программирование

Любой способ сделать паузу в определенных кадрах/точках времени с transition_reveal в gganimate?

Используя этот пример из пакета вики на 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))

Производит что-то вроде:

enter image description here

Я хотел знать, есть ли способ определить паузу в анимации в определенных точках. Например, в День 10, затем в 20, затем, когда анимация закончится, перед повторным циклом. geom_reveal нет state_length аргументов state_length или transition_length поэтому я не уверен, возможно ли это.

Редактировать: автор пакета упоминает, что это возможно в твиттере, но я не знаю, на какой аргумент "раскрыть время" он ссылается.

4b9b3361

Ответ 1

От ОП:

Редактировать: автор пакета упоминает, что это возможно [сделать это], но я не знать, на какой аргумент он указывает время.

В Твиттере Томас Лин Педерсен говорил о том, как линия transition_reveal управляет кадрами анимации. Таким образом, мы можем передать ему одну переменную, которая будет "сердцебиением" анимации, оставляя исходные переменные для графиков.

Мой первый подход состоял в том, чтобы создать новую переменную, reveal_time, которая была бы сердцебиением. Я бы увеличил его больше в точках паузы, чтобы анимация затрачивала больше времени на эти точки данных. Здесь я сделал это, добавив 10 в дни паузы и только 1 в другие дни.

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()

Затем я добавил это в анимацию, изменив фрейм исходных данных и строку transition_reveal.

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)

enter image description here

Но когда я это сделал, я понял, что это не пауза, а просто замедление анимации. Эффект "времени пули" - круто, но не совсем то, что я искал.

Таким образом, мой второй подход состоял в том, чтобы фактически скопировать приостановленные линии анимации. При этом не было бы твининга и были бы реальные паузы:

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()

enter image description here