library(animation)
ani.options
control the behaviour of the animation. Some egs with default values:
oopt = ani.options(
nmax=50, # maximum number of steps in a loop
interval=0.1, # the time interval of the animation (unit in seconds)
ani.width=480, # dimension of the animation
ani.height=480,
imgdir="images", # directory (relative path) for images when creating HTML page
htmlfile="index.html", # name of the produced html file
autobrowse = interactive(), # whether auto-browse the animation after created
loop = TRUE, # whether to iterate or not
title = "", # the title of the html page
description = "" # the description of the html page
)
Examples from here.
library(animation)
saveGIF({
for(i in 1:100) {
curve(sin(x), from = -5+(i*0.05), to = 5 + (i * 0.05), col = "red", ylab = "")
curve(cos(x), from = -5+(i*0.05), to = 5 + (i * 0.05), add = TRUE, col = "blue", ylab = "")
legend("topright", legend=c("sin(x)","cos(x)"), fill=c("red","blue"), bty="n")
}
ani.options(oopt)
}, movie.name="sine2D_animation.gif")
library(animation)
saveGIF({
for(i in 1:150){
x <- seq(-6 + (i * 0.05), 6 + (i * 0.05), length= 100)
y <- x
f <- function(x, y) { sin(x) + cos(y) }
z <- outer(x, y, f)
persp(x, y, z, theta = 45 + (i * 0.5), phi = 35, expand = 0.4, col = "lightblue")
}
ani.options(oopt)
}, movie.name="surface3D_animation.gif")
which produces:
Make HTMLs with function saveHTML
. It produces a new html file with the images in folder images
:
saveHTML({
xs <- seq(-2,2,len=100)
oopt <- ani.options(interval = 0.2, nmax = 5, autobrowse = FALSE)
for (i in 1:ani.options("nmax")) {
plot(dnorm(xs,0,1/i), type="l")
ani.pause()
}
ani.options(oopt)
}, htmlfile="dnorm_test.html",
img.name="dnorms")
## HTML file created at: dnorm_test.html
A package example of the Buffon’s needle:
## create an HTML animation page
saveHTML({
par(mar = c(3, 2.5, 1, 0.2), pch = 20, mgp = c(1.5, 0.5, 0))
ani.options(nmax = ifelse(interactive(), 300, 10), interval = 0.1)
buffon.needle(type = "S", redraw = FALSE)
},
img.name = "buffon.needle",
htmlfile = "buffon.needle.html",
ani.height = 500,
ani.width = 600,
title = "Simulation of Buffon's Needle",
description = c("There are three graphs made in each step: the",
"top-left, one is a simulation of the scenario, the top-right 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 dropping.")
)
ani.options(oopt)
Check the result.
However, saveGIF
might not work properly. In that case you could do it yourself. This takes the previous made pictures from saveHTML
and create the animated GIF:
im.convert(files="images/buffon.needle*.png",
output="images/buffon.needle.gif",
cmd.fun=system)
More samples here.
From here:
# 0 - empty
# 2 - first agent type color
# 4 - second agent type color
# initialize simulation
# size - square size
# perc.full - percentage of lots to be occupied
init <- function(side, perc.full) {
size <- floor(side ^ 2 * perc.full / 2)
state <- matrix(0, side, side)
occupied <- sample(side ^ 2, 2 * size)
state[occupied] <- c(2,4)
return(state)
}
# plot simulation state
# state - simulation state
# i - simulation iteration
do.plot <- function(state, i) {
side <- dim(state)[1]
x <- rep(1:side, side)
y <- rep(1:side, each = side)
par(fin=c(4,4), fig=c(0,1,0,1))
plot(x , y, axes = F, xlab="", ylab="", col = state,
main = paste("Step", i), pch = 19, cex = 40 / side)
}
# perform one step of simulation
# state - simulation state
# threshold - percent of required agents of the same color
# in neighborhood
# radius - neighborhood radius
sim.step <- function(state, threshold, radius) {
mod.1 <- function(a, b) { 1 + ((a - 1) %% b) }
div.1 <- function(a, b) { 1 + ((a - 1) %/% b) }
unhappy <- rep(NA, length(state))
side <- dim(state)[1]
check <- (-radius):(radius)
#find unhappy agents
for (n in which(state > 0)) {
x <- div.1(n, side)
y <- mod.1(n, side)
x.radius <- mod.1(check + x, side)
y.radius <- mod.1(check + y, side)
region <- state[y.radius, x.radius]
similar <- sum(region == state[n]) - 1
total <- sum(region > 0) - 1
unhappy[n] <- (similar < total * threshold)
}
vunhappy <- which(unhappy)
# move unhappy agents
vunhappy <- vunhappy[sample.int(length(vunhappy))]
empty <- which(state == 0)
for (n in vunhappy) {
move.idx <- sample.int(length(empty), 1)
state[empty[move.idx]] <- state[n]
state[n] <- 0
empty[move.idx] <- n
}
return(state)
}
library(animation)
# simple wrapper for animation plotting
go <- function() {
s <- init(51, 0.75)
for (i in 1:50) {
do.plot(s, i)
last.s <- s
s <- sim.step(s, 0.6, 1)
if (identical(last.s, s)) { break }
}
for (j in 1:4) {
do.plot(s, i)
}
ani.options(interval = 5 / (i + 2))
}
saveGIF(go(), movie.name="schelling_animation.gif")
## Output at: schelling_animation.gif
## [1] TRUE