gganimate не показывает все кадры - PullRequest
2 голосов
/ 04 июня 2019

Я бы хотел сделать простой gif с 138 состояниями .Мне не нужны какие-то необычные переходы между каждым состоянием, но мне нужно, чтобы каждое состояние отображалось в моем gif-файле.В настоящее время gganimate обрезает мой gif, не раскрывая последние ~ 30 состояний.

Пример

df <- lapply(1:138, function(t){
  data.frame(
    DT = as.POSIXct("2019-01-01 12:00:00", tz = "UTC") + t*24*60*60,
    x = seq(-3, 3, length.out = 100),
    y = t * seq(-3, 3, length.out = 100)
  )
})
df <- do.call(rbind, df)
range(df$DT)  # "2019-01-02 12:00:00 UTC" "2019-05-19 12:00:00 UTC"

p <- ggplot(data = df, mapping = aes(x = x, y = y)) + 
  geom_point()+ 
  transition_states(states = DT, transition_length = 0, state_length = 1)+
  labs(title = 'ScrapeDT: {previous_state}')
p

enter image description here

Как видите, gif воспроизводится примерно до 2019-04-10 вместо 2019-05-19.Я также пытался возиться с animate(), но безуспешно.Например,

animate(
  plot = p, 
  nframes = length(unique(df$DT)), 
  fps = 8, 
  end_pause = 8
)

enter image description here

Как сделать так, чтобы каждые желаемое состояние отображалось, скажем, 0,25секунд?

Ответы [ 2 ]

2 голосов
/ 04 июня 2019

Как указано в документах , transition_manual() - это именно то, что вам нужно:

Этот переход позволяет сопоставить переменную в ваших данных с конкретным кадром в анимации. Анимация данных не будет выполняться, и количество кадров в анимации будет определяться количеством уровней в переменной frame.

Обратите внимание, что я сделал ниже с transition_manual() и labs().

library(tidyverse)
library(gganimate)

df <- lapply(1:138, function(t){
  data.frame(
    DT = as.POSIXct("2019-01-01 12:00:00", tz = "UTC") + t * 24 * 60 * 60,
    x = seq(-3, 3, length.out = 100),
    y = t * seq(-3, 3, length.out = 100)
  )
})
df <- do.call(rbind, df)

p <- ggplot(data = df, mapping = aes(x = x, y = y)) + 
  geom_point()+ 
  transition_manual(frames = DT)+
  labs(title = 'ScrapeDT: {current_frame}')

animate(
  plot = p, 
  nframes = length(unique(df$DT)), 
  fps = 4, 
  end_pause = 8
)

working-animated-gif

1 голос
/ 04 июня 2019

Похоже, вас укусила выборка кадра. От ?animate:

Длина и частота кадров определяются временем рендеринга и могут быть любыми двумя комбинациями nframes, fps и длительности.

Рендеринг происходит в дискретных единицах времени. Это значит что любой событие в анимации округляется до ближайшего кадра (например, вход всегда будет занимать целое количество кадров). Это означает, что Артефакты округления возможны при рендеринге только нескольких кадров.

Чтобы избежать этого, вы можете увеличить аргумент детализации. деталь достанется умножается на nframes и полученное количество кадров получит вычисляется, но отображаются только nframes равномерно расположенные кадры.

Простое решение, гарантирующее печать каждого состояния, - установить detail> 1. Обычно detail = fps гарантирует использование каждого кадра.

animate(
  plot = p, 
  nframes = length(unique(df$DT)), 
  detail = 8,
  fps = 8, 
  end_pause = 8
)

with all frames

...