使用gganimate包做动态图 r 学习笔记

拟墨画扇 提交于 2020-08-19 17:32:57

今天学习一个主要用于绘制动画的ggplot2的扩展包—gganimate包

gganimate包简要介绍

几个主要函数

transition_()定义了数据应如何散布以及如何与时间相关。
shadow_() 定义应如何在给定的时间点显示其他时间点的数据。
view_() 定义位置比例应如何随着动画变化。
enter_()/exit_() 定义在动画过程中新数据应如何显示以及旧数据应如何消失。
ease_aes() 系列函数定义在过渡期间应如何缓和不同的美学。



gganimate的关键语法有三个:ggplot图形、transition_*()过渡函数、animate()生成动画。

先决条件:

gganimate 稳定版本在 CRAN 上可用,可与 一起安装。最新的开发版本可以安装如下:

install.packages('gganimate')devtools::install_github('thomasp85/gganimate')

加载所需的包,将默认 ggplot2 主题设置为 :theme_bw()

library(ggplot2)
library(gganimate)
library(gifski)
library(av)
theme_set(theme_bw())

演示数据集

library(gapminder)
head(gapminder)

  country     continent  year lifeExp      pop gdpPercap
  <fct>       <fct>     <int>   <dbl>    <int>     <dbl>
1 Afghanistan Asia       1952    28.8  8425333      779.
2 Afghanistan Asia       1957    30.3  9240934      821.
3 Afghanistan Asia       1962    32.0 10267083      853.
4 Afghanistan Asia       1967    34.0 11537966      836.
5 Afghanistan Asia       1972    36.1 13079460      740.
6 Afghanistan Asia       1977    38.4 14880372      786.

静态绘图

p <- ggplot(
  gapminder, 
  aes(x = gdpPercap, y=lifeExp, size = pop, colour = country)
  ) +
  geom_point(show.legend = FALSE, alpha = 0.7) +
  scale_color_viridis_d() +
  scale_size(range = c(2, 12)) +
  scale_x_log10() +
  labs(x = "GDP per capita", y = "Life expectancy")
p

在这里插入图片描述

核心函数1:transition_*() 按时间添加动态

transition_*()系列函数,这个系列的函数对于生成动图至关重要,确切地来说,动画的过渡效果都是由它(们)定义的。该系列共有九个函数:
tansition_states()的参数:

tansition_states() 这个函数应该是用得最多的。
参数:
states定义哪个图形随着哪个变量的变化而变化,该变量最好是有序的因子。
transition_length定义在该变量不同取值变化的过渡状态的时间。
state_length定义在该变量不同取值的停留时间。
wrap取值为逻辑值,指示在动画最后一个图形是否要过渡回最初的图形。
当你添加了transistion_states()图层后,就多了四个可以提供给标题的参数:





transitioning返回逻辑值,表明动画现在是否正在过渡。
previous_state表明动画过渡时显示刚才那个状态的名字,可以理解为过渡时当前显示的标签会有延迟。
next_state表明动画过渡时显示之后那个状态的名字,可以理解为过渡时当前显示的标签会有提前。
closest_state可以理解为上述两个参数的折中。


transition_filter()

transition_filter() 用来为动画添加筛选过程。
filter_length指定筛选过程的时间。可以理解为从上一个通过筛选的状态到下一个筛选状态的延迟。

不同筛选的状态需要给出不同的名字,名字后面接一个逻辑表达式,用于给这个筛选的状态提供筛选的条件。

状态的名字可以用"closest_filter"、"previous_filter"和"next_filter"提供给标题(closest、previous和next含义之前提到过)。

筛选状态的条件可以用"closest_expression"、"previous_expression"和"next_expression"提供给标题。

同样,这个函数也能将"transitioning"提供给标题,用于指示当前是否在过渡。

下面用官方文档的一个例子来加以说明:

anim3 <- ggplot(iris,aes(Petal.Width,
                       Petal.Length,colour = Species))+
    geom_point()+
    transition_filter(
      transition_length = 2,
      filter_length = 1,
      Setosa = Species =='setosa',
      Long = Petal.Length > 4,
      Wide = Petal.Width >2
    ) +
    ggtitle('Filter:{closest_filter}',
            subtitle = '{closest_expression}')

在上面这个例子中,给出了三个筛选的状态:
(在上面这个例子中,给出了三个筛选的状态:
Setosa,条件为Species ==‘setosa’
Long,条件为Petal.Length >4
Wide,条件为Petal.Widh >2)



transition_null

transition_null()这个函数最简单,顾名思义,就是不添加任何过渡效果,也就是不生成动画。

transition_reveal()的参数:

transition_reveal() 用于时间序列动图的绘制。参数:

along,指定动画变量

range,指定动画的时间范围,默认为along的范围

keep_last,逻辑值,是否保留之前的图形

可以提供给标题的参数:

frame_along

示例:

p <- ggplot(
  airquality,
  aes(Day, Temp, group = Month, color = factor(Month))
) +
  geom_line() +
  scale_color_viridis_d() +
  labs(x = "Day of Month", y = "Temperature") +
  theme(legend.position = "top")  #静态绘图
p + transition_reveal(Day)#按天显示(x 轴)
p + geom_point() +transition_reveal(Day)#显示点
p + geom_point(aes(group = seq_along(Day))) +transition_reveal(Day)#用一组点来显示数据

在这里插入图片描述
transtion_time()的参数

transtion_time() 同样也是用于时间序列动图。参数:

time,指定动画变量

range,指定动画的时间范围,默认为time的范围

可以提供给标题的参数:frame_time
示例: 状态之间的转换长度将设置为对应于它们之间的实际时差。transition_time()
标签变量, 给出当前帧对应的时间 :frame_time

p + transition_time(year) +
  labs(title = "Year: {frame_time}") #状态之间的转换长度将设置为对应于它们之间的实际时差

在这里插入图片描述
按大陆板块分(这个是ggplot2的语法)

p + facet_wrap(~continent) +
  transition_time(year) +
  labs(title = "Year: {frame_time}") #按大陆创建分面

在这里插入图片描述

核心函数2:view_*()让视图跟随每个帧中的数据变换

view_follow()参数
fixed_x,fixed_y,可以是逻辑值(固定或不固定x轴或y轴)也可以是数值向量(提供固定的显示范围,可以使用)
aspect_ratio,固定x、y坐标轴度量的比例,默认为1,不能与fixed_x和fixed_y同时使用,否则将会使它们的设置失效

view_static()
这个最简单,顾名思义,就是保持视图静止不动。

view_step()
这个函数可以随着数据的变化而实时调节视图,即视情况保持视图静止或者伸缩变换,配合transition_states()使用是个很好的选择,这个函数有两个版本:标准版:view_step()和手动版:view_step_manual()。
共有的参数:
pause_length,视图静止时长
step_length,视图变化时长
delay,延迟,默认为0
ease,在视图变化时的缓和函数,默认为"cubic-in-out"
wrap,在动画最后是否要返回第一帧,默认为TRUE
pause_first,在第一帧是否暂停,默认为TRUE
fixed_x、fixed_y、exclude_layer、aspect_ratio
view_step特有的参数:
nsteps,视图变化的次数,若设为NULL则默认为pause_lenth、step_length的最大值
look_ahead,提前进行视图变化的时长,默认为pause_length
include,视图变化是否要包括开始帧和结束帧,默认为TRUE
view_manual_step()特有的参数
xmin,xmax,ymin,ymax,手动设置视图的范围














示例:

p + transition_time(year) +
  labs(title = "Year: {frame_time}") +
  view_follow(fixed_y = TRUE) #让视图跟随每个帧中的数据

在这里插入图片描述

核心函数3:shadow():在给定的时间点显示其他时间点的数据(加小尾巴)

shadow_wake():
指定绘制当前图形的“苏醒”时间,可以理解为在图形变化的过程中生成幻影。参数:
参数:
wake_length:指定幻影的持续时间,取值在0到1之间,若取值为0.5,可以理解为每个时间点都有一半的图形是幻影。
size、alpha为逻辑值或者0到1之间的数值,表示以怎样的取值来结束幻影(默认为FALSE,或者说是0,例如对于size,表示以0的大小结束幻影)。colour、fill指定幻影结束时应该以怎样的映射结束。
wrap逻辑值,指示动图结尾到重新开始时是否也要添加这个幻影的过程。
exclude_phase,指明不为哪些“相”提供幻影,常用取值有’enter’(进入时)、‘exit’(退出时)、‘static’(静止时)、‘transition’(过渡时)、‘raw’(自然状态时,这个不知道怎么翻译……),默认为c(‘enter’,‘exit’)。





shadow_null()
这个最简单,顾名思义,就是不留下任何影子。

shadow_trail()
设置影子的轨迹。
参数:
distance,设其取值为x(0<x<1),设动图总时长为1,则在动图开始后,每隔x的时长留下当前图形的影子。
max_frames设置最多留下多少个这样的影子。 其他参数:exclude_layer(),alpha,colour。



shadow_mark()
用于生成影子。
参数:
past和future可设为逻辑值。若设past=TRUE,则留下已生成的图形的影子,future则提前生成将要生成的图形的影子
exclude_layer(),表示对这些影子要删除掉哪些ggplot2的图层,以ggplot2图层序号的向量的形式取值,在本例中,若取值为c(1,2),则柱形图geom_bar(第一个图层)和数据标签geom_text(第二个图层)都不会在影子中出现。
其他参数:alpha,colour,设置影子的透明度和颜色,如若设置alpha=alpha/2,则影子透明度为当前图形的1/2。




示例:显示具有逐渐减退的帧

p + transition_time(year) +
  labs(title = "Year: {frame_time}") +
  shadow_wake(wake_length = 0.1, alpha = FALSE)

在这里插入图片描述
示例:将原始数据显示为背景标记。此阴影允许您显示当前帧后面的原始数据。过去和/或未来的原始数据都可以显示和设置样式。

p + transition_time(year) +
  labs(title = "Year: {frame_time}") +
  shadow_mark(alpha = 0.3, size = 0.5)

在这里插入图片描述
参考:https://gganimate.com/reference/index.html
https://www.datanovia.com/en/blog/gganimate-how-to-create-plots-with-beautiful-animation-in-r/#comments

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!