---
title: 'Lecture 8: Create Animations in R'
author: '[Dr. Aijun Zhang](http://www.statsoft.org) - [STAT3622 Data Visualization](http://www.statsoft.org/teaching/stat3622/)'
date: "13 October 2016"
output:
html_document:
fig_height: 4
fig_width: 5
highlight: tango
# mathjax: null
number_sections: yes
theme: paper
toc: yes
toc_depth: 2
---
```{r setup, include=FALSE}
options(width=120)
knitr::opts_chunk$set(echo = TRUE, message=FALSE, message=FALSE)
```
**Introduction:** This lecture introdues the `animation` package written by the R-genius Yihui Xie when he was a (undergraduate?) student in Remin University of China. Below are some precaution messages before using `animation` on our Stat3622 R studio server.
* The `animation` package supports multiple animation formats including Video, GIF, HTML, Latex, SWF, but some depend on extra software packages, e.g. ImageMagick for coverting R images to GIF.
* We primarily use `saveGIF` here, with ImageMagick already installed on our R server. `saveHTML` and `saveVideo` are also tested, while `saveLatex` and `saveSWF` are not tested.
* There is a better way to automatically include animations generated by R chunks, by setting `fig.show='animate'`(it requires `ffmpeg`). Currently our R server has a small bug with "Padoc error 67" though.
* This note is only demonstrates how to use R `animation` package, with some motivating examples. What it mainly does is a wrap-up mechanism that converts multiple images to a specific animation format. It should be noted that the real goodness of an animation is largely determined by the core R function that generates multiple images.
# Hans Rosling Bubbles
```{r}
library(animation)
a = saveGIF({
ani.options(interval = 0.5, nmax = 10)
par(mar = rep(3, 4))
Rosling.bubbles()
}, movie.name = "RoslingBubbles.gif")
# Rosling.bubbles # code by Yihui Xie
```
```{r echo=FALSE}
knitr::include_graphics("RoslingBubbles.gif")
```
# Running Clock
```{r}
a = saveGIF({
ani.options(interval = 1, nmax = 12)
par(mar = rep(3, 4))
for (i in seq(pi/2, -4/3*pi, length = 12)) {
plot(0, 0, pch = 20, ann = FALSE, axes = FALSE)
arrows(0, 0, cos(i), sin(i))
axis(1, 0, "VI"); axis(2, 0, "IX")
axis(3, 0, "XII"); axis(4, 0, "III");
box()
}}, movie.name = "Clock.gif")
```
```{r echo=FALSE}
knitr::include_graphics("Clock.gif")
```
# Simulation of 1D Random Walk
```{r}
a = saveGIF({
par(mar = rep(3, 4))
X0 = 0
N = 30
mu = -0.1
sigma = 3
dt = 1
m = 10 # number of replicates
ani.options(interval = 0.1, nmax = N)
# -------------------------
# dX = mu*dt + sigma*dWt
# dWt~ N(0,dt)
# -------------------------
set.seed(20161013)
X = matrix(NA, N+1, m)
for (k in 1:m) {
dW = rnorm(N, 0, sqrt(dt))
dX = mu*rep(dt, N) + sigma*dW
X[,k] = cumsum(c(X0, dX))
}
t = c(0,seq(1,N))
# matplot(t, X, type='l', lty=1, col=rainbow(m))
for (i in 1:N){
matplot(0:i, X[1:(i+1),], type='l',
lty=1, col=rainbow(m),
xlim = c(0, N), ylim = c(min(X), max(X)),
main = "Simulation of 1D Random Walk")
}
}, movie.name = "Brownian1.gif")
```
```{r echo=FALSE}
knitr::include_graphics("Brownian1.gif")
```
# Simulation of 2D Brownian Motion
Courtey of Taiyun Wei
```{r}
a = saveGIF({
par(mar = rep(3, 4))
n = 10
tmax = 30
set.seed(20161013)
x = rnorm(n)
y = rnorm(n)
ani.options(interval = 0.5, nmax = tmax)
for (i in 1:tmax) {
plot(x, y, pch = 21, cex = 4,
col = "red", bg = "yellow",
xlim = c(-10, 10), ylim = c(-10, 10),
main = "Simulation of 2D Brownian Motion")
text(x, y)
x = x + rnorm(n)
y = y + rnorm(n)
}
}, movie.name = "Brownian2.gif")
```
```{r echo=FALSE}
knitr::include_graphics("Brownian2.gif")
```
# Mathematical Heartbeat
There are different mathematical "heart curves" at [Wolfram MathWorld](http://mathworld.wolfram.com/HeartCurve.html). We provide a new heart formula that can be made animating with varying parameter.
$$
\frac{1}{2}|xy| - \frac{3a}{4}x^2 - \frac{4a}{7}y^2 - ay \geq 0, ~~ a\in[0.9, 1.3]
$$
```{r}
a = saveGIF({
n = 800
X = matrix(rep(seq(-1.4, 1.4, length=n), n), nrow=n, byrow=F)
Y = matrix(rep(seq(0, -2.5, length=n), n), nrow=n, byrow=T)
tmax = 10
ani.options(interval = 0.5, nmax = tmax)
par(mar = c(3,3,0,3))
for (a in seq(0.9, 1.3, length = tmax)) {
Z = abs(X*Y)/2 - 3*a*X^2/4 - 4*a*Y^2/7 - a*Y
Z[Z<=0] = NA
image(Z, col=2, ann = FALSE, axes = FALSE)
}}, movie.name = "Heart.gif")
```
```{r echo=FALSE}
knitr::include_graphics("Heart.gif")
```