Skip to content

Instantly share code, notes, and snippets.

@jrjhealey
Created January 30, 2018 17:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jrjhealey/df19e91431dc0dd36d1c036e04cb48d9 to your computer and use it in GitHub Desktop.
Save jrjhealey/df19e91431dc0dd36d1c036e04cb48d9 to your computer and use it in GitHub Desktop.
Making a video from an R loop
#!/usr/bin/env Rscript
# Plotting surface plots via ggplot2/plotly
# Usage:
# $ Rscript CDmeltplot.R -i data.csv -o filename
############################################################
# General purpose heatmap plotting script for consistency. #
# This script can be slow as it was designed to be pretty #
# bullet-proof when loading/installing necessary packages. #
# #
# By J. Healey #
# Version 3
############################################################
# Load packages:
list.of.packages <- c("reshape2",
"plotly",
"argparse",
"ggplot2",
"RColorBrewer",
"tools",
"stringr",
"htmltools",
"magrittr",
"RSelenium")
new.packages <- list.of.packages[!(list.of.packages %in% installed.packages()[,"Package"])]
if(length(new.packages)) install.packages(new.packages)
suppressMessages(library("reshape2"))
suppressMessages(library("plotly"))
suppressMessages(library("argparse"))
suppressMessages(library("ggplot2"))
suppressMessages(library("RColorBrewer"))
suppressMessages(library("tools"))
suppressMessages(library("stringr"))
suppressMessages(library("htmltools"))
suppressMessages(library("magrittr"))
suppressMessages(library("RSelenium"))
parser <- ArgumentParser()
parser$add_argument('-i',
'--infile',
action='store',
required=TRUE,
help="Plain csv matrix file for plotting.")
parser$add_argument('-d',
'--device',
action='store',
default='svg',
choices=c('png','svg','jpeg','pdf','webp'),
help='Output image format/device. Default SVG.')
parser$add_argument('-o',
'--outfile',
action='store',
default='None',
help='Filename and path to save the image to. Defaults to the same as the infile with a new extension.')
parser$add_argument('-z',
'--zoom',
action='store',
default=2.5,
help='The zoom value of the camera, larger values move the camera away from the centre. Default 2.5')
parser$add_argument('-v',
'--vangle',
action='store',
default=0.4,
help='The vertical angle of the camera. Increased values will rotate the camera \'overhead\'. Default 0.4')
parser$add_argument('--movie',
action='store',
default='0.5:0.5:1',
help='Render multiple frames to create a video. Specify start:end:increment.')
parser$add_argument('--set_iter',
action='store',
default=0,
help='Set the iteration counter for the output images when rendering in multiple sessions. Keeps images numerically ordered to make video creation easier.')
args <-parser$parse_args()
# Prep variables for use
infile <- args$infile
outfile <- args$outfile
device <- args$device
movie <- args$movie
cam.zoom <- as.numeric(args$zoom)
ver.angle <- as.numeric(args$vangle)
set_iter <- as.numeric(args$set_iter)
browser <- args$browser
port <- as.numeric(args$port)
from <- as.numeric(strsplit(movie,":")[[1]][1])
to <- as.numeric(strsplit(movie,":")[[1]][2])
increment <- as.numeric(strsplit(movie,":")[[1]][3])
if (outfile == 'None'){
outfile <- basename(file_path_sans_ext(infile))
}
cat("Starting RSelenium server", "\n")
RS_server <- rsDriver(verbose = FALSE)
# Read in and prepare data
df <- read.csv(infile, sep=",", check.names=FALSE, row.names = 1, header = TRUE)
matrix <- as.matrix(df)
scan <- as.numeric(rownames(df))
temp <- as.numeric(colnames(df))
matrix.list <- list(z = matrix,
x = temp,
y = scan)
font.pref <- list(size=18, family="Arial, sans-serif", color="black")
x.list <- list(title = "Temperature (˚C)",
titlefont = font.pref,
ticklen = 20,
tickcolor = "white",
zerolinecolor = "black",
zerolinewidth = 2)
y.list <- list(title = "Wavelength (nm)",
titlefont = font.pref,
ticklen = 20,
tickcolor = "white",
zerolinecolor = "black",
zerolinewidth = 2)
z.list <- list(title = "CD Intensity",
titlefont = font.pref,
ticklen = 20,
tickcolor = "white",
zerolinecolor = "black",
zerolinewidth = 2)
iter = set_iter
for(i in seq(from, to, by=increment)){
iter = iter + 1
theta = i/100
graph <- plot_ly(z =~matrix, x=temp, y=scan, type="surface",
colors= c('black','gray','green'),
colorbar = list(title="CD Intensity",
yanchor="middle",
len=1.5)) %>%
layout(scene=list(xaxis = x.list,
yaxis = y.list,
zaxis = z.list,
camera = list(eye = list(x = cos((i/10))*cam.zoom,
y = sin((i/10))*cam.zoom,
z=ver.angle)
)
)
)
outfile_iter <- paste(outfile, ".", str_pad(iter, 4, pad ="0"), sep = "")
outfile_iter_ext <- paste(outfile_iter, device, sep = ".")
# Render images:
export(p = graph, outfile_iter_ext, RS_server)
if (device == "pdf"){
convert.installed <- system("convert --version", ignore.stdout = TRUE) == 0
if (convert.installed == TRUE){
cat("Calling ImageMagick to convert to formats other than PNG/JPEG", "\n")
cat(sprintf('convert %s %s',
paste(outfile_iter, device, sep = "."),
paste(outfile_iter, "pdf", sep = ".")), "\n")
system(sprintf('convert %s %s',
paste(outfile_iter, "png", sep = "."),
paste(outfile_iter, device, sep = ".")))
} else {
cat("Can't convert to that device. Make sure ImageMagick `convert` is in your PATH.", "\n")
}
}
cat("Outfile:", outfile_iter_ext, '\n')
}
# Kill the webserver
RS_server[["server"]]$stop()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment