Add an animated R plot to your LaTeX document
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.
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-
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-
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.
R-bloggers.com offers daily e-mail updates about R news and tutorials about learning R and many other topics. Click here if you're looking to post or find an R/data-science job.
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.