Animated plots in R

In my post on bitcoins, I wanted to show 2 dimensions of data, which lends itself to a scatter plot, but over time. There are easy ways to do that in r.

  • GoogleVis package
    • Makes Hans Rosling style motion charts using google API
    • Allows interaction, where the user can change which components are plotted
    • Expects time to be on the x-axis
    • End product is an html snippet
  • Manually using a loop to make each frame
    • A bit more effort than googleVis
    • Gives you complete freedom to do anything you want
    • Final product is a self contained gif with no dependencies
    • End product is a gif

Below, I’ll give an example using both methods.

The googleVis package

Super easy to use, the data just needs to be in long format. The time format has to be years or dates. In the dataset I’m feeding in the time interval is actually 30 seconds. So ignore the time scale in this plot, I didn’t really take years to ski down the mountain.

The data is from day one of my recent trip to Austria for skiing. If you hit play, you can see the lift rides heading up, and the ski runs are when the bubbles descend. Distance is sum of how far I had travelled over the whole day.

library(googleVis) # Open the googleVis package

## Create graph
Motion_plot <- gvisMotionChart(skidata_collapsed,
                               idvar="run",
                               timevar="time",
                               xvar="distance.km",
                               yvar="altitude.m",
                               sizevar="speed.kmhr"
                               )

### Take a gander at it
	plot(Motion_plot)

### Print HTML file
	print(Motion_plot, file="gvisplot.html")
Example motion chart with ill suited data

Manually create frames of the animation

So to manually animate the graph there are two steps,

  1. Make the frame of the animation
  2. Stitch them together

The first step is relatively easy. Make a loop that iterates over subsets of your data, spitting out a frame at each step. If you have ImageMagick installed, you can skip the second step and go straight to a gif by using saveGIF, rather than opening a png device.

mydata <- mydata[order(mydata$month_num) , ]
  order <- c(1:nrow(mydata))
  mydata <-cbind(mydata, order)

# Names for each frame of the animation
graphname <- paste("manualplot_",order,".png",sep="")

# Load up the data
# The torrent is pretty big, so no data dump in a gist this time

# Set up loop to run through each row of the dataset
for (i in 1:nrow(mydata)) {
  # Get name of graph, set width
  	png(graphname[i], width = 800)
  # Open ggplot2 object and subset to all data till that point of the loop
  g <- ggplot(mydata[1:i,],
              aes(x = count_trades_log,
                  y = priceperbitcoin_log,
                  #colour = as.numeric(month_num)
              )) +
    # Plot past points and path as faded
    geom_point(alpha=0.5) +
    geom_path(alpha=0.5) +
    # I dislike the default ggplot2 theme
    theme_bw() +
    # My colouring is a bit superflous - don't bother with the legend
    theme(legend.position = "none")  +
    ggtitle("Relationship between bitcoin value & number traded, by month") +
    # Write which month we are currently up to in the loop
    annotate("text",
             label = mydata[i,"month"],
             x = 4.5, y = 2,
             size=9) +
    # This needs to be adjusted to your data, as limits and labels will differ
    scale_x_continuous(name="Number of trades over the month",
                       limits=c(4,6.1),
                       labels=c("10,000","32,000","100,000","320,000","1,000,000")) +
    scale_y_continuous(name="Median value of a Bitcoin (£)" ,
                       labels=c(1,100,"1,000",10000),
                       limits=c(-0.3,2.6)
    ) +
    # Make the point we are up to stant out. Note I had to reaffirm the data being used,
    #	as now I just want the current date.
    geom_point(aes(x=count_trades_log,
                   y=priceperbitcoin_log),
               colour = "red", size = 5,
               data=mydata[i,])
  print(g)
  dev.off()
}

After running this code, you’ll have a series of pngs that are the frames of your animation. If you’ve installed stuff via terminal before, I’d recommend installing ImageMagick via Homebrew or some other package manager (It may have been my incompetency, but I found it a nightmare to install). The easy option though is one of the countless online services to stich the gif together, or GIMP1. Rather than risking screwing up something your OS depends on.

Increasing number of trades and value of a bitcoin over time.
  1. Saving an image in GIMP that has layers as a gif will result in a pop up box asking if this is an animation.

A post about: , and

You May Also Enjoy