Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

create a video from plotly 3d chart

Tags:

r

plotly

I'm wondering if anyone knows of a way to export plotly 3d charts as a video (more specifically if this can be done natively or requires bodging)?

Exporting a static image is simple, and exporting the interactive plots is fine for embedding in HTML etc.

Lets say I have a 3D chart that I want so simply rotate slowly, this seems like it could be pretty straight forward if the image can be rotated a given interval, an image taken, rotated further ad infinitum, perhaps in a loop - but I'm wondering if this isn't somehow supported natively?

Anyone know of a good strategy?

Solution ideally for R/RStudio, but since plotly is cross-platform, any solutions considered.

like image 748
Joe Healey Avatar asked Aug 30 '16 13:08

Joe Healey


1 Answers

For future reference:

The key to being able to iterate multiple perspectives turns out to lie in the camera control "eye", the plotly help centre pointed me toward this:

https://plot.ly/r/reference/#layout-scene-camera

camera = list(eye = list(x = 1.25, y = 1.25, z = 1.25))) #1.25 is default

This is kind of answered here, though searching for my specific query as above didn't find it:

enter link description here

I've used a for loop in the script to pass iterators to a trigonometric function that plots out a circle for the camera co-ordinates, rendering a new image at each step.

(x,y) = cos(theta) + sin(theta)

enter image description here

The eventual code looked like this:

# assume dataset read in, manipulated and given as a matrix in "matrix"
matrix.list <- list(x = temp, y = scan, z = matrix)

font.pref <- list(size=12, family="Arial, sans-serif", color="black")

x.list <- list(title = "X", titlefont = font.pref)
y.list <- list(title = "Y", titlefont = font.pref)
z.list <- list(title = "Z",titlefont = font.pref)

zoom <- 2

for(i in seq(0,6.3,by=0.1){
# 6.3 is enough for a full 360 rotation

 outfile <- paste(file,"plot",i, sep = "_")
 graph <- plot_ly(matrix.list, x = temp, y = scan, z = z,
                  type="surface") %>%
                  layout(scene=list(xaxis = x.list,
                                    yaxis = y.list,
                                    zaxis = z.list,
                                    camera = list(eye = list(x = cos(i)*zoom, y = sin(i)*zoom, z= 0.25))))

# The above camera parameters should orbit 
# horizontally around the chart.
# The multiplier controls how far out from
# from the graph centre the camera is (so 
# is functionally a 'zoom' control).

  graph
  plotly_IMAGE(graph, username="xxx", key="xxx",
               out_file = paste(outfile,"png", sep="."))
}

NB Number of files and the resolution of them could end up taking up a fair amount of space.

NB 2 I had forgotten while constructing this that plotly's free API limits you to 50 API calls per day, so if you want to render a video, adjust your frames etc, accordingly...

like image 154
Joe Healey Avatar answered Oct 28 '22 12:10

Joe Healey