gganimate:让数据动起来

简介

一年多以前我就写了篇R语言动画的博客: R语言可视化学习笔记之gganimate包。当时使用的是由 David Robinson开发的gganimate。后面由 Thomas Lin Pedersen接手,推倒重来,拓展了很多动画语法。具体的可参考 Thomas Lin Pedersengganimate的Github主页

gganimate语法

gganimateggplot2的基础上进行了动画的拓展,所以可以完美兼容ggplot2语法。主要有以下几类动画实现:

  • transition_*():定义数据如何伸展变化以及随时间关联
  • view_*():定义位置比例如何随动画变化
  • shadow_*():定义如何在给定时间点的基础上呈现来自其它时间点的数据
  • enter_*()/ exit_*():定义新数据如何显示,旧数据如何消失
  • ease_aes():定义了动画期间不同的美学映射如何过渡切换等

Examples

安装该包的话可以直接从CRAN安装或者从Github上安装

if (!require(gganimate)) {
  install.packages("gganimate")
}
# or install.packages('devtools')
# devtools :: install_github( ' thomasp85 / gganimate ')

下面我们通过例子来理解各个语法

先来看一下作者提供的一个小例子:

Example 1

if (!require(gapminder)) {
  install.packages("gapminder")
}
require(gapminder)
require(gganimate)
require(tidyverse)

ggplot(mtcars, aes(factor(cyl), mpg)) +
  geom_boxplot() +
  # 接下来就是gganimate实现动画的语法
  transition_states(
    gear,
    transition_length = 2,
    state_length = 1
  ) +
  enter_fade() +
  exit_shrink() +
  ease_aes("sine-in-out")

这里gear是分类数据类型,所以使用transition_states,并提供了用于转换和状态的相对时间长度,这里我的理解是transition也就是变化的相对时间长短以及transition后保持这个状态(view)的相对时间长短。enter_fade()的作用是出现的时候有个过程,慢慢浮现,不是突然之间出现。exit_shrink()我理解是消失的时候是慢慢萎缩消失的,不是突然之间就没了,中间有个过程。ease_aes("sine-in-out")的作用是使动画之间的切换按照正弦曲线的方式变化,这里x轴是没变化的,只有y轴变化。

Example 2

head(gapminder)
# A tibble: 6 x 6
  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.
ggplot(gapminder, aes(gdpPercap, lifeExp, size = pop, color = country)) +
  geom_point(alpha = 0.7, show.legend = FALSE) +
  scale_color_manual(values = country_colors) +
  scale_x_log10() +
  scale_size(range = c(2, 12)) +
  facet_wrap(~continent) +
  # 接下来就是gganimate实现动画的语法
  labs(title = "Year:{frame_time}", x = "GDP per capita", y = "life expectancy") +
  transition_time(year) +
  ease_aes("linear")

这里是按照时间(Year)变化的,具有连续性,所以无需指定transition 和 state length,比如1980~1990十年的变化时间自然就是2000~2005五年的2倍。

Example 3

最后提供一个用R语言放烟花的 例子,真正的烟花。。。。

# Firework colours
colours <- c(
  "lawngreen",
  "gold",
  "white",
  "orchid",
  "royalblue",
  "yellow",
  "orange"
)
# Produce data for a single blast
blast <- function(n, radius, x0, y0, time) {
  u <- runif(n, -1, 1)
  rho <- runif(n, 0, 2 * pi)
  x <- radius * sqrt(1 - u^2) * cos(rho) + x0
  y <- radius * sqrt(1 - u^2) * sin(rho) + y0
  id <- sample(.Machine$integer.max, n + 1)
  data.frame(
    x = c(x0, rep(x0, n), x0, x),
    y = c(0, rep(y0, n), y0, y),
    id = rep(id, 2),
    time = c((time - y0) * runif(1), rep(time, n), time, time + radius + rnorm(n)),
    colour = c("white", rep(sample(colours, 1), n), "white", rep(sample(colours, 1), n)),
    stringsAsFactors = FALSE
  )
}
# Make 20 blasts
n <- round(rnorm(20, 30, 4))
radius <- round(n + sqrt(n))
x0 <- runif(20, -30, 30)
y0 <- runif(20, 40, 80)
time <- runif(20, max = 100)
fireworks <- Map(blast, n = n, radius = radius, x0 = x0, y0 = y0, time = time)
fireworks <- dplyr::bind_rows(fireworks)

p <- ggplot(fireworks) +
  geom_point(aes(x, y, colour = colour, group = id), size = 0.5, shape = 20) +
  scale_colour_identity() +
  coord_fixed(xlim = c(-65, 65), expand = FALSE, clip = "off") +
  theme_void() +
  theme(
    plot.background = element_rect(fill = "black", colour = NA),
    panel.border = element_blank()
  ) +
  # Here comes the gganimate code
  transition_components(time, exit_length = 20) +
  ease_aes(x = "sine-out", y = "sine-out") +
  shadow_wake(
    0.05,
    size = 3,
    alpha = TRUE,
    wrap = FALSE,
    falloff = "sine-in",
    exclude_phase = "enter"
  ) +
  exit_recolour(colour = "black")

Researcher

I am a PhD student of Crop Genetics and Breeding at the Zhejiang University Crop Science Lab. My research interests covers a range of issues:Population Genetics Evolution and Ecotype Divergence Analysis of Oilseed Rape, Genome-wide Association Study (GWAS) of Agronomic Traits.

comments powered by Disqus