Animations in R

Animated charts can be very helpful in illustrating concepts or discovering relationships, which makes them very helpful in teaching and exploratory research. Fortunately, creating animated graphs in R is fairly straightforward, once you have the right tools and understand a few basic principles about how the animations are created.

In this article I'll provide an example of how to use the animation package to create an animated chart with a couple of bells and whistles.

The package installs out-of-the-box with several animations that are tailored for instruction. The examples are of varying complexity ranging from a simple coin flip simulation to illustrations of mathematical problems such as Buffon's needle problem. In most scenarios, however, you'll want to create your own animations, so let's look at how to do that.

First, there are several different formats in which you can create your animations - GIF, HTML, LaTeX, SWF and mp4. The saveGIF() function call below illustrates the generic format for each of the calls:

saveGIF({
    for (i in 1:10) plot(runif(10), ylim = 0:1)
})

Understanding that the package creates animations by generating and then compiling many graphs is central to creating polished custom animations. As you can see, the syntax looks a little unfamiliar at first because the inside of the function call is a custom loop that creates the individual graphs. (Note: If you're familiar with with the way the boot() function works, this is somewhat similar.) Once those individual graphs are created, the function compiles the images in the format specified by the function call. As you might have guessed, most of the animation types require that you install 3rd party libraries for R to be able to do the compilations. The installation of these libraries is covered in the package help.

Basic use of the animation functions is covered in the package help, but the application of the functions to novel tasks can still be a little difficult. As a result, I've created an example that illustrates how to use the functions to create animations with a couple of bells and whistles.

This animation plots the density functions of 150 draws of 100 values from a normally distributed random variable. To make things a little more interesting (i.e., make the distribution move), a constant that varies based on the iteration count is added to the 100 values. The chart also includes a slightly stylized frame tracker (or draw counter) along the top of the chart and a horizontal bar that notes the current position and previous two positions of the sample mean. Finally, the foreground color of the chart changes based on the mean of the distribution.

 

###################################
library(animation)

#Set delay between frames when replaying
ani.options(interval=.05)

# Set up a vector of colors for use below
col.range <- heat.colors(15)

# Begin animation loop
# Note the brackets within the parentheses
saveGIF({
 
  # For the most part, it's safest to start with graphical settings in
  # the animation loop, as the loop adds a layer of complexity to
  # manipulating the graphs. For example, the layout specification needs to
  # be within animation loop to work properly.
  layout(matrix(c(1, rep(2, 5)), 6, 1))
 
  # Adjust the margins a little
  par(mar=c(4,4,2,1) + 0.1)
 
    # Begin the loop that creates the 150 individual graphs
    for (i in 1:150) {
     
      # Pull 100 observations from a normal distribution
      # and add a constant based on the iteration to move the distribution
      chunk <- rnorm(100)+sqrt(abs((i)-51))
     
      # Reset the color of the top chart every time (so that it doesn't change as the
      # bottom chart changes)
      par(fg=1)
     
      # Set up the top chart that keeps track of the current frame/iteration
      # Dress it up a little just for fun
      plot(-5, xlim = c(1,150), ylim = c(0, .3), axes = F, xlab = "", ylab = "", main = "Iteration")
      abline(v=i, lwd=5, col = rgb(0, 0, 255, 255, maxColorValue=255))
      abline(v=i-1, lwd=5, col = rgb(0, 0, 255, 50, maxColorValue=255))
      abline(v=i-2, lwd=5, col = rgb(0, 0, 255, 25, maxColorValue=255))
     
      # Bring back the X axis
      axis(1)
     
      # Set the color of the bottom chart based on the distance of the distribution's mean from 0
      par(fg = col.range[mean(chunk)+3])
     
      # Set up the bottom chart
      plot(density(chunk), main = "", xlab = "X Value", xlim = c(-5, 15), ylim = c(0, .6))

      # Add a line that indicates the mean of the distribution. Add additional lines to track
      # previous means
      abline(v=mean(chunk), col = rgb(255, 0, 0, 255, maxColorValue=255))
      if (exists("lastmean")) {abline(v=lastmean, col = rgb(255, 0, 0, 50, maxColorValue=255)); prevlastmean <- lastmean;}
      if (exists("prevlastmean")) {abline(v=prevlastmean, col = rgb(255, 0, 0, 25, maxColorValue=255))}
      #Fix last mean calculation
      lastmean <- mean(chunk)
    }
})

########################

And the final product:

A couple of closing notes:

  • Because there are external programs involved (e.g., SWF Tools, ImageMagick, FFmpeg), the setup for this package is slightly more difficult than the average package and things will likely seem less polished than normal. Things may also not work as well; you'll need to be prepared to be flexible with your animation formats and graph layouts.
  • Animation works exceptionally well when smaller numbers of individual graphs are being compiled, but as the number of individual graphs grows, so does your likelihood of hitting a problem. E.g., although GIF is a very exportable and transportable format, and therefore ideal for many situations, I found that animations with more than ~500 source graphs just didn't compile. The limit for HTML was similar. Your mileage may vary, but again, be prepared to be flexible.
  • If you do not need to transport your animation and it will have less than a few hundred individual images, you can avoid installing 3rd party software by using the saveHTML function. This output also includes an interface that allows you to pause and move within the animation easily.
  • As mentioned in the code above, if you're having trouble getting a particular graphical parameter to work, make sure that it is in the internal loop. For efficiency, you want to keep the loop as clean as possible of course, but some things need to be specified each time a new chart is plotted, and therefore need to be inside the loop.
  • Animations aren't very common in research presentations, but can provide extensive insight beyond static images. Given R's advanced graphing capabilities, it's possible to create very nice animations without needing to learn a completely different software package.

If you've created an animation you'd like to share or have additional tips, feel free add them to the comments.


RStudio Development Environment

RStudio LayoutCompared to many other languages of equal popularity, there are realtively few development environments for R. In fact, the total number of production ready R IDEs could probably be counted on one hand. That deficiency is a small price to pay to use R and if you're not already accustomed to using IDEs for other languages, you probably haven't missed it too much. But RStudio goes a long way toward providing a full-featured R development platform, that, once you've used it, quickly becomes hard to give up again.

RStudio has some nice graphical features and the layout is clean and logical for the most part. Functionally, some of the best features are:
  • Plot caching (allows you to flip back through previous graphs without rerunning them, making it much easier to review your graphical output)
  • Function, object and parameter listing and completion that works even with user-defined functions
  • Shortcuts for quickly drilling down into functions

RStudio paramater completion

RStudio also provides version control integration (Git, SVN) which could prove to be very helpful, but I haven't yet tested it. I can't speak to how well it works, just that it is available.

In addition to these positives, RStudio has an active support system with developer participation via the RStudio support site.

Overall, I've been very impressed with RStudio over the past few weeks. If you haven't yet tested it, I suggest you give it a try. Given the growth of R over recent years, I think it's time we expected development tools to mature to the level that they have for other programming languages with similar levels of adoption. The only way that will produce sustainable, mature products is if there is a constant demand in the market.

Already using something else? Feel free to mention your favorite R IDE in the comments.

Installing quantstrat from R-forge and source

R is used extensively in the financial industry; many of my recent clients have been working in or developing products for the financial sector. Some common applications are to use R to analyze market data and evaluate quantitative trading strategies. Custom solutions are almost always the best way to do this, but the quantstrat package can make it easy to quickly get a high-level understanding of a strategy's potential. However, quantstrat is still under development, and this, combined with a lack of documentation and the complex nature of the tasks involved, make it difficult to work with. This article addresses one of the most basic issues with quantstrat - getting it installed. quantstrat and it's required packages currently aren't available on CRAN - you have to get them from R-forge. As a result, the installation is slightly less straightforward than other packages and provides an opportunity to discuss how to install packages from R-forge and locally from source. Although this article focuses on installing quantstrat, these instructions will help with any R-package that you need to build from source.


If you're installing from R-forge, the process is only moderately different than installing from CRAN; simply change the install.packages command to point to the R-forge repository:


install.packages("FinancialInstrument", repos="http://R-Forge.R-project.org")

install.packages("blotter", repos="http://R-Forge.R-project.org")

install.packages("quantstrat", repos="http://R-Forge.R-project.org")


Since the FinancialInstrument and blotter packages are dependencies for quantstrat, you can download and install all three at once with just the last line.


In some cases, you may need to build the packages yourself. You'll need to set your system up to compile R source code if it isn't already. To do so, follow steps 1-3 below. If your system is already set up to compile R source code, you can skip to step 4.


# 1) Install Rtools package (must be done manually from http://www.murdoch-sutherland.com/Rtools/

# 2) Install LaTex from www.miktex.org/

# 3) Install InnoSetup http://www.jrsoftware.org/

# 4) Download the three package source files available from R-forge http://r-forge.r-project.org/R/?group_id=316

# 5) Install the packages using the commands below (substituting the appropriate version numbers):


install.packages("C:/yourpath/FinancialInstrument_0.9.18.tar.gz", repos = NULL, type="source")

install.packages("C:/yourpath/blotter_0.8.4.tar.gz", repos = NULL, type="source")

install.packages("C:/yourpath/quantstrat_0.6.1.tar.gz", repos = NULL, type="source")


Note that these directions are relevant until the packages are available on CRAN, after which, you'll be able to download and install them like any other package (I'll make a note on this post once that happens). Also note that since these packages are under heavy development, you'll want to update them often.


Subscriptions Feature Added

You can now subscribe to almost any content on the ProgrammingR website, including the job listings.

To be notified of job listings as soon as they are posted, click the "R Jobs" link above and follow the instructions on that page to add the jobs feed to your feed reader.Because of this change, I will now be reposting jobs from the R Jobs listserv and other sources, so that you only need to subscribe to one service. If you have a source for R Jobs listings that you would like to see represented in the Job Listings section, send me a message and I will attempt to include it.

If you would like to submit a job or consultant listing, you can do so via the contact page.


Syndicate content