使用ggplot2绘图时如何给图层添加动态效果

6

我开始熟悉gganimate了,但我想进一步扩展我的gif。

例如,我可以在gganimate中对一个变量添加frame,但是如果我想动画显示添加完全新的图层/几何对象/变量的过程呢?

这是一个标准的gganimate示例:

library(tidyverse)
library(gganimate)

p <- ggplot(mtcars, aes(x = hp, y = mpg, frame = cyl)) +
    geom_point()

gg_animate(p)

但如果我想让gif动起来怎么办:

# frame 1
ggplot(mtcars, aes(x = hp, y = mpg)) +
    geom_point()

# frame 2
ggplot(mtcars, aes(x = hp, y = mpg)) +
    geom_point(aes(color = factor(cyl)))

# frame 3
ggplot(mtcars, aes(x = hp, y = mpg)) +
    geom_point(aes(color = factor(cyl), size = wt))

# frame 4
ggplot(mtcars, aes(x = hp, y = mpg)) +
    geom_point(aes(color = factor(cyl), size = wt)) +
    labs(title = "MTCARS")

这该如何实现呢?
3个回答

8
您可以手动为每个图层添加frame美学,但它会立即包括所有帧的图例(我相信这是有意为之,以保持比例/边距等正确)。
saveAnimate <-
  ggplot(mtcars, aes(x = hp, y = mpg)) +
  # frame 1
  geom_point(aes(frame = 1)) +
  # frame 2
  geom_point(aes(color = factor(cyl)
                 , frame = 2)
             ) +
  # frame 3
  geom_point(aes(color = factor(cyl), size = wt
                 , frame = 3)) +
  # frame 4
  geom_point(aes(color = factor(cyl), size = wt
                 , frame = 4)) +
  # I don't think I can add this one
  labs(title = "MTCARS")

gg_animate(saveAnimate)

在这里输入图片描述

如果您想自己添加东西,甚至想看到图例、标题等如何移动物体,那么您可能需要退回到更低级别的软件包,并自己构建图像。在这里,我使用的是animation软件包,它允许您循环显示一系列绘图,没有限制(它们不必有任何关联,因此可以显示将物体移动到绘图区域的内容)。请注意,我认为这需要在您的计算机上安装ImageMagick。

p <- ggplot(mtcars, aes(x = hp, y = mpg))

toSave <- list(
  p + geom_point()
  , p + geom_point(aes(color = factor(cyl)))
  , p + geom_point(aes(color = factor(cyl), size = wt))
  , p + geom_point(aes(color = factor(cyl), size = wt)) +
    labs(title = "MTCARS")
)

library(animation)

saveGIF(
  {lapply(toSave, print)}
  , "animationTest.gif"
 )

enter image description here


相当不错。我以前从未在SO上看到过动画显示。我认为SO只显示png文件。现在我们只需要稍微减慢一下速度,但这可能是另一个问题。 - IRTFM
saveGIF 的帮助指向 ani.options,其中包括 interval,它设置每个帧停留的时间(以秒为单位)。因此,只需添加 interval = 3 就可以让每个帧持续 3 秒。 - Mark Peterson
一度看起来你可能已经添加了代码以固定图例的格式,但随着页面刷新,这种印象消失了。哦,没关系...上面的有这个功能,下面的没有。 - IRTFM

2
早期的答案中的gganimate命令已于2021年被弃用,无法完成OP的任务。
在Mark的代码基础上,您现在可以简单地创建一个静态的ggplot对象,并添加gganimate::transition_layers函数来创建一个动画,该动画在静态图层之间进行转换。像enter_fade()enter_grow()这样的缓动函数控制元素如何进入和退出帧。
library(tidyverse)
library(gganimate)

anim <- ggplot(mtcars, aes(x = hp, y = mpg)) +
  # Title
  labs(title = "MTCARS") +
  # Frame 1
  geom_point() +
  # Frame 2  
  geom_point(aes(color = factor(cyl))) +
  # Frame 3
  geom_point(aes(color = factor(cyl), size = wt)) +
  # gganimate functions
  transition_layers() + enter_fade() + enter_grow()

# Render animation
animate(anim)


欢迎来到SO。非常好的贡献。+1。最后一个框架是无意义的(尽管有很多点被绘制出来)。原帖作者本意是在这里添加一个标题。我试过了,可能不是那么简单。 - tjebo
感谢指出意外重复的 geom_point()。根据 OP 的要求,编辑了帖子以删除它并添加标题。在 ggplot() 调用和 gganimate 函数之间的任何位置添加 labs(title = "") 调用似乎可以解决问题。 - martinlu

0

animation包不强制您在数据中指定帧。请参见此页面底部的示例here,其中动画包装在大型saveGIF()函数中。您可以指定单个帧的持续时间和其他所有内容。

这样做的缺点是,与很好的gganimate函数不同,基本的逐帧动画无法保持图形尺寸/图例恒定。但是,如果您可以通过黑客方式显示每个帧所需的内容,则基本动画包将为您提供服务。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接