This page is to explain what happens behind the animation functions. Generally speaking, there are three steps to follow when we want to create an HTML animation page. First, make some preparations (copy necessary CSS and JS files) for the HTML file and open a graphics device for the next step – ani.start(); second, make a series of plots using any R functions – these plots will be recorded as image frames one by one; third, write the HTML file – ani.stop(). Below is a typical process for creating HTML animation pages:
ani.options(...) ani.start(...) for (i in 1:nmax) plot(...) ani.stop()
The function ani.options() will tell the following functions some options to make an animation, such as the time interval, the maximum frames, the width and height of images, etc.
In the beginning, two files ANI.css and FUN.js are copied to the output directory outdir. Then a graphics device ani.dev is opened to record the plots as image files in the images/ directory1). The format of the image files is paste(%d, '.', ani.type), thus the files will be named from 1 to the maximum number of image frames.
Then some high-level plotting commands (typically in a loop) are executed and the plots are written to images/.
In the end, we have obtained all the animation frames, and ani.stop() will write an HTML file2) containing the animation driven by JS. The JS code also works as a loop: in the i-th step, display the i-th image element and hide the rest.
Below are two examples using functions in package animation and some custom R code to generate HTML animation pages respectively.
The function brownian.motion() in the package animation has given a demonstration of the Brownian Motion.
# create an HTML animation page of Brownian Motion # store the old option to restore it later oopt = ani.options(interval = 0.05, nmax = 100, ani.dev = png, ani.type = "png", title = "Demonstration of Brownian Motion", description = "Random walk on the 2D plane: for each point (x, y), x = x + rnorm(1) and y = y + rnorm(1).") ani.start() opar = par(mar = c(3, 3, 1, 0.5), mgp = c(2, .5, 0), tcl = -0.3, cex.axis = 0.8, cex.lab = 0.8, cex.main = 1) brownian.motion(pch = 21, cex = 5, col = "red", bg = "yellow") par(opar) ani.stop() ani.options(oopt)
The animation is like this:
Here is some code to produce an animation illustrating the gradient colors in polygons.
y = 0.1 + runif(20, 0.2, 1) xx = c(1, 1:20, 20) yy = c(0, y, 0) cl = seq(255, 0, length = 50) for (i in 1:50) { yy = rbind(yy, c(0, y - (1 - cl[i]/255) * min(y), 0)) plot(xx, yy[1, ], type = "n", xlab = "x", ylab = "y") for (j in 1:i) polygon(xx, yy[j + 1, ], col = rgb(1, cl[j]/255, 0), border = NA\) Sys.sleep(0.1) }
We can also put the animation in an HTML animation page like this:
oopt = ani.options(interval = 0.2, nmax = 50, ani.dev = png, ani.type = "png", ani.height = 350, ani.width = 500, title = "Demonstration of Polygons with Gradient Colors", description = "The graph actually consists of a series of polygons, each with a redder color starting from yellow.") ani.start() opar = par(mar = c(3, 3, 1, 0.5), mgp = c(2, .5, 0), tcl = -0.3, cex.axis = 0.8, cex.lab = 0.8, cex.main = 1) #################### y = 0.1 + runif(20, 0.2, 1) xx = c(1, 1:20, 20) yy = c(0, y, 0) cl = seq(255, 0, length = 50) for (i in 1:50) { yy = rbind(yy, c(0, y - (1 - cl[i]/255) * min(y), 0)) plot(xx, yy[1, ], type = "n", xlab = "x", ylab = "y") for (j in 1:i) polygon(xx, yy[j + 1, ], col = rgb(1, cl[j]/255, 0), border = NA\) # Sys.sleep(0.1) # not need to 'sleep' here! } #################### par(opar) ani.stop() ani.options(oopt)
This is the animation (it may look different with your output because y is random):
Here is an example of using the device CairoPNG() device in the Cairo package to record image frames (Thanks, Ivan Porro):
library(Cairo) library(animation) oopt = ani.options(interval = 0.05, nmax = 100, ani.dev = CairoPNG, title = "Demonstration of Brownian Motion", description = "Random walk on the 2D plane") ani.start() opar = par(mar = c(3, 3, 1, 0.5), mgp = c(2, 0.5, 0), tcl = -0.3, cex.axis = 0.8, cex.lab = 0.8, cex.main = 1) brownian.motion(pch = 21, cex = 5, col = "red", bg = "yellow") par(opar) ani.stop() ani.options(oopt)
Post the discussions here.