# Brownian Motion GIF with R and ImageMagick

(This article was first published on long time ago…, and kindly contributed to R-bloggers)

Hi there!
Last Monday we celebrated a “Scientific Marathon” at Royal Botanic Garden in Madrid, a kind of mini-conference to talk about our research. I was talking about the relation between fungal spore size and environmental variables such as temperature and precipitation. To make my presentation more friendly, I created a GIF to explain the Brownian Motion model. In evolutionary biology, we can use this model to simulate the random variation of a continuous trait through time. Under this model, we can notice how closer species tend to maintain closer trait values due to shared evolutionary history. You have a lot of information about Brownian Motion models in evolutionary biology everywhere!
Here I will show you how I built a GIF to explain Brownian Motion in my talk using R and ImageMagick.
`` # First, we simulate continuous trait evolution by adding in each iteration   # a random number from a normal distribution with mean equal to 0 and standard   # deviation equal to 1. We simulate a total of 4 processes, to obtain at first   # two species and a specieation event at the middle of the simulation, obtaining   # a total of 3 species at the end.   df1 names(df1) y for (g in 1:750){   df1[g,2]  df1[g,1]  y  }   #plot(df1\$X,df1\$Y, ylim=c(-100,100), xlim=c(0,1500), cex=0)   #lines(df1\$X,df1\$Y, col="red")   df2 names(df2) y for (g in 1:1500){    df2[g,2]   df2[g,1]   y  }   #lines(df2\$X,df2\$Y, col="blue")   df3 names(df3) y for (g in 750:1500){    df3[g-749,2]   df3[g-749,1]   y  }   #lines(df3\$X,df3\$Y, col="green")   df4 names(df4) y for (g in 750:1500){    df4[g-749,2]   df4[g-749,1]   y  }   #lines(df4\$X,df4\$Y, col="orange")  ``

`` # Now, we have to plot each simmulation lapse and store them in our computer.   # I added some code to make lighter the gif (plotting just odd generations) and    # to add a label at the speciation time. Note that, since Brownan Model is a    # stocasthic process, my simulation will be different from yours.   # You should adjust labels or repeat the simulation process if you don't    # like the shape of your plot.   parp parp for (q in 1:750){    if ( q %% 2 == 1) {    id   png(paste("bm",id,".png", sep=""), width=900, height=570, units="px",       pointsize=18)    par(omd = c(.05, 1, .05, 1))    plot(df1\$X,df1\$Y, ylim=c(-70,70), xlim=c(0,1500), cex=0,        main=paste("Brownian motion model n generation=", 749 + q) ,        xlab="generations", ylab="trait value", font.lab=2, cex.lab=1.5 )   lines(df1\$X,df1\$Y, col="red", lwd=4)   lines(df2\$X[1:(q+749)],df2\$Y[1:(q+749)], col="blue", lwd=4)   lines(df3\$X[1:q],df3\$Y[1:q], col="green", lwd=4)   lines(df4\$X[1:q],df4\$Y[1:q], col="orange", lwd=4)   if (parp[q]==0)   text(750, 65,labels="speciation event", cex= 1.5, col="black", font=2)   if (parp[q]==0)   arrows(750, 60, 750, 35, length = 0.20, angle = 30, lwd = 3)   dev.off()   }   }  ``

Now, you just have to use ImageMagick to put all the PNG files together in a GIF using a command like this in a terminal:

`` convert -delay 10 *.png bm.gif  ``

Et voilà!