Members-Only Course

Animation

It can be beneficial to make things move over time. Sometimes the transitions make changes easier to see, and other times it’s just fun to watch. Animation in R isn’t the greatest, but it’s workable if you’re not dealing with too much data and the animation isn’t too long.

Using the animation package, you can make a bunch of plots and strings them together like a flip book. The result is an animated GIF. So first, install the package if you don’t have it yet.

install.packages("animation", dependencies=TRUE)

The package relies on ImageMagick to create GIFs, so be sure to install that too (outside of R).

Are we in business? Okay, let’s do it.

Load the animation package.

library(animation)

Create an images folder in your working directory, and then enter the following in the console. It sets the directory where temporary images are saved as a GIF is constructed.

ani.options(outdir = paste(getwd(), "/images", sep=""))

Remember what I said about the flip book? This is key to understanding how to animate in R. You’re not actually moving objects around on a single plot. Instead you generate a whole bunch of plots, each one slightly different than the one before it, and then string them together for a moving effect.

For example, see the chart below:

Animated Multiline

This is an animated version of the multi-line plot that you already made. Another year is added in each frame until it reaches the end, and then it cycles back to the beginning. Think about how you might do this by hand. For the first year, you draw a blank plot. For the second year, you draw a plot with lines that connect the first and second year. In the third, you draw a plot with lines that connect the first through third. Continue to 2013, and you end up with a plot for every year.

The code below does just this. It draws a new plot for each year with a call to plot(), each time with a longer line. The saveGIF() function automatically strings them together as an animated GIF.

#
# Animate multi-line
#
saveGIF({
  for (i in 1:length(food$year)) {
    plot(food$year, food$meat_Beef, type="n", ylim=c(0, max_servings))
    
    for (j in 1:length(meat_columns)) {
      lines(food$year[1:i], food[1:i,meat_columns[j]])
    }
  }
}, movie.name = "meat-multiline.gif", interval=0.15, nmax=100, ani.width=650, ani.height=600)

Maybe you want to animate the small multiples version. The process is similar, as shown below.

#
# Animate small multiples
#
saveGIF({
  for (i in 1:length(food$year)) {
    par(mfrow=c(3,3))
    for (j in 1:length(meat_columns)) {
      plot(food$year[1:i], food[1:i,meat_columns[j]], type="l", main=meat_columns[j], xlab="year", ylab="ounces", xlim=c(1970,2013), ylim=c(0,3))
    }
  }
}, movie.name = "meat-multiples.gif", interval=0.15, nmax=100, ani.width=650, ani.height=600)

The difference is the line with par(mfrow=c(3,3)). Each time this is called, a new plotting device is created, which means a new frame for saveGIF(). In the multi-line example, mfrow is not used, so a call to plot() creates a new device.

The small multiples result:

Animated small multiples

In each frame, you draw a plot with a longer line each year.

This takes a bit of getting used to if you’re new to this sort of thing. For more, there are a couple more tutorials: one with an animated map and the other with a shifting population distribution.

population-pyramid-feautred

Animated Pyramid Chart

The modified bar chart shows the distribution of two categories at once.

05-Growth every two weeks

How to Make an Animated Growth Map in R

The process and logic is the same regardless of what you animate. This is a geographic version.