Проблема со многими (> 50) состояниями в gganimate - PullRequest
0 голосов
/ 14 сентября 2018

Я пытаюсь создать GIF с использованием gganimate для набора данных, охватывающего 90 лет, т.е. я хочу, чтобы GIF работал через 90 штатов / лет. Однако, похоже, что gganimate может работать только с менее чем 50 штатами.

Итак, вот пример:

library(tidyverse)
# devtools::install_github('thomasp85/gganimate')
library(gganimate)

df = expand.grid(  x = 1,
                   y = c(2,3),
                year = 1670:1760) %>% mutate( z = 0.03* year,
                                              u = .2 * year)

все это прекрасно работает в течение 49 лет:

ggplot(data=df %>% filter(., year %in% 1670:1719) , aes()) + 
  geom_point( aes(x = x, y = y, fill = z, size = u), shape = 21 ) + 
  labs( title = 'Year: {closest_state}') +
  enter_appear() +
  transition_states(year, transition_length = 1, state_length = 2) 

example1

Тем не менее, становится странным, когда я включаю 50 (или более) лет:

ggplot(data=df %>% filter(., year %in% 1670:1720) , aes()) + 
  geom_point( aes(x = x, y = y, fill = z, size = u), shape = 21 ) + 
  labs( title = 'Year: {closest_state}') +
  enter_appear() +
  transition_states(year, transition_length = 1, state_length = 2) 

example2

Как я могу создать GIF на все 90 лет? Любые идеи приветствуются!
Я все еще новичок в gganimate, я неправильно использую transition_states?

1 Ответ

0 голосов
/ 16 сентября 2018

Это связано с тем, что gganmiate использует фиксированное число 100 кадров для анимации. На срок до 50 лет (обратите внимание, что 1670:1719 имеет длину 50, а не 49), это нормально, но если вы хотите построить больше лет, вам нужно больше кадров. Вы можете контролировать количество кадров, явно вызвав animate().

Для вашего примера это означает, что вы должны сначала сохранить свой график в переменной:

p <- ggplot(df) + 
      geom_point(aes(x = x, y = y, fill = z, size = u), shape = 21) + 
      labs( title = 'Year: {closest_state}') +
      enter_appear() +
      transition_states(year, transition_length = 1, state_length = 2)

Затем вы можете запустить анимацию, набрав любой из следующих символов

p
animate(p)
animate(p, nframes = 100)

Эти три строки эквивалентны. Первый - то, что вы сделали в своем примере: это будет неявно вызывать animate() для рендеринга анимации. Вторая строка делает вызов animate() явным, а третья также явно устанавливает количество кадров равным 100. Поскольку nframes = 100 является значением по умолчанию, эта последняя строка также делает то же самое, что и остальные.

Чтобы анимация работала, вам нужно установить большее количество кадров. 100 кадров работали в течение 50 лет, поэтому 182 кадра должны работать в течение 91 года в вашем полном кадре данных. Опять же, следующие две строки одинаковы:

animate(p, nframes = 182)
animate(p, nframes = 2 * length(unique(df$year)))

А теперь работает:

enter image description here

Я не знаю наверняка, почему вам нужно вдвое больше кадров, чем у вас лет, но после прочтения следующего утверждения из документации по transition_states()

Затем выполняется анимация между определенными состояниями и паузами в каждом состоянии.

Я бы предположил, что один кадр используется для перехода между двумя годами, а один кадр используется для представления даты для данного года.

Это будет означать, что вам на самом деле нужен один кадр, который вдвое меньше количества лет, потому что для перехода после прошлого года не требуется никаких кадров. Действительно, вывод из gganimate() для nframes = 100 и nframes = 182 соответственно составляет:

Frame 99 (100%)
Finalizing encoding... done!

Frame 181 (100%)
Finalizing encoding... done!

Таким образом, это действительно создает именно то количество кадров, которое следует ожидать, если мое предположение было правильным.

...