在gganimate中有许多(> 50)个状态的问题

and*_*eas 6 r ggplot2 gganimate

我正在尝试使用gganimate覆盖90年的数据集来创建GIF ,即我希望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)
Run Code Online (Sandbox Code Playgroud)

这一切都运作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) 
Run Code Online (Sandbox Code Playgroud)

例1

然而,当我包括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) 
Run Code Online (Sandbox Code Playgroud)

例题

我怎样才能创造90年的GIF?欢迎任何想法!
我还是新来的gganimate,我使用transition_states不正确吗?

Sti*_*ibu 9

这与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)
Run Code Online (Sandbox Code Playgroud)

然后,您可以通过键入以下任意一个来开始动画

p
animate(p)
animate(p, nframes = 100)
Run Code Online (Sandbox Code Playgroud)

这三行是等效的。第一个是您在示例中所做的:这将隐式调用animate()以渲染动画。第二行进行animate()显式调用,第三行也将调用数显式设置为100。由于nframes = 100是默认值,因此最后一行也与其他行相同。

为了使动画有效,您需要设置更多的帧数。100帧可以使用50年,因此在整个数据帧中,182帧应该可以在91年内使用。同样,以下两行相同:

animate(p, nframes = 182)
animate(p, nframes = 2 * length(unique(df$year)))
Run Code Online (Sandbox Code Playgroud)

现在它可以工作了:

在此处输入图片说明

我不确定为什么您需要的帧数是几年的两倍,但是在阅读了以下文档中的以下说明后 transition_states()

然后,它会在定义的状态之间补间,并在每个状态下暂停。

我猜想,一帧用于两年之间的过渡,一帧用于表示给定年份的日期。

这意味着您实际上需要的帧数少于年份的两倍,因为上一年之后的过渡不需要帧。实际上,gganimate()for nframes = 100和的输出nframes = 182分别是:

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

Frame 181 (100%)
Finalizing encoding... done!
Run Code Online (Sandbox Code Playgroud)

因此,如果我的猜测正确的话,它确实可以准确地创建预期的帧数。