Making a movie with R

Since some models (like mine) do not always give a direct interface with results, R provides us with a powerful tool to play around with big piles of data models spit out. Obviously, you also may want to do this despite existing model interfaces!  The program R is making life often happy due to its endless possibilities. Since I am performing a vegetation model with individual trees modelled, one of my wishes was to see the forest in real life and 3D. So the forest is growing, waning, stabilizing and so forth. Making a movie with R!

All right, I directly admit: the movie is not made with R, but is calling another program from outside R; namely Image Magick in combination with the FFMPEG software. Nevertheless the code is totally in R and it works really nice.
If you have time-dependent graphs, plots, maps or whatsoever, you can use this neat function to make a moving pictures file. Of course you can also use a sleeper function within the R studio display, but it is easier for use to make a seperate movie.

First I will show you my personal code, which is making a movie of a growing tree stand and then explain it command by command:

TOT=floor(tlen/interval)    # decide on number of graphs needed, based on total time and time steps
for(step in 0:TOT){      # start the loop of making graphs here!
  t=1+(interval*step)             # step counter  
  # decide on some specific graph-parameters before and put them in 1 dataframe
  # open the file in which the graph is drawn: the following if-statements are to make sure the graphs are numbered well, 
  # so 100 is not appearing before 1 and so on...
  if(step<10){             # make sure generated graphs are numbers from 1-999
    jpeg(filename=sprintf("%sMovie/%s/Flash_00%s.jpeg",Folder,nameshort,step), width=1000, height=800, units="px")
  } else if(step<100){
    jpeg(filename=sprintf("%sMovie/%s/Flash_0%s.jpeg",Folder,nameshort,step), width=1000, height=800, units="px")
  with(TreeStruct, {
    s3d <- scatterplot3d(gridyx1, gridyx2,HTrees,             # x y (grids) and z (height) axis in scatterplot3d package
                         color=CTrees, pch=FTrees,            # color (species) and form (canopyform) of symbols
                         cex.symbols=STrees,                  # symbol size (canopy size)
                         zlim=c(0:40),# alpha=0.2,                        # maximum value for z-axis (height)
                         type="h", lty.hplot=2,               # lines to the horizontal plane and its line type (2=dashes)
                         grid=TRUE, main=sprintf("A Hectare of Tree Growth \n (time = %s)",t), # include the grid and graph title
                         xlab="", ylab="", zlab="Height (m)") # axes titles
  # Sys.sleep(0.5)      # possibility to let the movie run in the R-studio plot (might be disfunctional when using the whole script)   }    # the loop for making graphs ends here!
# create morphing images with same size (morph 3 = 3 images per graph):
cmd_morph <- paste0("convert ", sprintf("%sMovie/%s/*.jpeg",Folder,nameshort),
                    " -morph 3 ", sprintf("%sMovie/%s/",Folder,nameshort), "%05d.morph.jpg")
# create the movie from the morph images (-r 10 = movie speed 10 fps; -qscale 2 = quality class 2):
cmd_mov <- paste0("ffmpeg -r 10 -i ",sprintf("%sMovie/%s/",Folder,nameshort), 
                  "%05d.morph.jpg -qscale 2 ", sprintf("%sMovie/%s/%s_%.0f%.0f.mp4",Folder,nameshort,nameshort,x,y))
# run the command lines created above in linux terminal

As one can see, I first make the graphs, that form the basis of the movie. I did not provide all details here, since it would make the script too long, due to the specifics of trees. Of course you can skip this all, when you have your own nice graphs. Just be aware you put them in a logical numbering order to read for the movie maker program later!
I also wanted to show here the s3d plotting function of R, which is really cool. It makes it possible to have 3D graphs. There are even options to look at the whole grid from different angles. (do not forget to download and call the package at the start of your R-script)

So, the real movie making starts at the very end of this script with the programs Image Magick and FFMPEG. In R you can create a command using the paste0-function, which is then called on the system with “system(command line)”.
We use two commands: the first I call “cmd_morph”, which creates the morphed pictures, so the movie is flowing; and the second one I call “cmd_mov”, which in fact makes the movie.

> cmd_morph <- convert inputfile/*.jpeg -morph x outputfile/%05d.morph.jpg
x = number of frames (morphed pictures) in between input graphs – the higher this number, the more flowinf the movie will be, but also the more time it needs to generate – standard is 2 to 5.
inputfile/ = file address of input graphs in jpeg or other picture type – take care this file only entails the graphs for the movie (or use inputfile/rootname*.jpeg).
outputfile/ = file address, where morphed output files will be stores.
%05d.morph.jpg = name of output file using 5 numbers (for max. 99999 frames) – change this 5 into 3 (max 999 frames) or any other number, depending on the frame number x.

> cmd_mov <- ffmpeg -r a -i inputfile/%05d.morph.jpg qscale b outputfile/name.mp4
a = the r-factor, meaning the number of frames per second – standard is 10.
b = the qscale-factor, meaning the quality class of the movie – standard is 2.
inputfile/05d.morph.jpg = file addres of the morphed input files, that resulted from the previous command cmd_morph.
Outputfile/name.mp4 = file address for the movie – consider a specific name for the location and time.

Hope this bit of code has entertained you a little bit.


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s