gganimate:让数据动起来
简介
一年多以前我就写了篇R语言动画的博客:
R语言可视化学习笔记之gganimate包。当时使用的是由
David Robinson开发的gganimate
。后面由
Thomas Lin Pedersen接手,推倒重来,拓展了很多动画语法。具体的可参考
Thomas Lin Pedersen的
gganimate的Github主页。
gganimate语法
gganimate
在ggplot2
的基础上进行了动画的拓展,所以可以完美兼容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")