Brownian Motion GIF with R and ImageMagick

December 9, 2017

(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<- data.frame(0,0)
names(df1)<- c("Y","X")
for (g in 1:750){
df1[g,2] <- g
df1[g,1] <- y
y <- y + rnorm(1,0,1)
#plot(df1$X,df1$Y, ylim=c(-100,100), xlim=c(0,1500), cex=0)
#lines(df1$X,df1$Y, col="red")
df2<- data.frame(0,0)
names(df2)<- c("Y","X")
for (g in 1:1500){
df2[g,2] <- g
df2[g,1] <- y
y <- y + rnorm(1,0,1)
#lines(df2$X,df2$Y, col="blue")
df3<- data.frame(750,df1[750,1])
names(df3)<- c("Y","X")
for (g in 750:1500){
df3[g-749,2] <- g
df3[g-749,1] <- y
y <- y + rnorm(1,0,1)
#lines(df3$X,df3$Y, col="green")
df4<- data.frame(750,df1[750,1])
names(df4)<- c("Y","X")
for (g in 750:1500){
df4[g-749,2] <- g
df4[g-749,1] <- y
y <- y + rnorm(1,0,1)
#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<-rep(0:1, times=7, each= 15)
parp<- c(parp, rep(0, 600))
for (q in 1:750){
if ( q %% 2 == 1) {
id <- sprintf("%04d", q+749)
png(paste("bm",id,".png", sep=""), width=900, height=570, units="px",
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)

 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à!

To leave a comment for the author, please follow the link and comment on their blog: long time ago.... offers daily e-mail updates about R news and tutorials on topics such as: Data science, Big Data, R jobs, visualization (ggplot2, Boxplots, maps, animation), programming (RStudio, Sweave, LaTeX, SQL, Eclipse, git, hadoop, Web Scraping) statistics (regression, PCA, time series, trading) and more...

If you got this far, why not subscribe for updates from the site? Choose your flavor: e-mail, twitter, RSS, or facebook...

Comments are closed.

Search R-bloggers


Never miss an update!
Subscribe to R-bloggers to receive
e-mails with the latest R posts.
(You will not see this message again.)

Click here to close (This popup will not appear again)