You are here

Add an animated R plot to your LaTeX document

My first introduction with LaTeX was not very pleasant. I got tired and frustrated by writing so many codes for producing a simple document; but a few days ago I could write a function for producing an animated plot in R and also could export it to my LaTeX document with all its animations intact (using animation package of R).

That really made me interested in learning LaTeX; just think a PDF book has animated plots and the readers can rewind and reverse and also can control the motion of the plots just by clicking mouse! It will be very helpful for both the writer and the readers.

Now let’s discuss about producing a very simple animated plot in R. I have three variables X, Y and Z. And I regressed Z on X and Y and extracted the residuals. Now I want to examine the standardized residuals where some attractive animations will help us to visualize their characteristics. To be specific, I want that the residuals with positive values and negative values will be denoted by the letters “P” and “N” respectively, and the size of the letters will increase gradually. The next animation effect will show the largest values of the residuals (both positive and negative) and will denote these two values by the words “maximum (+)” and “maximum (-)” respectively, and the sizes of the words will increase gradually and at the same time will rotate at 360 degrees. These two points will also be pointed by red blinking circles. At last I want to find if there is any standardized residual that falls above 3 or below -3; and if any point does it should be denoted by a text “warning” (whose size will also increase at every animation frame). The function is given below-

reg<-lm(Z~X+Y,data=data)
r<-resid(reg)
x<-(r-mean(r))/sd(r)
 
 for (i in 1:30) {
    plot(x, type = "l",col="blue",xlim=c(-10,153),ylim=c(min(x)-1,max(x)+1))
    bad<-ifelse(x>=0,"orange","darkgreen")
    sym<-ifelse(x>=0,"P","N")
    points(x,col=bad,pch=sym,cex = 1.2*i/30)
    Sys.sleep(.001)
}
for (i in 1:45) {
    plot(x, type = "l",col="blue",xlim=c(-10,153),ylim=c(min(x)-1,max(x)+1))
    abline(h=0,col="black",lty=2)
    abline(h=3,col="red",lty=2)
    abline(h=-3,col="red",lty=2)
    bad<-ifelse(x>=0,"orange","darkgreen")
    sym<-ifelse(x>=0,"P","N")
    points(x,col=bad,pch=sym,cex = 1.2)
    if (i<=30)
    points(x=c(which(x==max(x)),which(x==min(x))),y=c(max(x),min(x)),
    col="red",lwd=2,pch="O",cex=2.5*i/30)
    else
    points(x=c(which(x==max(x)),which(x==min(x))),y=c(max(x),min(x)),
    col="red",lwd=2,pch="O",cex=2.5*(45-(i-9))/15)
    text(x=c(which(x==max(x)),which(x==min(x))),y=c(max(x),min(x)),
    labels=c("maximum(+)","maximum(-)"),pos=c(3,1),col="midnightblue",
    cex =1*i/45,srt=i*8)
    text(x=c(which(abs(x)>3)),y=x[c(which(abs(x)>3))],
    labels=rep("warning",times=sum(abs(x)>3)),cex=1.5*i/45,col="magenta")
    Sys.sleep(0.001)
}

It is to be noted that at the first for loop I put 30 animation frames just because I want the letters P and N to increase to size 1.2 after 30 steps. We can change this number to alter the motion of our animation. In the second for loop 45 frames are put for the same reason; and the “if” argument is put because I want the red circles to increase in size for the first 30 animation frames and for the next 15 frames the size will decrease gradually and at last will settle at size 1.5. Look at the “srt” argument in the function “text” in second for loop, it make the text rotate at 8 degrees at each frame. The final frame of the animated plot is like following-

plot1.jpg

This function will produce a nice animated plot that might be very useful in visualizing and understanding various aspects of our data. This plot does not require any additional package but the package “animation” can be very much useful in producing more complex animated plots. Now we want to add this animated plot to our LaTeX document with all its effects. The package animation has a very useful function named “saveLatex” for this purpose. The function I used for exporting the plot to LaTeX is –

   saveLatex(expr=c(for (i in 1:30) {
    plot(x, type = "l",col="blue",xlim=c(-10,153),ylim=c(min(x)-1,max(x)+1))
    bad<-ifelse(x>=0,"orange","darkgreen")
    sym<-ifelse(x>=0,"P","N")
    points(x,col=bad,pch=sym,cex = 1.2*i/30)
    Sys.sleep(.001)
}
for (i in 1:45) {
    plot(x, type = "l",col="blue",xlim=c(-10,153),ylim=c(min(x)-1,max(x)+1))
    abline(h=0,col="black",lty=2)
    abline(h=3,col="red",lty=2)
    abline(h=-3,col="red",lty=2)
    bad<-ifelse(x>=0,"orange","darkgreen")
    sym<-ifelse(x>=0,"P","N")
    points(x,col=bad,pch=sym,cex = 1.2)
    if (i<=30)
    points(x=c(which(x==max(x)),which(x==min(x))),y=c(max(x),min(x)),
    col="red",lwd=2,pch="O",cex=2.5*i/30)
    else
    points(x=c(which(x==max(x)),which(x==min(x))),y=c(max(x),min(x)),
    col="red",lwd=2,pch="O",cex=2.5*(45-(i-9))/15)
    text(x=c(which(x==max(x)),which(x==min(x))),y=c(max(x),min(x)),
    labels=c("maximum(+)","maximum(-)"),pos=c(3,1),col="midnightblue",
    cex =1*i/45,srt=i*8)
    text(x=c(which(abs(x)>3)),y=x[c(which(abs(x)>3))],
    labels=rep("warning",times=sum(abs(x)>3)),cex=1.5*i/45,col="magenta")
    Sys.sleep(0.001)
    }),interval=.001,latex.filename="c.tex",outdir=getwd(),
    nmax=75,documentclass=”article”)

Look at the highlighted parts of the function; these are the additional things I did for exporting the plot to LaTeX. Here I put “documentclass” as article, make it “beamer” if you want to make a multimedia presentation. The function “outdir=getwd()” will put the outcome files to your working directory (by default it is home folder for Linux and My Documents for windows). The argument “nmax” denote the maximum number of animation frames; here we have 30 frames for first for loop and for the second loop have 45; so, here “nmax” should be at least 75.

This function will produce several files including a PDF file (which will contain the animated plot) and a tex file which you can always modify. To see the animation in the PDF file you need to install Adobe Reader in your computer as no other PDF reader support JavaScript correctly (am I wrong? Is there any open source available?) . Linux users please download Adobe Reader for Linux from
here

The PDF file will contain a plot which will initially look like following-
plot2.jpg
By clicking on the play button we can see the animations, there are also some additional buttons with which we can control the speed of our animation and also can rewind or reverse the animation (For the final frame look at the main image of the article).

It is also possible to convert the plot to a GIF image that we can add to our Microsoft Office PowerPoint or open office impress slide. For this we have to use the “saveMovie” function and for running this function we need to have “imageMagick” installed in our computer. Download and install “imageMagick” from here.

It is also possible to convert this animated plot to a flash video file (that we can upload to YouTube). For this purpose, use “saveSWF” function. Softwares like “SWFTools” need to be installed before doing this. Download SWFTools from here here. "saveMovie" function adn "saveSWF" functions are very much similar to "saveLatex"; so, for details please read the R animation package help manual.

Have fun with R and LaTeX.

Category: 

Comments

You are most welcome. All the three variables, I used to run the regression model, have 133 observations, so, I can't provide the whole dataset here. But, you can do the same thing using any dataset. Nevertheless,if you really want my dataset I can mail you that, just leave your mail address here.

I think it would be a good idea to mention the version of animation that you used to produce this graph with the provided code. Because, with the newer versions of the package, some arguments to saveLatex() might get changed, causing errors if someone runs your code.

For instance, when I ran this, I got some error regarding "unused arguments" such as:

Error in ani.dev(sprintf("%s%s.%s", ani.basename, num, ani.ext), ...) :
unused argument(s)

Also, for some reason, I had to change the Latex.filename() to latex.filename().

It is to be mentioned that I am using Ubuntu 10.x with R 2.11.0 and animation version 1.1 (2010-09-28)

Dear sir, thanks again. I ran the code in R 2.10.1 with the same version of animation package you have tried. And sir, Latex.filename is actually a typo, and it should be latex.filename as you have mentioned. And sir, I have rechecked the code in R 2.12.0 with the same version of animation package and everything went fine(of course after fixing the typo); I'm not really sure why you have had these errors. Please let me know if you can find anything else regarding the code. Thank you again.

Take any data, this procedure should work with any variable (depending on what type of graph you are trying to create).

Add new comment