Title:  A Gallery of Animations in Statistics and Utilities to Create Animations 

Description:  Provides functions for animations in statistics, covering topics in probability theory, mathematical statistics, multivariate statistics, nonparametric statistics, sampling survey, linear models, time series, computational statistics, data mining and machine learning. These functions may be helpful in teaching statistics and data analysis. Also provided in this package are a series of functions to save animations to various formats, e.g. Flash, 'GIF', HTML pages, 'PDF' and videos. 'PDF' animations can be inserted into 'Sweave' / 'knitr' easily. 
Authors:  Yihui Xie [aut, cre], Christian Mueller [ctb], Lijia Yu [ctb], Weicheng Zhu [ctb] 
Maintainer:  Yihui Xie <[email protected]> 
License:  GPL 
Version:  2.7.1 
Built:  20240724 23:14:46 UTC 
Source:  https://github.com/yihui/animation 
This package contains a variety functions for animations in statistics which could probably aid in teaching statistics and data analysis; it also has several utilities to export R animations to other formats.
This package mainly makes use of HTML & JavaScript and R windows graphics
devices (such as x11
) to demonstrate animations in statistics;
other kinds of output such as Flash (SWF) or GIF animations or PDF animations
are also available if required software packages have been installed. See
below for details on each type of animation.
It's natural and easy to create an animation
in R using the windows graphics device, e.g. in x11()
or
windows()
. A basic scheme is like the Example 1 (see below).
Onscreen animations do not depend on any thirdparty software, but the rendering speed of the windows graphics devices is often slow, so the animation might not be smooth (especially under Linux and Mac OS).
The generation of HTML animation pages does not rely on
any thirdparty software either, and we only need a web browser to watch
the animation. See saveHTML
.
The HTML interface is just like a movie player – it comes with a series of buttons to control the animation (play, stop, next, previous, ...).
This HTML approach is flexible enough to be used even in Rweb, which means
we do not really have to install R to create animations! There is a demo in
system.file('misc', 'Rweb', 'demo.html', package = 'animation')
. We
can use saveHTML
to create animations directly in Rweb; this
can be helpful when we do not have R or cannot install R.
If ImageMagick or GraphicsMagick has been installed,
we can use im.convert
or gm.convert
to create a
GIF animation (combining several R plots together), or use
saveGIF
to create a GIF animation from an R code chunk.
If SWF Tools has been installed, we can use
saveSWF
to create a Flash animation (again, combining R
plots).
If LaTeX is present in the system, we can use
saveLatex
to insert animations into a PDF document and watch
the animation using the Adobe reader.
The animation is created by the LaTeX package animate
.
The function saveVideo
can use FFmpeg to
convert images to various video formats (e.g. ‘mp4’, ‘avi’ and
‘wmv’, etc).
Bug reports and feature requests can be sent to https://github.com/yihui/animation/issues.
Yihui Xie
Examples at https://yihui.org/animation/example/animationpackage/
The associated website for this package: https://yihui.org/animation
Yihui Xie and Xiaoyue Cheng. animation: A package for statistical animations. R News, 8(2):23–27, October 2008. URL: https://CRAN.Rproject.org/doc/Rnews/Rnews_20082.pdf
(NB: some functions mentioned in the above article have been slightly modified; see the help pages for the uptodate usage.)
Yihui Xie (2013). animation: An R Package for Creating Animations and Demonstrating Statistical Methods. Journal of Statistical Software, 53(1), 127. URL doi:10.18637/jss.v053.i01.
saveHTML
, saveGIF
,
saveSWF
, saveVideo
, saveLatex
There are various parameters that control the behaviour of the animation, such as time interval, maximum number of animation frames, height and width, etc.
ani.options(...)
ani.options(...)
... 
arguments in 
ani.options()
returns a list containing the options: when
parameters are set, their former values are returned in an invisible named
list. Such a list can be passed as an argument to
ani.options
to restore the parameter values.
ani.options('tag')
returns the value of the option 'tag'
.
ani.options(c('tag1', 'tag2'))
or ani.options('tag1', 'tag2')
returns a list containing the corresponding options.
The supported animation parameters:
a positive number to set the time interval of the animation (unit in seconds); default to be 1.
maximum number of steps in a loop (e.g. iterations) to create animation frames. Note: the actual number of frames can be less than this number, depending on specific animations. Default to be 50.
width and height of image frames (unit in
px); see graphics devices like png
, jpeg
, ...;
default to be 480. NB: for different graphics devices, the units of these
values might be different, e.g. PDF devices usually use inches, whereas
bitmap devices often use pixels.
The nominal resolution in ppi which will be recorded in the bitmap file,
if a positive integer. Also used for units other than the default,
and to convert points to pixels.;
see graphics devices like png
, jpeg
.
Customizing image number format in saveHTML
,
saveGIF
, saveLatex
and saveVideo
,
saveSWF
is not included,
it allows user to define the Cstyle string format for output image.
character: the name of the directory (a relative path) for
images when creating HTML animation pages; default to be 'images'
.
character: name of the target HTML main file (without path
name; basename only; default to be 'index.html'
)
a function or a function name: the graphics device; e.g.
(png
, pdf
, ...); default to be 'png'
character: image format for animation frames, e.g.
png
, jpeg
, ...; default to be 'png'
; this will be used
as the file extension of images, so don't forget to change this option as
well when you changed the option ani.dev
character: the title and description of the
animation in the HTML page created by saveHTML
logical: if TRUE
, write a footer part
in the HTML page containing detailed technical information else
the footer of the page will be blank.
logical or numeric: Number of times the GIF animation is to cycle through the image sequence before stopping. By default, this is set to zero or boolean value TRUE (infinite loop).
logical: whether autobrowse the animation page
immediately after it is created? (default to be interactive()
)
logical: whether to autoplay the animation when the HTML
page is loaded (default to be TRUE
); only applicable to
saveHTML
whether to use the graphics device specified in
ani.options('ani.dev')
(default to be TRUE
); if FALSE
,
we need to generate image files by our own approaches in the expression
expr
(see functions saveHTML
, saveGIF
,
saveLatex
and saveSWF
); this can be useful when
the output cannot be captured by standard R graphics devices – a typical
example is the rgl graphics (we can use rgl.snapshot
to
capture rgl graphics to png files, or rgl.postscript
to save
plots as postscript/pdf; see demo('rgl_animation')
or
demo('use_Cairo')
for examples or the last example below). Note,
however, we do not really have to create the images using R graphics
devices – see demo('flowers')
on how to download images from the
Internet and create an HTML animation page!
There are a couple of “hidden” options which are designed to facilitate the usage of some functions but are not initialized like the above options when the package is loaded, including:
this option will be checked first when calling
im.convert
(or saveGIF
) to see if it contains
the path to ‘convert.exe’; we can specify it beforehand to save the
efforts in searching for ‘convert.exe’ in ImageMagick under Windows.
For example, ani.options(convert = 'c:/program
files/imagemagick/convert.exe')
; note this option also works for Mac and
Linux (see help(im.convert)
)
this can help saveSWF
save the efforts of
searching for the software package “SWF Tools” under Windows; e.g. we can
specify ani.options(swftools = 'c:/program files/swftools')
in
advance
the value of this option can be used to determine the image
filename format when we want to use custom graphics devices to record
images, e.g. in saveLatex
, if ani.options('use.dev') ==
FALSE
, then ani.options('img.fmt')
will be a string like
'path/to/output/img.name%d.png'
, so we can use it to generate file
names in the argument expr
; see demo('rgl_animation')
for
example or the last example below
the path of the program qpdf
, e.g.
ani.options(qpdf = 'C:/Software/qpdf/bin/qpdf.exe')
; qpdf
is mainly used to compress PDF files in this package, and it is a smaller
tool than pdftk
. It is recommended over pdftk
especially under Linux, because tests show that pdftk
does not
work well under Linux in compressing PDF files, while qpdf
is
much better.
the path of the program Pdftk
, e.g.
ani.options(pdftk = 'C:/Software/pdftk.exe')
or
ani.options(pdftk = '/home/john/bin/pdftk')
; pdftk
will be
used to compress the PDF graphics output in the function
pdftk
; compression will not be tried if this options is
NULL
. This option will only affect saveGIF
,
saveLatex
and saveSWF
when
ani.options('ani.type')
is 'pdf'
.
the path of the progam ffmpeg
, e.g.
ani.options(ffmpeg = 'C:/Software/ffmpeg/bin/ffmpeg.exe')
; FFmpeg is
used to convert a sequence of images to a video. See
saveVideo
.
Please note that nmax
is not always equal to the number of
animation frames. Sometimes there is more than one frame recorded in a
single step of a loop, for instance, there are 2 frames generated in each
step of kmeans.ani
, and 4 frames in knn.ani
,
etc; whereas for newton.method
, the number of animation
frames is not definite, because there are other criteria to break the loop.
This function can be used for almost all the animation functions such as
brownian.motion
, boot.iid
,
buffon.needle
, cv.ani
, flip.coin
,
kmeans.ani
, knn.ani
, etc. Most of the options
here will affect the behaviour of animations of the formats HTML, GIF, SWF
and PDF; onscreen animations are only affected by interval
and
nmax
.
Yihui Xie
Examples at https://yihui.org/animation/example/anioptions/
options
, dev.interactive
,
saveHTML
, saveGIF
, saveLatex
,
saveSWF
, pdftk
https://www.pdflabs.com/docs/pdftkmanpage/
If this function is called in an interactive graphics device, it will pause
for a time interval (by default specified in
ani.options('interval')
) and flush the current device;
otherwise it will do nothing.
ani.pause(interval = ani.options("interval"))
ani.pause(interval = ani.options("interval"))
interval 
a time interval to pause (in seconds) 
Invisible NULL
.
Yihui Xie
dev.interactive
, Sys.sleep
,
dev.flush
## pause for 2 seconds oopt = ani.options(interval = 2) for (i in 1:5) { plot(runif(10), ylim = c(0, 1)) ani.pause() } ani.options(oopt) ## see demo('Xmas2', package = 'animation') for another example
## pause for 2 seconds oopt = ani.options(interval = 2) for (i in 1:5) { plot(runif(10), ylim = c(0, 1)) ani.pause() } ani.options(oopt) ## see demo('Xmas2', package = 'animation') for another example
These two functions use recordPlot
and replayPlot
to record image frames and replay the animation respectively.
Replay the animation
ani.record(reset = FALSE, replay.cur = FALSE) ani.replay(list)
ani.record(reset = FALSE, replay.cur = FALSE) ani.replay(list)
reset 
if 
replay.cur 
whether to replay the current plot (we can set both

list 
a list of recorded plots; if missing, the recorded plots by

One difficulty in capturing images in R (base graphics) is that the
offscreen graphics devices cannot capture lowlevel plotting commands as
new image files – only highlevel plotting commands can produce new
image files; ani.record
uses recordPlot
to record
the plots when any changes are made on the current plot. For a graphical
device to be recordable, you have to call dev.control('enable')
before
plotting.
ani.replay
can replay the recorded plots as an
animation. Moreover, we can convert the recorded plots to other formats
too, e.g. use saveHTML
and friends.
The recorded plots are stored as a list in .ani.env$.images
, which
is the default value to be passed to ani.replay
;
.ani.env
is an invisible environment
created when this
package is loaded, and it will be used to store some commonly used objects
such as animation options (ani.options
).
Invisible NULL
.
Although we can record changes made by lowlevel plotting commands
using ani.record
, there is a price to pay – we need memory
to store the recorded plots, which are usually verg large when the plots
are complicated (e.g. we draw millions of points or polygons in a single
plot). However, we can set replay.cur
to force R to produce a new
copy of the current plot, which will be automatically recorded by
offscreen grapihcs devices as new image files. This method has a
limitation: we must open a screen device to assist R to record the plots.
See the last example below. We must be very careful that no other graphics
devices are opened before we use this function.
If we use base graphics, we should bear in mind that the background colors
of the plots might be transparent, which could lead to problems in HTML
animation pages when we use the png
device (see the examples
below).
Yihui Xie
Examples at https://yihui.org/animation/example/anirecord/
recordPlot
and replayPlot
;
ani.pause
library(animation) n = 20 x = sort(rnorm(n)) y = rnorm(n) ## set up an empty frame, then add points one by one par(bg = "white") # ensure the background color is white plot(x, y, type = "n") ani.record(reset = TRUE) # clear history before recording for (i in 1:n) { points(x[i], y[i], pch = 19, cex = 2) ani.record() # record the current frame } ## now we can replay it, with an appropriate pause between frames oopts = ani.options(interval = 0.5) ani.replay() ## or export the animation to an HTML page saveHTML(ani.replay(), img.name = "record_plot") ## record plots and replay immediately saveHTML({ dev.control("enable") # enable recording par(bg = "white") # ensure the background color is white plot(x, y, type = "n") for (i in 1:n) { points(x[i], y[i], pch = 19, cex = 2) ani.record(reset = TRUE, replay.cur = TRUE) # record the current frame } }) ani.options(oopts)
library(animation) n = 20 x = sort(rnorm(n)) y = rnorm(n) ## set up an empty frame, then add points one by one par(bg = "white") # ensure the background color is white plot(x, y, type = "n") ani.record(reset = TRUE) # clear history before recording for (i in 1:n) { points(x[i], y[i], pch = 19, cex = 2) ani.record() # record the current frame } ## now we can replay it, with an appropriate pause between frames oopts = ani.options(interval = 0.5) ani.replay() ## or export the animation to an HTML page saveHTML(ani.replay(), img.name = "record_plot") ## record plots and replay immediately saveHTML({ dev.control("enable") # enable recording par(bg = "white") # ensure the background color is white plot(x, y, type = "n") for (i in 1:n) { points(x[i], y[i], pch = 19, cex = 2) ani.record(reset = TRUE, replay.cur = TRUE) # record the current frame } }) ani.options(oopts)
This is a visual demonstration of finding the root of an equation $f(x) =
0$
on an interval using the Bisection Method.
bisection.method( FUN = function(x) x^2  4, rg = c(1, 10), tol = 0.001, interact = FALSE, main, xlab, ylab, ... )
bisection.method( FUN = function(x) x^2  4, rg = c(1, 10), tol = 0.001, interact = FALSE, main, xlab, ylab, ... )
FUN 
the function in the equation to solve (univariate) 
rg 
a vector containing the endpoints of the interval to be searched
for the root; in a 
tol 
the desired accuracy (convergence tolerance) 
interact 
logical; whether choose the endpoints by cliking on the curve (for two times) directly? 
xlab , ylab , main

axis and main titles to be used in the plot 
... 
other arguments passed to 
Suppose we want to solve the equation $f(x) = 0$
. Given two points a and
b such that $f(a)$
and $f(b)$
have opposite signs, we know by the
intermediate value theorem that $f$
must have at least one root in the
interval $[a, b]$
as long as $f$
is continuous on this interval. The
bisection method divides the interval in two by computing $c = (a + b) /
2$
. There are now two possibilities: either $f(a)$
and $f(c)$
have
opposite signs, or $f(c)$
and $f(b)$
have opposite signs. The
bisection algorithm is then applied recursively to the subinterval where the
sign change occurs.
During the process of searching, the midpoint of subintervals are annotated in the graph by both texts and blue straight lines, and the endpoints are denoted in dashed red lines. The root of each iteration is also plotted in the right margin of the graph.
A list containing
root 
the root found by the algorithm 
value 
the value of 
iter 
number of
iterations; if it is equal to 
The maximum number of iterations is specified in
ani.options('nmax')
.
Yihui Xie
Examples at https://yihui.org/animation/example/bisectionmethod/
For more information about Bisection method, please see https://en.wikipedia.org/wiki/Bisection_method
Several points moving randomly in a circle.
BM.circle(n = 20, col = rainbow(n), ...)
BM.circle(n = 20, col = rainbow(n), ...)
n 
number of points 
col 
colors of points 
... 
other parameters passed to 
This is a solution to the question raised in Rhelp: https://stat.ethz.ch/pipermail/rhelp/2008December/183018.html.
Invisible NULL
.
The maximum number of steps in the motion is specified in
ani.options('nmax')
.
Yihui Xie
Examples at https://yihui.org/animation/example/bmcircle/
Use a sunflower scatter plot to illustrate the results of resampling, and a histogram to show the distribution of the statistic of interest.
boot.iid( x = runif(20), statistic = mean, m = length(x), mat = matrix(1:2, 2), widths = rep(1, ncol(mat)), heights = rep(1, nrow(mat)), col = c("black", "red", "bisque", "red", "gray"), cex = c(1.5, 0.8), main, ... )
boot.iid( x = runif(20), statistic = mean, m = length(x), mat = matrix(1:2, 2), widths = rep(1, ncol(mat)), heights = rep(1, nrow(mat)), col = c("black", "red", "bisque", "red", "gray"), cex = c(1.5, 0.8), main, ... )
x 
a numerical vector (the original data). 
statistic 
A function which returns a value of the statistic of interest when applied to the data x. 
m 
the sample size for bootstrapping ( 
mat , widths , heights

arguments passed to 
col 
a character vector of length 5 specifying the colors of: points of original data, points for the sunflowerplot, rectangles of the histogram, the density line, and the rug. 
cex 
a numeric vector of length 2: magnification of original data points and the sunflowerplot points. 
main 
a character vector of length 2: the main titles of the two graphs. 
... 
other arguments passed to 
This is actually a very naive version of bootstrapping but may be useful for novices. By default, the circles denote the original dataset, while the red sunflowers (probably) with leaves denote the points being resampled; the number of leaves just means how many times these points are resampled, as bootstrap samples with replacement. The xaxis is the sample values, and yaxis is the indices of sample points.
The whole process has illustrated the steps of resampling, computing the statistic and plotting its distribution based on bootstrapping.
A list containing
t0 
The observed value of 'statistic' applied to 'x'. 
tstar 
Bootstrap versions of the 'statistic'. 
The maximum times of resampling is specified in
ani.options('nmax')
.
Yihui Xie
Examples at https://yihui.org/animation/example/bootiid/
There are many references explaining the bootstrap and its variations.
Efron, B. and Tibshirani, R. (1993) An Introduction to the Bootstrap. Chapman & Hall.
Sample the original data with replacement and fit LOWESS curves accordingly.
boot.lowess(x, y = NULL, f = 2/3, iter = 3, line.col = "#FF000033", ...)
boot.lowess(x, y = NULL, f = 2/3, iter = 3, line.col = "#FF000033", ...)
x , y , f , iter

passed to 
line.col 
the color of the LOWESS lines 
... 
other arguments passed to the scatterplot by 
We keep on resampling the data and finally we will see several bootstrapped LOWESS curves, which may give us a rough idea about a “confidence interval” of the LOWESS fit.
Yihui Xie
Examples at https://yihui.org/animation/example/bootlowess/
Brownian motion, or random walk, can be regarded as the trace of some cumulative normal random numbers.
brownian.motion(n = 10, xlim = c(20, 20), ylim = c(20, 20), ...)
brownian.motion(n = 10, xlim = c(20, 20), ylim = c(20, 20), ...)
n 
Number of points in the scatterplot 
xlim , ylim

Arguments passed to 
... 
other arguments passed to 
The location of the next step is “current location + random Gaussian numbers”, i.e.,
$x_{k + 1} = x_{k} + rnorm(1)$
$y_{k + 1} = y_{k} + rnorm(1)$
where (x, y) stands for the location of a point.
None (invisible NULL
).
The maximum number of steps in the motion is specified in
ani.options('nmax')
.
Yihui Xie
Examples at https://yihui.org/animation/example/brownianmotion/
This function provides a simulation for the problem of Buffon's Needle, which is one of the oldest problems in the field of geometrical probability.
buffon.needle( l = 0.8, d = 1, redraw = TRUE, mat = matrix(c(1, 3, 2, 3), 2), heights = c(3, 2), col = c("lightgray", "red", "gray", "red", "blue", "black", "red"), expand = 0.4, type = "l", ... )
buffon.needle( l = 0.8, d = 1, redraw = TRUE, mat = matrix(c(1, 3, 2, 3), 2), heights = c(3, 2), col = c("lightgray", "red", "gray", "red", "blue", "black", "red"), expand = 0.4, type = "l", ... )
l 
numerical. length of the needle; shorter than 
d 
numerical. distances between lines; it should be longer than

redraw 
logical. redraw former ‘needles’ or not for each drop. 
mat , heights

arguments passed to 
col 
a character vector of length 7 specifying the colors of:
background of the area between parallel lines, the needles, the sin curve,
points below / above the sin curve, estimated 
expand 
a numerical value defining the expanding range of the yaxis
when plotting the estimated 
type 
an argument passed to 
... 
other arguments passed to

This is quite an old problem in probability. For mathematical background, please refer to https://en.wikipedia.org/wiki/Buffon's_needle or https://mste.illinois.edu/activity/buffon/.
‘Needles’ are denoted by segments on the 2D plane, and dropped randomly to
check whether they cross the parallel lines. Through many times of ‘dropping’
needles, the approximate value of $\pi$
can be calculated out.
There are three graphs made in each step: the topleft one is a simulation of
the scenario, the topright one is to help us understand the connection
between dropping needles and the mathematical method to estimate $\pi$
,
and the bottom one is the result for each drop.
The values of estimated $\pi$
are returned as a numerical vector
(of length nmax
).
Note that redraw
has great influence on the speed of the
simulation (animation) if the control argument nmax
(in
ani.options
) is quite large, so you'd better specify it as
FALSE
when doing a large amount of simulations.
The maximum number of drops is specified in ani.options('nmax')
.
Yihui Xie
Examples at https://yihui.org/animation/example/buffonneedle/
Ramaley, J. F. (Oct 1969). Buffon's Noodle Problem. The American Mathematical Monthly 76 (8): 916918.
Cleveland Cavaliers played against Los Angeles Lakers at Staples Center in LA on Dec 25, 2009 and won the game by 102:87. This data recorded the locations of players on the court and the results of the shots.
A data frame with 455 observations on the following 7 variables.
player
a character vector: the current player
time
a character vector: the time
period
a numeric vector: the period (1  4)
realx
a numeric vector: the xaxis location
realy
a numeric vector: the yaxis location
result
a factor with levels made
and
missed
team
a factor with levels CLE
,
LAL
and OFF
We view the court with CLE in the left and LAL in the right:
realx
is the distance to the left border of CLE's court, and
realy
is the distance to the bottom border of the court; notice that
the size of the court is $94 \times 50$
(feet).
http://www.basketballgeek.com/data/ (transformed based on the original data)
## see demo('CLEvsLAL', package = 'animation') for a `replay' of the game
## see demo('CLEvsLAL', package = 'animation') for a `replay' of the game
First of all, a number of obs
observations are generated from a
certain distribution for each variable $X_j$
, $j = 1, 2, \cdots, n$
, and $n = 1, 2, \cdots, nmax$
, then
the sample means are computed, and at last the density of these sample means
is plotted as the sample size $n$
increases (the theoretical limiting
distribution is denoted by the dashed line), besides, the Pvalues from the
normality test shapiro.test
are computed for each $n$
and
plotted at the same time.
clt.ani( obs = 300, FUN = rexp, mean = 1, sd = 1, col = c("bisque", "red", "blue", "black"), mat = matrix(1:2, 2), widths = rep(1, ncol(mat)), heights = rep(1, nrow(mat)), xlim, ... )
clt.ani( obs = 300, FUN = rexp, mean = 1, sd = 1, col = c("bisque", "red", "blue", "black"), mat = matrix(1:2, 2), widths = rep(1, ncol(mat)), heights = rep(1, nrow(mat)), xlim, ... )
obs 
the number of sample means to be generated from the distribution
based on a given sample size 
FUN 
the function to generate 
mean , sd

the expectation and standard deviation of the population
distribution (they will be used to plot the density curve of the
theoretical Normal distribution with mean equal to 
col 
a vector of length 4 specifying the colors of the histogram, the density curve of the sample mean, the theoretical density cuve and Pvalues. 
mat , widths , heights

arguments passed to 
xlim 
the xaxis limit for the histogram (it has a default value if not specified) 
... 
other arguments passed to 
As long as the conditions of the Central Limit Theorem (CLT) are satisfied,
the distribution of the sample mean will be approximate to the Normal
distribution when the sample size n
is large enough, no matter what is
the original distribution. The largest sample size is defined by nmax
in ani.options
.
A data frame of Pvalues.
Yihui Xie
Examples at https://yihui.org/animation/example/cltani/
This function gives a demonstration of the concept of confidence intervals in mathematical statistics.
conf.int(level = 0.95, size = 50, cl = c("red", "gray"), ...)
conf.int(level = 0.95, size = 50, cl = c("red", "gray"), ...)
level 
the confidence level 
size 
the sample size for drawing samples from N(0, 1) 
cl 
two different colors to annotate whether the confidence intervals
cover the true mean ( 
... 
other arguments passed to 
Keep on drawing samples from the Normal distribution N(0, 1), computing the intervals based on a given confidence level and plotting them as segments in a graph. In the end, we may check the coverage rate against the given confidence level.
Intervals that cover the true parameter are denoted in color cl[2]
,
otherwise in color cl[1]
. Each time we draw a sample, we can compute
the corresponding confidence interval. As the process of drawing samples goes
on, there will be a legend indicating the numbers of the two kinds of
intervals respectively and the coverage rate is also denoted in the topleft
of the plot.
The argument nmax
in ani.options
controls the maximum
times of drawing samples.
A list containing
level 
confidence level 
size 
sample size 
CI 
a matrix of confidence intervals for each sample 
CR 
coverage rate 
Yihui Xie
Examples at https://yihui.org/animation/example/confint/
George Casella and Roger L. Berger. Statistical Inference. Duxbury Press, 2th edition, 2001.
This function uses rectangles to illustrate the $k$
folds and
mark the test set and the training set with different colors.
cv.ani( x = runif(150), k = 10, col = c("green", "red", "blue"), pch = c(4, 1), ... )
cv.ani( x = runif(150), k = 10, col = c("green", "red", "blue"), pch = c(4, 1), ... )
x 
a numerical vector which stands for the sample points. 
k 
an integer: how many parts should we split the data into?
(comes from the 
col 
a character vector of length 3 specifying the colors of: the rectangle representing the test set, the points of the test set, and points of the training set. 
pch 
a numeric vector of length 2 specifying the symbols of the test set and training set respectively. 
... 
other arguments passed to

Briefly speaking, the process of crossvalidation is just to split the whole data set into several parts and select one part as the test set and the rest parts as the training set.
The computation of sample sizes is base on kfcv
.
None (invisible NULL
).
For the ‘leaveoneout’ crossvalidation, just specify
k
as length(x)
, then the rectangles will ‘shrink’
into single lines.
The final number of animation frames is the smaller one of
ani.options('nmax')
and k
.
This function has nothing to do with specific models used in crossvalidation.
Yihui Xie
Examples at https://yihui.org/animation/example/cvani/
This function provids an illustration of the process of finding out the optimum number of variables using kfold crossvalidation in a linear discriminant analysis (LDA).
cv.nfeaturesLDA( data = matrix(rnorm(600), 60), cl = gl(3, 20), k = 5, cex.rg = c(0.5, 3), col.av = c("blue", "red"), ... )
cv.nfeaturesLDA( data = matrix(rnorm(600), 60), cl = gl(3, 20), k = 5, cex.rg = c(0.5, 3), col.av = c("blue", "red"), ... )
data 
a data matrix containg the predictors in columns 
cl 
a factor indicating the classification of the rows of 
k 
the number of folds 
cex.rg 
the range of the magnification to be used to the points in the plot 
col.av 
the two colors used to respectively denote rates of correct predictions in the ith fold and the average rates for all k folds 
... 
arguments passed to 
For a classification problem, usually we wish to use as less variables as possible because of difficulties brought by the high dimension.
The selection procedure is like this:
Split the whole data randomly into $k$
folds:
For the number of features $g = 1, 2, \cdots, g_{max}$
, choose $g$
features that have the largest discriminatory
power (measured by the Fstatistic in ANOVA):
For the fold $i$
($i = 1, 2, \cdots, k$
):
Train a LDA model without the $i$
th fold data, and predict with the
$i$
th fold for a proportion of correct predictions
$p_{gi}$
;
Average the $k$
proportions to get the correct rate $p_g$
;
Determine the optimum number of features with the largest $p$
.
Note that $g_{max}$
is set by ani.options('nmax')
(i.e. the
maximum number of features we want to choose).
A list containing
accuracy 
a matrix in which the element in the ith row and jth column is the rate of correct predictions based on LDA, i.e. build a LDA model with j variables and predict with data in the ith fold (the test set) 
optimum 
the optimum number of features based on the crossvalidation 
Yihui Xie <https://yihui.org/>
Examples at https://yihui.org/animation/example/cvnfeatureslda/
Maindonald J, Braun J (2007). Data Analysis and Graphics Using R  An ExampleBased Approach. Cambridge University Press, 2nd edition. pp. 400
Suppose there are two plant species in a field: A and B. One of them will die at each time and a new plant will grow in the place where the old plant died; the species of the new plant depends on the proportions of two species: the larger the proportion is, the greater the probability for this species to come up will be.
ecol.death.sim( nr = 10, nc = 10, num.sp = c(50, 50), col.sp = c(1, 2), pch.sp = c(1, 2), col.die = 1, pch.die = 4, cex = 3, ... )
ecol.death.sim( nr = 10, nc = 10, num.sp = c(50, 50), col.sp = c(1, 2), pch.sp = c(1, 2), col.die = 1, pch.die = 4, cex = 3, ... )
nr , nc

number of rows and columns of the field (plants grow on a

num.sp 
number of two plants respectively 
col.sp , pch.sp

colors and point symbols of the two species respectively 
col.die , pch.die , cex

the color, point symbol and magnification to annotate the plant which dies (symbol default to be an ‘X’) 
... 
other arguments passed to 
a vector (factor) containing 1's and 2's, denoting the plants finally survived
2 * ani.options('nmax')
image frames will actually be produced.
Yihui Xie
This animation is motivated by a question raised from Jing Jiao, a student in biology, to show the evolution of two species.
The original post is in the forum of the “Capital of Statistics”: https://d.cosx.org/d/14093 (in Chinese)
oopt = ani.options(nmax = ifelse(interactive(), 50, 2), interval = 0.3) par(ann = FALSE, mar = rep(0, 4)) ecol.death.sim() ## large scale simulation ani.options(nmax = ifelse(interactive(), 1000, 2), interval = 0.02) ecol.death.sim(col.sp = c(8, 2), pch.sp = c(20, 17)) ani.options(oopt)
oopt = ani.options(nmax = ifelse(interactive(), 50, 2), interval = 0.3) par(ann = FALSE, mar = rep(0, 4)) ecol.death.sim() ## large scale simulation ani.options(nmax = ifelse(interactive(), 1000, 2), interval = 0.02) ecol.death.sim(col.sp = c(8, 2), pch.sp = c(20, 17)) ani.options(oopt)
This function provides a simulation to the process of flipping coins and computes the frequencies for ‘heads’ and ‘tails’.
flip.coin( faces = 2, prob = NULL, border = "white", grid = "white", col = 1:2, type = "p", pch = 21, bg = "transparent", digits = 3 )
flip.coin( faces = 2, prob = NULL, border = "white", grid = "white", col = 1:2, type = "p", pch = 21, bg = "transparent", digits = 3 )
faces 
an integer or a character vector. See details below. 
prob 
the probability vector of showing each face. If 
border 
The border style for the rectangles which stand for probabilities. 
grid 
the color for horizontal grid lines in these rectangles 
col 
The colors to annotate different faces of the ‘coin’. 
type , pch , bg

See 
digits 
integer indicating the precision to be used in the annotation of frequencies in the plot 
If faces
is a single integer, say 2, a sequence of integers from 1 to
faces
will be used to denote the faces of a coin; otherwise this
character vector just gives the names of each face.
When the $i$
th face shows up, a colored thin rectangle will be added to
the corresponding place (the $i$
th bar), and there will be corresponding
annotations for the number of tosses and frequencies.
The special argument grid
is for consideration of a too large number
of flipping, in which case if you still draw horizontal lines in these
rectangles, the rectangles will be completely covered by these lines, thus we
should specify it as NA
.
At last the frequency for each face will be computed and shown in the header
of the plot – this shall be close to prob
if
ani.options('nmax')
is large enough.
A list containing
freq 
A vector of frequencies (simulated probabilities) 
nmax 
the total number of tosses 
You may change the colors of each face using the argument col
(repeated if shorter than the number of faces).
Yihui Xie
Examples at https://yihui.org/animation/example/flipcoin/
We can use R to generate random numbers from the Normal distribution and write them into an HTML document, then the Google Visualization gadget “motionchart” will prepare the animation for us (a Flash animation with several buttons).
g.brownian.motion( p = 20, start = 1900, digits = 14, file = "index.html", width = 800, height = 600 )
g.brownian.motion( p = 20, start = 1900, digits = 14, file = "index.html", width = 800, height = 600 )
p 
number of points 
start 
start “year”; it has no practical meaning in this animation but it's the required by the Google gadget 
digits 
the precision to round the numbers 
file 
the HTML filename 
width , height

width and height of the animation 
NULL
. An HTML page will be opened as the side effect.
The number of frames is controlled by ani.options('nmax')
as
usual.
Due to the “security settings” of Adobe Flash player, you might not be able to view the generated Flash animation locally, i.e. using an address like ‘file:///C:/Temp/index.html’. In this case, you can upload the HTML file to a web server and use the http address to view the Flash file.
Yihui Xie
https://developers.google.com/chart/?csw=1 and https://yihui.org/en/2008/11/brownianmotionusinggooglevisualizationapiandr/
brownian.motion
, BM.circle
,
rnorm
if (interactive()) g.brownian.motion(15, digits = 2, width = 600, height = 500, file = "BMmotionchart.html")
if (interactive()) g.brownian.motion(15, digits = 2, width = 600, height = 500, file = "BMmotionchart.html")
This function provids a visual illustration for the process of minimizing a realvalued function through Gradient Descent Algorithm.
grad.desc( FUN = function(x, y) x^2 + 2 * y^2, rg = c(3, 3, 3, 3), init = c(3, 3), gamma = 0.05, tol = 0.001, gr = NULL, len = 50, interact = FALSE, col.contour = "red", col.arrow = "blue", main )
grad.desc( FUN = function(x, y) x^2 + 2 * y^2, rg = c(3, 3, 3, 3), init = c(3, 3), gamma = 0.05, tol = 0.001, gr = NULL, len = 50, interact = FALSE, col.contour = "red", col.arrow = "blue", main )
FUN 
a bivariate objective function to be minimized (variable names do
not have to be 
rg 
ranges for independent variables to plot contours; in a 
init 
starting values 
gamma 
size of a step 
tol 
tolerance to stop the iterations, i.e. the minimum difference
between 
gr 
the gradient of 
len 
desired length of the independent sequences (to compute z values for contours) 
interact 
logical; whether choose the starting values by clicking on the contour plot directly? 
col.contour , col.arrow

colors for the contour lines and arrows respectively (default to be red and blue) 
main 
the title of the plot; if missing, it will be derived from

Gradient descent is an optimization algorithm. To find a local minimum of a function using gradient descent, one takes steps proportional to the negative of the gradient (or the approximate gradient) of the function at the current point. If instead one takes steps proportional to the gradient, one approaches a local maximum of that function; the procedure is then known as gradient ascent.
The arrows are indicating the result of iterations and the process of
minimization; they will go to a local minimum in the end if the maximum
number of iterations ani.options('nmax')
has not been reached.
A list containing
par 
the solution for the local minimum 
value 
the value of the objective function corresponding to

iter 
the number of iterations; if it is equal to

gradient 
the gradient function of the objective function 
persp 
a function to make the perspective plot of the objective
function; can accept further arguments from 
Please make sure the function FUN
provided is differentiable at
init
, what's more, it should also be 'differentiable' using
deriv
if you do not provide the gradient function gr
.
If the arrows cannot reach the local minimum, the maximum number of
iterations nmax
in ani.options
may need to be
increased.
Yihui Xie
Examples at https://yihui.org/animation/example/graddesc/
This speech came on the 30th anniversary of China's economic reform in 1978.
int [1:75] 119 175 222 204 276 168 257 89 61 288 ...
On Dec 18, 2008, Chinese President Hu gave a speech on the 30th anniversary of China's economic reform in 1978, and this data has recorded the number of words used in each paragraph of his speech.
The full text of speech is at
http://cpc.people.com.cn/GB/64093/64094/8544901.html
(you may use
web.archive.org
if this URL is no longer accessible).
## clear pattern: 1/3 short, 1/3 long, 1/3 short again plot(HuSpeech, type = "b", pch = 20, xlab = "paragraph index", ylab = "word count") ## see ?moving.block for an animation example
## clear pattern: 1/3 short, 1/3 long, 1/3 short again plot(HuSpeech, type = "b", pch = 20, xlab = "paragraph index", ylab = "word count") ## see ?moving.block for an animation example
Temperatures in central Iowa over 106 years.
TimeSeries [1:116] from 1895 to 2010: 32.7 27.8 32.7 30.4 42.6 31.9 34.5 39.8 32.6 39.6 ...
http://www.wrcc.dri.edu/cgibin/divplot1_form.pl?1305
plot(iatemp)
plot(iatemp)
The main purpose of these two functions is to create GIF animations.
im.convert( files, output = "animation.gif", convert = c("magick", "convert", "gm convert"), cmd.fun = if (.Platform$OS.type == "windows") shell else system, extra.opts = "", clean = FALSE ) gm.convert(..., convert = "gm convert")
im.convert( files, output = "animation.gif", convert = c("magick", "convert", "gm convert"), cmd.fun = if (.Platform$OS.type == "windows") shell else system, extra.opts = "", clean = FALSE ) gm.convert(..., convert = "gm convert")
files 
either a character vector of file names, or a single string containing wildcards (e.g. ‘Rplot*.png’) 
output 
the file name of the output (with proper extensions, e.g.

convert 
the 
cmd.fun 
a function to invoke the OS command; by default

extra.opts 
additional options to be passed to 
clean 
logical: delete the input 
... 
arguments to be passed to 
The function im.convert
simply wraps the arguments of the
convert
utility of ImageMagick to make it easier to call
ImageMagick in R;
The function gm.convert
is a wrapper for the command
gm convert
of GraphicsMagick.
The command for the conversion.
If ani.options('autobrowse') == TRUE
, this function will also try to
open the output automatically.
If files
is a character vector, please make sure the order of
filenames is correct! The first animation frame will be files[1]
,
the second frame will be files[2]
, ...
Both ImageMagick and GraphicsMagick may have a limit on the number of
images to be converted. It is a known issue that this function can fail
with more than (approximately) 9000 images. The function
saveVideo
is a better alternative in such a case.
Most Windows users do not have read the boring notes below after they have installed ImageMagick or GraphicsMagick. For the rest of Windows users:
Please install ImageMagick from
http://www.imagemagick.org, and make sure the the path to
convert.exe
is in your 'PATH'
variable, in which case the
command convert
can be called without the full path. Windows
users are often very confused about the ImageMagick and 'PATH'
setting, so I'll try to search for ImageMagick in the Registry Hive by
readRegistry('SOFTWARE\ImageMagick\Current')$BinPath
, thus you might
not really need to modify your 'PATH'
variable.
For Windows users who have installed LyX, I will also try to find the
convert
utility in the LyX installation directory, so they do not
really have to install ImageMagick if LyX exists in their system (of
course, the LyX should be installed with ImageMagick).
Once the convert
utility is found, the animation option
'convert'
will be set (ani.options(convert =
'path/to/convert.exe')
); this can save time for searching for
convert
in the operating system next time.
During the installation of GraphicsMagick, you will be asked if you allow it to change the PATH variable; please do check the option.
A reported problem is cmd.fun = shell
might not work under Windows
but cmd.fun = system
works fine. Try this option in case of
failures.
Yihui Xie
Examples at https://yihui.org/animation/example/imconvert/
ImageMagick: http://www.imagemagick.org/script/convert.php
GraphicsMagick: http://www.graphicsmagick.org
Other utilities:
saveGIF()
,
saveHTML()
,
saveLatex()
,
saveSWF()
,
saveVideo()
Compute sample sizes for $k$
fold crossvalidation.
kfcv(k, N)
kfcv(k, N)
k 
number of groups. 
N 
total sample size. 
If N/k is an integer, the sample sizes are k ‘N/k’s (N/k, N/k, ...), otherwise the remainder will be allocated to each group as ‘uniformly’ as possible, and at last these sample sizes will be permuted randomly.
A vector of length k
containing $k$
sample sizes.
Yihui Xie
## divisible kfcv(5, 25) ## not divisible kfcv(10, 77)
## divisible kfcv(5, 25) ## not divisible kfcv(10, 77)
This function provides a demo of the kMeans cluster algorithm for data containing only two variables (columns).
kmeans.ani( x = cbind(X1 = runif(50), X2 = runif(50)), centers = 3, hints = c("Move centers!", "Find cluster?"), pch = 1:3, col = 1:3 )
kmeans.ani( x = cbind(X1 = runif(50), X2 = runif(50)), centers = 3, hints = c("Move centers!", "Find cluster?"), pch = 1:3, col = 1:3 )
x 
A numercal matrix or an object that can be coerced to such a matrix (such as a numeric vector or a data frame with all numeric columns) containing only 2 columns. 
centers 
Either the number of clusters or a set of initial (distinct)
cluster centres. If a number, a random set of (distinct) rows in 
hints 
Two text strings indicating the steps of kmeans clustering: move the center or find the cluster membership? 
pch , col

Symbols and colors for different clusters; the length of these two arguments should be equal to the number of clusters, or they will be recycled. 
The kMeans cluster algorithm may be regarded as a series of iterations of: finding cluster centers, computing distances between sample points, and redefining cluster membership.
The data given by x
is clustered by the $k$
means method, which
aims to partition the points into $k$
groups such that the sum of squares
from points to the assigned cluster centers is minimized. At the minimum, all
cluster centres are at the mean of their Voronoi sets (the set of data points
which are nearest to the cluster centre).
A list with components
cluster 
A vector of integers indicating the cluster to which each point is allocated. 
centers 
A matrix of cluster centers. 
This function is only for demonstration purpose. For practical
applications please refer to kmeans
.
Note that ani.options('nmax')
is defined as the maximum number of
iterations in such a sense: an iteration includes the process of computing
distances, redefining membership and finding centers. Thus there should be
2 * ani.options('nmax')
animation frames in the output if the other
condition for stopping the iteration has not yet been met (i.e. the cluster
membership will not change any longer).
Yihui Xie
Examples at https://yihui.org/animation/example/kmeansani/
Demonstrate the process of kNearest Neighbour classification on the 2D plane.
knn.ani( train, test, cl, k = 10, interact = FALSE, tt.col = c("blue", "red"), cl.pch = seq_along(unique(cl)), dist.lty = 2, dist.col = "gray", knn.col = "green", ... )
knn.ani( train, test, cl, k = 10, interact = FALSE, tt.col = c("blue", "red"), cl.pch = seq_along(unique(cl)), dist.lty = 2, dist.col = "gray", knn.col = "green", ... )
train 
matrix or data frame of training set cases containing only 2 columns 
test 
matrix or data frame of test set cases. A vector will be
interpreted as a row vector for a single case. It should also contain only
2 columns. This data set will be ignored if 
cl 
factor of true classifications of training set 
k 
number of neighbours considered. 
interact 
logical. If 
tt.col 
a vector of length 2 specifying the colors for the training data and test data. 
cl.pch 
a vector specifying symbols for each class 
dist.lty , dist.col

the line type and color to annotate the distances 
knn.col 
the color to annotate the knearest neighbour points using a polygon 
... 
additional arguments to create the empty frame for the animation
(passed to 
For each row of the test set, the $k$
nearest (in Euclidean distance)
training set vectors are found, and the classification is decided by majority
vote, with ties broken at random. For a single test sample point, the basic
steps are:
locate the test point
compute the distances between the test point and all points in the training set
find $k$
shortest
distances and the corresponding training set points
vote for the result (find the maximum in the table for the true classifications)
As there are four steps in an iteration, the total number of animation frames
should be 4 * min(nrow(test), ani.options('nmax'))
at last.
A vector of class labels for the test set.
There is a special restriction (only two columns) on the training and
test data set just for sake of the convenience for making a scatterplot.
This is only a rough demonstration; for practical applications, please
refer to existing kNN functions such as knn
in
class, etc.
If either one of train
and test
is missing, there'll be
random matrices prepared for them. (It's the same for cl
.)
Yihui Xie
Examples at https://yihui.org/animation/example/knnani/
Venables, W. N. and Ripley, B. D. (2002) Modern Applied Statistics with S. Fourth edition. Springer.
This is a simple demonstration of the meaning of least squares in univariate linear regression.
least.squares( x, y, n = 15, ani.type = c("slope", "intercept"), a, b, a.range, b.range, ab.col = c("gray", "black"), est.pch = 19, v.col = "red", v.lty = 2, rss.pch = 19, rss.type = "o", mfrow = c(1, 2), ... )
least.squares( x, y, n = 15, ani.type = c("slope", "intercept"), a, b, a.range, b.range, ab.col = c("gray", "black"), est.pch = 19, v.col = "red", v.lty = 2, rss.pch = 19, rss.type = "o", mfrow = c(1, 2), ... )
x 
a numeric vector: the independent variable 
y 
a numeric vector: the dependent variable 
n 
the sample size: when x and y are missing, we use simulated values
of y ( 
ani.type 

a , b

the fixed intercept and slope; depending on 
a.range , b.range

a vector of length 2 to define the range of the intercept and the slope; only one of them need to be specified; see above 
ab.col 
the colors of two lines: the real regression line and the moving line with either intercept or slope changing 
est.pch 
the point character of the 'estimated' values given 
v.col , v.lty

the color and line type of the vetical lines which demonstrate the residuals 
rss.pch , rss.type

the point character and plot type of the residual plot 
mfrow 
defines the layout of the graph; see 
... 
other parameters passed to 
With either the intercept or the slope changing, the lines will be moving in the graph and corresponding residuals will be plotted. We can finally see the best estimate of the intercept and the slope from the residual plot.
The value returned depends on the animation type.
If it is a slope animation, the value will be a list containing
lmfit 
the estimates of the intercept and slope with

anifit 
the estimate of the slope in the animation 
If it is an intercept animation, the second component of the above list will be the estimate of the intercept.
Note the estimate will not be precise generally.
ani.options('nmax')
specifies the maximum number of steps for
the slope or intercept to move.
Yihui Xie
Examples at https://yihui.org/animation/example/leastsquares/
This function plots the sample mean as the sample size grows to check whether the sample mean approaches to the population mean.
lln.ani( FUN = rnorm, mu = 0, np = 30, pch = 20, col.poly = "bisque", col.mu = "gray", ... )
lln.ani( FUN = rnorm, mu = 0, np = 30, pch = 20, col.poly = "bisque", col.mu = "gray", ... )
FUN 
a function to generate random numbers from a certain distribution:

mu 
population mean; passed to 
np 
times for sampling from a distribution (not the sample size!); to examine the behaviour of the sample mean, we need more times of sampling to get a series of mean values 
pch 
symbols for points; see Details 
col.poly 
the color of the polygon to annotate the range of sample means 
col.mu 
the color of the horizontal line which denotes the population mean 
... 
other arguments passed to 
np
points are plotted to denote the distribution of the sample mean;
we will observe that the range of the sample mean just becomes smaller and
smaller as the sample size increases and ultimately there will be an obvious
trend that the sample mean converges to the population mean mu
.
The parameter nmax
in ani.options
means the maximum
sample size.
None (invisible NULL
).
The argument pch
will influence the speed of plotting, and for a
very large sample size (say, 300), it is suggested that this argument be
specified as '.
'.
Yihui Xie
Examples at https://yihui.org/animation/example/llnani/
Integrate a function using the HitorMiss Monte Carlo algorithm.
MC.hitormiss( FUN = function(x) x  x^2, n = ani.options("nmax"), from = 0, to = 1, col.points = c("black", "red"), pch.points = c(20, 4), ... )
MC.hitormiss( FUN = function(x) x  x^2, n = ani.options("nmax"), from = 0, to = 1, col.points = c("black", "red"), pch.points = c(20, 4), ... )
FUN 
the function to be integrated 
n 
number of points to be sampled from the Uniform(0, 1) distribution 
from , to

the limits of integration 
col.points , pch.points

colors and point characters for points which “hit” or “miss” the area under the curve 
... 
other arguments passed to 
We compute the proportion of points hitting the area under the curve, and the integral can be estimated by the proportion multiplied by the total area of the rectangle (from xmin to xmax, ymin to ymax).
A list containing
x1 
the Uniform random numbers generated on xaxis 
x2 
the Uniform random numbers generated on yaxis 
y 
function values evaluated at 
n 
number of points drawn from the Uniform distribtion 
est 
the estimated value of the integral 
This function is for demonstration purpose only; the integral might be
very inaccurate when n
is small.
ani.options('nmax')
specifies the maximum number of trials.
Yihui Xie
Examples at https://yihui.org/animation/example/mchitormiss/
Integrate a function from 0 to 1 using the Sample Mean Monte Carlo algorithm
MC.samplemean( FUN = function(x) x  x^2, n = ani.options("nmax"), col.rect = c("gray", "black"), adj.x = TRUE, ... )
MC.samplemean( FUN = function(x) x  x^2, n = ani.options("nmax"), col.rect = c("gray", "black"), adj.x = TRUE, ... )
FUN 
the function to be integrated 
n 
number of points to be sampled from the Uniform(0, 1) distribution 
col.rect 
colors of rectangles (for the past rectangles and the current one) 
adj.x 
should the locations of rectangles on the xaxis be adjusted?
If 
... 
other arguments passed to 
Sample Mean Monte Carlo integration can compute
$I=\int_0^1 f(x) dx$
by drawing random numbers $x_i$
from Uniform(0, 1) distribution and
average the values of $f(x_i)$
. As $n$
goes to infinity, the sample
mean will approach to the expectation of $f(X)$
by Law of Large Numbers.
The height of the $i$
th rectangle in the animation is $f(x_i)$
and
the width is $1/n$
, so the total area of all the rectangles is $\sum
f(x_i) 1/n$
, which is just the sample mean. We can compare the area of
rectangles to the curve to see how close is the area to the real integral.
A list containing
x 
the Uniform random numbers 
y 
function values evaluated at 
n 
number of points drawn from the Uniform distribtion 
est 
the estimated value of the integral 
This function is for demonstration purpose only; the integral might be
very inaccurate when n
is small.
ani.options('nmax')
specifies the maximum number of trials.
Yihui Xie
Examples at https://yihui.org/animation/example/mcsamplemean/
For a long numeric vector or matrix (or data frame), we can plot only a
subset of its elements to take a closer look at its structure. With a moving
“block” from the beginning to the end of a vector or matrix or any R
objects to which we can apply subset
, all elements inside the block
are plotted as a line or scatter plot or any customized plots.
moving.block(dat = runif(100), block, FUN, ...)
moving.block(dat = runif(100), block, FUN, ...)
dat 
a numeric vector or twocolumn matrix 
block 
block length (i.e. how many elements are to be plotted in each step) 
FUN 
a plot function to be applied to the subset of data 
... 
other arguments passed to 
For a vector, the elments from i + 1
to i + block
will be
plotted in the ith step; similarly for a matrix or data frame, a (scatter)
plot will be created from the i + 1
th row to i + block
th row.
However, this function is not limited to scatter plots or lines – we can
customize the function FUN
as we wish.
NULL
There will be ani.options('nmax')
image frames created in the
end. Ideally the relationship between ani.options('nmax')
and
block
should follow this equality: block = length(x) 
ani.options('nmax') + 1
(replace length(x)
with nrow(x)
when
x
is a matrix). The function will compute block
according to
the equality by default if no block length is specified.
The three arguments dat
, i
and block
are passed to
FUN
in case we want to customize the plotting function, e.g. we may
want to annonate the xaxis label with i
, or we want to compute the
mean value of dat[i + 1:block]
, etc. See the examples below to learn
more about how to make use of these three arguments.
Yihui Xie
Examples at https://yihui.org/animation/example/movingblock/
This function just fulfills a very naive idea about moving window regression using rectangles to denote the “windows” and move them, and the corresponding AR(1) coefficients as long as rough confidence intervals are computed for data points inside the “windows” during the process of moving.
mwar.ani( x, k = 15, conf = 2, mat = matrix(1:2, 2), widths = rep(1, ncol(mat)), heights = rep(1, nrow(mat)), lty.rect = 2, ... )
mwar.ani( x, k = 15, conf = 2, mat = matrix(1:2, 2), widths = rep(1, ncol(mat)), heights = rep(1, nrow(mat)), lty.rect = 2, ... )
x 
univariate timeseries (a single numerical vector); default to be

k 
an integer of the window width 
conf 
a positive number: the confidence intervals are computed as

mat , widths , heights

arguments passed to 
lty.rect 
the line type of the rectangles respresenting the moving “windows” 
... 
other arguments passed to 
The AR(1) coefficients are computed by arima
.
A list containing
phi 
the AR(1) coefficients 
L 
lower bound of the confidence interval 
U 
upper bound of the confidence interval 
Yihui Xie
Examples at https://yihui.org/animation/example/mwarani/
Robert A. Meyer, Jr. Estimating coefficients that change over time. International Economic Review, 13(3):705710, 1972.
This function provides an illustration of the iterations in Newton's method.
newton.method( FUN = function(x) x^2  4, init = 10, rg = c(1, 10), tol = 0.001, interact = FALSE, col.lp = c("blue", "red", "red"), main, xlab, ylab, ... )
newton.method( FUN = function(x) x^2  4, init = 10, rg = c(1, 10), tol = 0.001, interact = FALSE, col.lp = c("blue", "red", "red"), main, xlab, ylab, ... )
FUN 
the function in the equation to solve (univariate), which has to be defined without braces like the default one (otherwise the derivative cannot be computed) 
init 
the starting point 
rg 
the range for plotting the curve 
tol 
the desired accuracy (convergence tolerance) 
interact 
logical; whether choose the starting point by cliking on the curve (for 1 time) directly? 
col.lp 
a vector of length 3 specifying the colors of: vertical lines, tangent lines and points 
main , xlab , ylab

titles of the plot; there are default values for them
(depending on the form of the function 
... 
other arguments passed to 
Newton's method (also known as the NewtonRaphson method or the NewtonFourier method) is an efficient algorithm for finding approximations to the zeros (or roots) of a realvalued function f(x).
The iteration goes on in this way:
$x_{k + 1} = x_{k}  \frac{FUN(x_{k})}{FUN'(x_{k})}$
From the starting value $x_0$
, vertical lines and points are plotted to
show the location of the sequence of iteration values $x_1, x_2,
\ldots$
; tangent lines are drawn to illustrate the
relationship between successive iterations; the iteration values are in the
right margin of the plot.
A list containing
root 
the root found by the algorithm 
value 
the value of 
iter 
number of
iterations; if it is equal to 
The algorithm might not converge – it depends on the starting value. See the examples below.
Yihui Xie
Examples at https://yihui.org/animation/example/newtonmethod/
For more information about Newton's method, please see https://en.wikipedia.org/wiki/Newton's_method
This data recorded the number of words in each paragraph of Barack Obama's speech in Chicago after winning the presidential election.
int [1:59] 2 45 52 53 11 48 28 15 50 29 ...
The full text of speech is at http://web.archive.org/web/20160306143403/http://www.baltimoresun.com/news/nationworld/baltext1105story.html
## pattern: longer paragraph and shorter paragraph plot(ObamaSpeech, type = "b", pch = 20, xlab = "paragraph index", ylab = "word count")
## pattern: longer paragraph and shorter paragraph plot(ObamaSpeech, type = "b", pch = 20, xlab = "paragraph index", ylab = "word count")
The data is collected by Awstats for the website http://yihui.org.
A data frame with 73 observations on the following 5 variables.
Date starts from Sep 21, 2007 to Dec 2, 2007.
number of visits: a new visit is defined as each new incoming visitor (viewing or browsing a page) who was not connected to the site during last 60 min.
number of times a page of the site is viewed (sum for all visitors for all visits). This piece of data differs from “files” in that it counts only HTML pages and excludes images and other files.
number of times a page, image, file of the site is viewed or downloaded by someone.
amount of data downloaded by all pages, images and files within the site (units in MegaBytes).
plot(pageview[, 1:2], type = "b", col = "red", main = "Number of Visits in Yihui's Web") ## partial autocorrelation pacf(pageview$visits)
plot(pageview[, 1:2], type = "b", col = "red", main = "Number of Visits in Yihui's Web") ## partial autocorrelation pacf(pageview$visits)
If the toolkit Pdftk is available in the system, it will be called to manipulate the PDF files (especially to compress the PDF files).
pdftk(input, operation = NULL, output, other.opts = "compress dont_ask")
pdftk(input, operation = NULL, output, other.opts = "compress dont_ask")
input 
the path of the input PDF file(s) 
operation 
the operation to be done on the input (default to be

output 
the path of the output (if missing and 
other.opts 
other options (default to be 
This is a wrapper to call pdftk
. The path of pdftk
should
be set via ani.options(pdftk = 'path/to/pdftk')
.
See the reference for detailed usage of pdftk
.
if ani.options('pdftk')
is nonNULL
, then this function
returns the status of the operation (0
for success; see
system
); otherwise a warning will be issued
Yihui Xie
Examples at https://yihui.org/animation/example/pdftk/
pdftk official website https://www.pdflabs.com/tools/pdftkthepdftoolkit/
There are 3848 observations on 5 variables. From the 1986 ASA Data Exposition dataset, made up by David Coleman of RCA Labs
A data frame with 3848 observations on the following 5 variables.
a numeric vector
a numeric vector
a numeric vector
a numeric vector
a numeric vector
collected from Statlib Datasets Archive: http://lib.stat.cmu.edu/dataexpo/
## some dense points in the center? plot(pollen[, 1:2], pch = 20, col = rgb(0, 0, 0, 0.1)) ## see demo('pollen', package = 'animation') for a 3D demo; truth is there!
## some dense points in the center? plot(pollen[, 1:2], pch = 20, col = rgb(0, 0, 0, 0.1)) ## see demo('pollen', package = 'animation') for a 3D demo; truth is there!
This function can display the frequencies of stock prices in a certain time span with the span changing.
price.ani( price, time, time.begin = min(time), span = 15 * 60, ..., xlab = "price", ylab = "frequency", xlim, ylim, main )
price.ani( price, time, time.begin = min(time), span = 15 * 60, ..., xlab = "price", ylab = "frequency", xlim, ylim, main )
price 
stock prices 
time 
time corresponding to prices 
time.begin 
the time for the animation to begin (default to be the
minimum 
span 
time span (unit in seconds; default to be 15 minutes) 
... 
other arguments passed to 
xlab , ylab , xlim , ylim , main

they are passed to 
invisible NULL
Yihui Xie
Examples at https://yihui.org/animation/example/priceani/
If the tool qpdf is available in the system, it will be called to manipulate the PDF files (especially to compress the PDF files).
qpdf(input, output, options = "streamdata=compress")
qpdf(input, output, options = "streamdata=compress")
input 
the path of the input PDF file 
output 
the path of the output (if missing, 
options 
options for 
This is a wrapper to call qpdf
. The path of qpdf
should
be set via ani.options(qpdf = 'path/to/qpdf')
.
See the reference for detailed usage of qpdf
.
if ani.options('qpdf')
is nonNULL
, then this function
returns the status of the operation (0
for success; see
system
); otherwise a warning will be issued
Yihui Xie
Examples at https://yihui.org/animation/example/qpdf/
qpdf official website https://qpdf.sourceforge.io/
Simulates the quincunx with “balls” (beans) falling through several layers
(denoted by triangles) and the distribution of the final locations at which
the balls hit is denoted by a histogram; quincunx()
is shows single
layer, and quincunx2()
is a twostage version of the quincunx.
quincunx( balls = 200, layers = 15, pch.layers = 2, pch.balls = 19, col.balls = sample(colors(), balls, TRUE), cex.balls = 2 ) quincunx2( balls = 200, layers = 15, pch.layers = 2, pch.balls = 19, col.balls = sample(colors(), balls, TRUE), cex.balls = 2 )
quincunx( balls = 200, layers = 15, pch.layers = 2, pch.balls = 19, col.balls = sample(colors(), balls, TRUE), cex.balls = 2 ) quincunx2( balls = 200, layers = 15, pch.layers = 2, pch.balls = 19, col.balls = sample(colors(), balls, TRUE), cex.balls = 2 )
balls 
number of balls 
layers 
number of layers 
pch.layers 
point character of layers; triangles ( 
pch.balls , col.balls , cex.balls

point character, colors and magnification of balls 
The bean machine, also known as the quincunx or Galton box, is a device invented by Sir Francis Galton to demonstrate the law of error and the normal distribution.
When a ball falls through a layer, it can either go to the right or left side with the probability 0.5. At last the location of all the balls will show us the bellshaped distribution.
A named vector: the frequency table for the locations of the balls. Note the names of the vector are the locations: 1.5, 2.5, ..., layers  0.5.
The maximum number of animation frames is controlled by
ani.options('nmax')
as usual, but it is strongly recommended that
ani.options(nmax = balls + layers 2)
, in which case all the balls
will just fall through all the layers and there will be no redundant
animation frames.
Yihui Xie, Lijia Yu, and Keith ORourke
Examples at https://yihui.org/animation/example/quincunx/
In Hans Rosling's attractive talk “Debunking thirdworld myths with the best
stats you've ever seen”, he used a lot of bubble plots to illustrate trends
behind the data over time. This function gives an imitation of those moving
bubbles, besides, as this function is based on symbols
, we can
also make use of other symbols such as squares, rectangles, thermometers,
etc.
Rosling.bubbles( x, y, data, type = c("circles", "squares", "rectangles", "stars", "thermometers", "boxplots"), bg, xlim = range(x), ylim = range(y), main = NULL, xlab = "x", ylab = "y", ..., grid = TRUE, text = 1:ani.options("nmax"), text.col = rgb(0, 0, 0, 0.5), text.cex = 5 )
Rosling.bubbles( x, y, data, type = c("circles", "squares", "rectangles", "stars", "thermometers", "boxplots"), bg, xlim = range(x), ylim = range(y), main = NULL, xlab = "x", ylab = "y", ..., grid = TRUE, text = 1:ani.options("nmax"), text.col = rgb(0, 0, 0, 0.5), text.cex = 5 )
x , y

the x and y coordinates for the centres of the bubbles (symbols).
Default to be 10 uniform random numbers in [0, 1] for each single image
frame (so the length should be 10 * 
type , data

the type and data for symbols; see 
bg , main , xlim , ylim , xlab , ylab , ...

see 
grid 
logical; add a grid to the plot? 
text 
a character vector to be added to the plot one by one (e.g. the year in Rosling's talk) 
text.col , text.cex

color and magnification of the background text 
Suppose we have observations of $n$
individuals over
ani.options('nmax')
years. In this animation, the data of each year
will be shown in the bubbles (symbols) plot; as time goes on, certain trends
will be revealed (like those in Rosling's talk). Please note that the
arrangement of the data for bubbles (symbols) should be a matrix like
$A_{ijk}$
in which $i$
is the individual id (from 1 to n), $j$
denotes the $j$
th variable (from 1 to p) and $k$
indicates the time
from 1 to ani.options('nmax')
.
And the length of x
and y
should be equal to the number of rows
of this matrix.
NULL
.
Yihui Xie
Examples at https://yihui.org/animation/example/roslingbubbles/
TED talk: https://www.ted.com/talks/hans_rosling_the_best_stats_you_ve_ever_seen
Each rectangle stands for a cluster, and the simple random sampling without replacement is performed for each cluster. All points in the clusters being sampled will be drawn out.
sample.cluster( pop = ceiling(10 * runif(10, 0.2, 1)), size = 3, p.col = c("blue", "red"), p.cex = c(1, 3), ... )
sample.cluster( pop = ceiling(10 * runif(10, 0.2, 1)), size = 3, p.col = c("blue", "red"), p.cex = c(1, 3), ... )
pop 
a vector for the size of each cluster in the population. 
size 
the number of clusters to be drawn out. 
p.col , p.cex

different colors / magnification rate to annotate the population and the sample 
... 
other arguments passed to 
None (invisible NULL
).
Yihui Xie
Examples at https://yihui.org/animation/example/samplecluster/
sample
, sample.simple
,
sample.ratio
, sample.strat
,
sample.system
This function demonstrates the advantage of ratio estimation when further information (ratio) about x and y is available.
sample.ratio( X = runif(50, 0, 5), R = 1, Y = R * X + rnorm(X), size = length(X)/2, p.col = c("blue", "red"), p.cex = c(1, 3), p.pch = c(20, 21), m.col = c("black", "gray"), legend.loc = "topleft", ... )
sample.ratio( X = runif(50, 0, 5), R = 1, Y = R * X + rnorm(X), size = length(X)/2, p.col = c("blue", "red"), p.cex = c(1, 3), p.pch = c(20, 21), m.col = c("black", "gray"), legend.loc = "topleft", ... )
X 
the X variable (ancillary) 
R 
the population ratio Y/X 
Y 
the Y variable (whose mean we what to estimate) 
size 
sample size 
p.col , p.cex , p.pch

point colors, magnification and symbols for the population and sample respectively 
m.col 
color for the horizontal line to denote the sample mean of Y 
legend.loc 
legend location: topleft, topright, bottomleft,
bottomright, ... (see 
... 
other arguments passed to 
From this demonstration we can clearly see that the ratio estimation is generally better than the simple sample average when the ratio R really exists, otherwise ratio estimation may not help.
A list containing
X 
X population 
Y 
Y population 
R 
population ratio 
r 
ratio calculated from samples 
Ybar 
population mean of Y 
ybar.simple 
simple sample mean of Y 
ybar.ratio 
sample mean of Y via ratio estimation 
Yihui Xie
Examples at https://yihui.org/animation/example/sampleratio/
sample
, sample.simple
,
sample.cluster
, sample.strat
,
sample.system
The whole sample frame is denoted by a matrix (nrow * ncol
) in the
plane just for convenience, and the points being sampled are marked out (by
red circles by default). Each member of the population has an equal and known
chance of being selected.
sample.simple( nrow = 10, ncol = 10, size = 15, p.col = c("blue", "red"), p.cex = c(1, 3) )
sample.simple( nrow = 10, ncol = 10, size = 15, p.col = c("blue", "red"), p.cex = c(1, 3) )
nrow 
the desired number of rows of the sample frame. 
ncol 
the desired number of columns of the sample frame. 
size 
the sample size. 
p.col , p.cex

different colors /magnification rate to annotate the population and the sample 
None (invisible NULL
).
Yihui Xie
Examples at https://yihui.org/animation/example/samplesimple/
sample
, sample.ratio
,
sample.cluster
, sample.strat
,
sample.system
Each rectangle stands for a stratum, and the simple random sampling without replacement is performed within each stratum. The points being sampled are marked out (by red circles by default).
sample.strat( pop = ceiling(10 * runif(10, 0.5, 1)), size = ceiling(pop * runif(length(pop), 0, 0.5)), p.col = c("blue", "red"), p.cex = c(1, 3), ... )
sample.strat( pop = ceiling(10 * runif(10, 0.5, 1)), size = ceiling(pop * runif(length(pop), 0, 0.5)), p.col = c("blue", "red"), p.cex = c(1, 3), ... )
pop 
a vector for the size of each stratum in the population. 
size 
a corresponding vector for the sample size in each stratum (recycled if necessary). 
p.col , p.cex

different colors /magnification rate to annotate the population and the sample 
... 
other arguments passed to 
None (invisible 'NULL
').
Yihui Xie
Examples at https://yihui.org/animation/example/samplestrat/
sample
, sample.simple
,
sample.cluster
, sample.ratio
,
sample.system
The whole sample frame is denoted by a matrix (nrow * ncol
) in the
plane, and the sample points with equal intervals are drawn out according to
a random starting point. The points being sampled are marked by red circles.
sample.system( nrow = 10, ncol = 10, size = 15, p.col = c("blue", "red"), p.cex = c(1, 3) )
sample.system( nrow = 10, ncol = 10, size = 15, p.col = c("blue", "red"), p.cex = c(1, 3) )
nrow 
the desired number of rows of the sample frame. 
ncol 
the desired number of columns of the sample frame. 
size 
the sample size. 
p.col , p.cex

different colors / magnification rate to annotate the population and the sample 
None (invisible NULL
).
Yihui Xie
Examples at https://yihui.org/animation/example/samplesystem/
sample
, sample.simple
,
sample.cluster
, sample.ratio
,
sample.strat
This function opens a graphical device (specified in
ani.options('ani.dev')
) first to generate a sequence of images based
on expr
, then makes use of the command convert
in
‘ImageMagick’ to convert these images to a single animated movie (as a GIF or
MPG file). An alternative software package is GraphicsMagick (use
convert = 'gm convert'
), which is smaller than ImageMagick.
saveGIF( expr, movie.name = "animation.gif", img.name = "Rplot", convert = "magick", cmd.fun, clean = TRUE, extra.opts = "", ... ) saveMovie( expr, movie.name = "animation.gif", img.name = "Rplot", convert = "magick", cmd.fun, clean = TRUE, extra.opts = "", ... )
saveGIF( expr, movie.name = "animation.gif", img.name = "Rplot", convert = "magick", cmd.fun, clean = TRUE, extra.opts = "", ... ) saveMovie( expr, movie.name = "animation.gif", img.name = "Rplot", convert = "magick", cmd.fun, clean = TRUE, extra.opts = "", ... )
expr 
an expression to generate animations; use either the animation
functions (e.g. 
movie.name 
file name of the movie (with the extension) 
img.name 
file name of the sequence of images (‘pure’ name; without any format or extension) 
convert 
the command to convert images (default to be 
cmd.fun 
a function to invoke the OS command; by default

clean 
whether to delete the individual image frames 
extra.opts 
additional options passed to 
... 
other arguments passed to 
This function calls im.convert
(or gm.convert
,
depending on the argument convert
) to convert images to a single
animation.
The advantage of this function is that it can create a single movie file,
however, there are two problems too: (1) we need a special (free) software
ImageMagick or GraphicsMagick; (2) the speed of the animation will be beyond
our control, as the interval
option is fixed. Other approaches in this
package may have greater flexibilities, e.g. the HTML approach (see
saveHTML
).
See ani.options
for the options that may affect the output,
e.g. the graphics device (including the height/width specifications), the
file extension of image frames, and the time interval between image frames,
etc. Note that ani.options('interval')
can be a numeric vector!
The command for the conversion (see im.convert
).
See im.convert
for details on the configuration of
ImageMagick (typically for Windows users) or GraphicsMagick.
It is recommended to use ani.pause()
to pause between animation
frames in expr
, because this function will only pause when called in
a noninteractive graphics device, which can save a lot of time. See the
demo 'Xmas2'
for example (demo('Xmas2', package =
'animation')
).
saveGIF
has an alias saveMovie
(i.e. they are
identical); the latter name is for compatibility to older versions of this
package (< 2.02). It is recommended to use saveGIF
to avoid
confusions between saveMovie
and saveVideo
.
Yihui Xie
Examples at https://yihui.org/animation/example/savegif/
ImageMagick: http://www.imagemagick.org/script/convert.php;
GraphicsMagick: http://www.graphicsmagick.org
Other utilities:
im.convert()
,
saveHTML()
,
saveLatex()
,
saveSWF()
,
saveVideo()
This function first records all the plots in the R expression as bitmap images, then inserts them into an HTML page and finally creates the animation using the SciAnimator library.
saveHTML( expr, img.name = "Rplot", global.opts = "", single.opts = "", navigator = ani.options("nmax") <= 100 && ani.options("interval") >= 0.05, htmlfile = "index.html", ... )
saveHTML( expr, img.name = "Rplot", global.opts = "", single.opts = "", navigator = ani.options("nmax") <= 100 && ani.options("interval") >= 0.05, htmlfile = "index.html", ... )
expr 
an R expression to be evaluated to create a sequence of images 
img.name 
the filename of the images (the real output will be like
‘img.name1.png’, ‘img.name2.png’, ...); this name has to be
different for different animations, since it will be used as the
identifiers for each animation; make it as unique as possible; meanwhile,
the following characters in

global.opts 
a string: the global options of the animation; e.g. we can
specify the default theme to be blue using

single.opts 
the options for each single animation (if there are multiple ones in one HTML page), e.g. to use the dark theme and text labels for buttons:
or to remove the navigator panel (the navigator can affect the smoothness
of the animation when the playing speed is extremely fast (e.g.
see the reference for a complete list of available options 
navigator 
whether to show the navigator (like a progress bar); by default, the navigator is not shown for performance reasons when the number of images is greater than 100 or the time interval is smaller than 0.05 
htmlfile 
the filename of the HTML file 
... 
other arguments to be passed to 
It mainly uses the SciAnimator library, which is based on jQuery. It has a neat interface (both technically and visually) and is much easier to use or extend. Moreover, this function allows multiple animations in a single HTML page – just use the same HTML filename.
Optionally the source code and some session information can be added below
the animations for the sake of reproducibility (specified by the option
ani.options('verbose')
– if TRUE
, the description, loaded
packages, the code to produce the animation, as well as a part of
sessionInfo()
will be written in the bottom of the animation;
the R code will be highlighted using the SyntaxHighlighter library for better
reading experience).
The path of the HTML output.
Microsoft IE might restrict the HTML page from running JavaScript and try to “protect your security” when you view the animation page, but this is not really a security problem.
When you want to publish the HTML page on the web, you have to upload the associated ‘css’ and ‘js’ folders with the HTML file as well as the images.
For saveHTML
, ani.options('description')
can be a
character vector, in which case this vector will be pasted into a scalar;
use '\n\n'
in the string to separate paragraphs (see the first
example below).
For the users who do not have R at hand, there is a demo in
system.file('misc', 'Rweb', 'demo.html', package = 'animation')
to
show how to create animations online without R being installed locally. It
depends, however, on whether the Rweb service can be provided for public
use in a long period (currently we are using the Rweb at Tama University).
See the last example below.
Yihui Xie
Examples at https://yihui.org/animation/example/savehtml/
scianimator official website https://github.com/brentertz/scianimator
Other utilities:
im.convert()
,
saveGIF()
,
saveLatex()
,
saveSWF()
,
saveVideo()
Record animation frames and insert them into a LaTeX document with the
animate
package. Compile the document if an appropriate LaTeX command
is provided.
saveLatex( expr, nmax, img.name = "Rplot", ani.opts, centering = TRUE, caption = NULL, label = NULL, pkg.opts = NULL, documentclass = "article", latex.filename = "animation.tex", pdflatex = "pdflatex", install.animate = TRUE, overwrite = TRUE, full.path = FALSE, ... )
saveLatex( expr, nmax, img.name = "Rplot", ani.opts, centering = TRUE, caption = NULL, label = NULL, pkg.opts = NULL, documentclass = "article", latex.filename = "animation.tex", pdflatex = "pdflatex", install.animate = TRUE, overwrite = TRUE, full.path = FALSE, ... )
expr 
an expression to generate animations; use either the animation
functions (e.g. 
nmax 
maximum number of animation frames (if missing and the graphics
device is a bitmap device, this number will be automatically calculated);
note that we do not have to specify 
img.name 
basename of file names of animation frames; see the Note
section for a possible adjustment on 
ani.opts 
options to control the behavior of the animation (passed to
the LaTeX macro 
centering 
logical: whether to center the graph using the LaTeX
environment 
caption , label

caption and label for the graphics in the figure environment 
pkg.opts 
global options for the 
documentclass 
LaTeX document class; if 
latex.filename 
file name of the LaTeX document; if an empty string

pdflatex 
the command for pdfLaTeX (set to 
install.animate 
copy the LaTeX style files ‘animate.sty’ and
‘animfp.sty’? If you have not installed the LaTeX package

overwrite 
whether to overwrite the existing image frames 
full.path 
whether to use the full path ( 
... 
other arguments passed to the graphics device

This is actually a wrapper to generate a LaTeX document using R. The document
uses the LaTeX package called animate
to insert animations into PDF's.
When we pass an R expression to this function, the expression will be
evaluated and recorded by a grahpics device (typically png
and
pdf
). At last, a LaTeX document will be created and compiled if
an appropriate LaTeX command is provided. And the final PDF output will be
opened with the PDF viewer set in getOption('pdfviewer')
if
ani.options('autobrowse') == TRUE
.
Invisible NULL
This function will detect if it was called in a Sweave environment –
if so, img.name
will be automatically adjusted to
prefix.stringlabel
, and the LaTeX output will not be a complete
document, but rather a single line like
\animategraphics[ani.opts]{1/interval}{img.name}{}{}
This automatic feature can be useful to Sweave users (but remember to set
the Sweave option results=tex
). See demo('Sweave_animation')
for a complete example.
PDF devices are recommended because of their high quality and usually they
are more friendly to LaTeX, but the size of PDF files is often much larger;
in this case, we may set the option 'qpdf'
or 'pdftk'
to
compress the PDF graphics output. To set the PDF device, use
ani.options(ani.dev = 'pdf', ani.type = 'pdf')
So far animations created by the LaTeX package animate can only be
viewed with Acrobat Reader (Windows) or acroread
(Linux). Other
PDF viewers may not support JavaScript (in fact the PDF animation is driven
by JavaScript). Linux users may need to install acroread
and set
options(pdfviewer = 'acroread')
.
Yihui Xie
Examples at https://yihui.org/animation/example/savelatex/
To know more about the animate
package, please refer to
http://www.ctan.org/texarchive/macros/latex/contrib/animate/. There
are a lot of options can be set in ani.opts
and pkg.opts
.
Other utilities:
im.convert()
,
saveGIF()
,
saveHTML()
,
saveSWF()
,
saveVideo()
This function opens a graphical device first to generate a sequence of images
based on expr
, then makes use of the commands in SWFTools
(png2swf
, jpeg2swf
, pdf2swf
) to convert these
images to a single Flash animation.
saveSWF( expr, swf.name = "animation.swf", img.name = "Rplot", swftools = NULL, ... )
saveSWF( expr, swf.name = "animation.swf", img.name = "Rplot", swftools = NULL, ... )
expr 
an expression to generate animations; use either the animation
functions (e.g. 
swf.name 
file name of the Flash file 
img.name 
the base file name of the sequence of images (without any format or extension) 
swftools 
the path of SWFTools, e.g. ‘C:/swftools’. This argument
is to make sure that 
... 
other arguments passed to 
An integer indicating failure (1) or success (0) of the converting
(refer to system
).
Please download and install the SWFTools before using this function: http://www.swftools.org
We can also set the path to SWF Tools by ani.options(swftools =
'path/to/swftools')
.
ani.options('ani.type')
can only be one of png
, pdf
and jpeg
.
Also note that PDF graphics can be compressed using qpdf or Pdftk (if
either one is installed and ani.options('qpdf')
or
ani.options('pdftk')
has been set); see qpdf
or
pdftk
.
Yihui Xie
Examples at https://yihui.org/animation/example/saveswf/
Other utilities:
im.convert()
,
saveGIF()
,
saveHTML()
,
saveLatex()
,
saveVideo()
This function opens a graphics device to record the images produced in the
code expr
, then uses FFmpeg to convert these images to a video.
saveVideo( expr, video.name = "animation.mp4", img.name = "Rplot", ffmpeg = ani.options("ffmpeg"), other.opts = if (grepl("[.]mp4$", video.name)) "pix_fmt yuv420p", ... )
saveVideo( expr, video.name = "animation.mp4", img.name = "Rplot", ffmpeg = ani.options("ffmpeg"), other.opts = if (grepl("[.]mp4$", video.name)) "pix_fmt yuv420p", ... )
expr 
the R code to draw (several) plots 
video.name 
the file name of the output video (e.g. ‘animation.mp4’ or ‘animation.avi’) 
img.name 
the file name of the sequence of images to be generated 
ffmpeg 
the command to call FFmpeg (e.g.

other.opts 
other options to be passed to 
... 
other arguments to be passed to 
This function uses system
to call FFmpeg to convert the images
to a single video. The command line used in this function is: ffmpeg
y r <1/interval> i <img.name>%d.<ani.type> other.opts video.name
where interval
comes from ani.options('interval')
, and
ani.type
is from ani.options('ani.type')
. For more details on
the numerous options of FFmpeg, please see the reference.
Some linux systems may use the alternate software 'avconv' instead of 'ffmpeg'. The package will attempt to determine which command is present and set ani.options('ffmpeg')
to an appropriate default value. This can be overridden by passing in the ffmpeg
argument.
An integer indicating failure (1) or success (0) of the converting
(refer to system
).
There are a lot of possibilities in optimizing the video. My knowledge on FFmpeg is very limited, hence the default output by this function could be of low quality or too large. The file ‘presets.xml’ of WinFF might be a good guide: https://code.google.com/archive/p/winff.
Yihui Xie, based on an inital version by Thomas Julou [email protected]
Examples at https://yihui.org/animation/example/savevideo/
To know more about ffmpeg, please see http://ffmpeg.org/documentation.html
Other utilities:
im.convert()
,
saveGIF()
,
saveHTML()
,
saveLatex()
,
saveSWF()
This demo shows the possible QQ plots created by random numbers generated from a Normal distribution so that users can get a rough idea about how QQ plots really look like.
sim.qqnorm(n = 20, last.plot = NULL, ...)
sim.qqnorm(n = 20, last.plot = NULL, ...)
n 
integer: sample size 
last.plot 
an expression to be evaluated after the plot is drawn, e.g.

... 
other arguments passed to 
When the sample size is small, it is hard to get a correct inference about the distribution of data from a QQ plot. Even if the sample size is large, usually there are outliers far away from the straight line. Therefore, don't overinterpret the QQ plots.
NULL
Yihui Xie
Examples at https://yihui.org/animation/example/simqqnorm/
This is a sample of stock prices of the Vanke Co., Ltd on 2009/11/27.
A data frame with 2831 observations on the following 2 variables.
POSIXt: the time corresponding to stock prices
a numeric vector: stock prices
This data can be obtained from most stock websites.
The two most common types of grid illusions are Hermann grid illusions and Scintillating grid illusions. This function provides illustrations for both illusions.
vi.grid.illusion( nrow = 8, ncol = 8, lwd = 8, cex = 3, col = "darkgray", type = c("s", "h") )
vi.grid.illusion( nrow = 8, ncol = 8, lwd = 8, cex = 3, col = "darkgray", type = c("s", "h") )
nrow 
number of rows for the grid 
ncol 
number of columns for the grid 
lwd 
line width for grid lines 
cex 
magnification for points in Scintillating grid illusions 
col 
color for grid lines 
type 
type of illusions: 
A grid illusion is any kind of grid that deceives a person's vision.
This is actually a static image; pay attention to the intersections of the grid and there seems to be some moving points (nonexistent in fact).
NULL
Yihui Xie
## default to be Scintillating grid illusions vi.grid.illusion() ## set wider lines to see Hermann grid illusions vi.grid.illusion(type = "h", lwd = 22, nrow = 5, ncol = 5, col = "white")
## default to be Scintillating grid illusions vi.grid.illusion() ## set wider lines to see Hermann grid illusions vi.grid.illusion(type = "h", lwd = 22, nrow = 5, ncol = 5, col = "white")
Stare at the center cross for a few (say 30) seconds to experience the phenomena of the illusion.
vi.lilac.chaser(np = 16, col = "magenta", bg = "gray", p.cex = 7, c.cex = 5)
vi.lilac.chaser(np = 16, col = "magenta", bg = "gray", p.cex = 7, c.cex = 5)
np 
number of points 
col 
color of points 
bg 
background color of the plot 
p.cex 
magnification of points 
c.cex 
magnification of the center cross 
Just try it out.
NULL
In fact, points in the original version of ‘Lilac Chaser’ are blurred, which is not implemented in this function.
Yihui Xie
Examples at https://yihui.org/animation/example/vililac.chaser/