Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Shiny RGL Plot3D: Keep Plot View Orientation On Replot

Tags:

plot

r

shiny

rgl

Whenever I do a re-plot on a RGL plot3D it causes the view orientation of the plot to be reset to it's default.

Does anyone know how to save these settings so that I can reapply them after a plot is redrawn. I tried this:

# save settings
pp <- par3d(no.readonly=TRUE)

# initialize plot
plot3d(c(), c(), c(), "", "", "")

# Replot data here
# ...

# restore settings
par3d(pp)

However, this did not restore the plot orientation.

EDIT: printing out the result of par3d() shows that the values are not getting updated as the plot is rotated and zoomed, so I'm guessing this is the issue. It might be an issue only with ShinyRGL if people have gotten it to work with rgl.

like image 286
bcorso Avatar asked Apr 03 '15 15:04

bcorso


2 Answers

Problem

The problem with the rgl plot is that it does not change the par3d rotation matrix as you rotate the plot (same for zoom). Additionally, I can't find any documentation that hints to where the rotation/zoom state is stored. Thus, we have no information on the current state of the plot, and saving/loading that state is impossible.

Solution

My solution is to use sliders to manually control the rotation/zoom of the plot; and when those sliders change, we manually update the par3d rotation matrix.

While I really don't like this solution because it takes away a lot of the convenience of plot rotation/zoom, it's the only way I was able to maintain the rotation/zoom state after updates.

  1. I defined 3 sliders representing the rotation around the X, Y, Z axes, and an additional slider representing the zoom ZOOM.
  2. Instead of rotating/zooming on the plot, use the sliders.
  3. on Slider Change: update the rotations directly in par3d
  4. When updating the plot (e.g. new data), the method I described in the original Question to save/load the state will now work because par3d contains the rotation/zoom state.
like image 182
bcorso Avatar answered Oct 27 '22 08:10

bcorso


I don't know whether this changed in recent rgl versions, but for me it is working. I am using rgl version 0.95.1441.

Define a function that loads data and calls plot3d() (here it uses random data):

library(rgl)

newRGLrandom <- function(){
  n <- 10
  x <- sort(rnorm(n))
  y <- rnorm(n)
  z <- rnorm(n) + atan2(x, y)
  plot3d(x, y, z, col = rainbow(n), size=10)
}

The plot starts in the standard orientation:

newRGLrandom()

enter image description here

Then I rotate it by hand in the rgl window:

enter image description here

When I call the newRGLrandom() function again it shows the new plot in the same rotation:

newRGLrandom()

enter image description here

I am also able to save the user rotation:

uM <- par3d()$userMatrix

and move the plot to the stored rotation later on:

par3d(userMatrix = uM)

Saving the whole par3d also works for me:

pp <- par3d(no.readonly=TRUE)
par3d(pp)

I don't know why it didn't work when you tried it. Maybe it is OS specific? My sessionInfo() is the following:

> sessionInfo()
R version 3.2.2 (2015-08-14)
Platform: x86_64-apple-darwin13.4.0 (64-bit)
Running under: OS X 10.11.6 (El Capitan)

locale:
[1] de_DE.UTF-8/de_DE.UTF-8/de_DE.UTF-8/C/de_DE.UTF-8/de_DE.UTF-8

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
[1] rgl_0.95.1441

loaded via a namespace (and not attached):
[1] tools_3.2.2
like image 25
nnn Avatar answered Oct 27 '22 06:10

nnn