Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to render scatter3d inside shiny page instead of popup

Tags:

plot

r

3d

shiny

rgl

I'm looking at implementing 3D interactive plots in my shiny App, and so far I've been using plotly. However, plotly has one major disadvantage, it's extremely slow when rendering. I've done checks, and the whole creation of updated outplot$plot <- renderPlotly ({.....}) and plotlyOutput("plot") takes less than 0.5 seconds, despite the large data set involved. This is a know issue for years but still seems to be current.

Hence, I'm looking to use a package called car, also because it has many options, some which I particularly want that are not available in other packages. Info on the car package is here: http://www.sthda.com/english/wiki/amazing-interactive-3d-scatter-plots-r-software-and-data-visualization The problem is that it renders in a separate popup window rather than inside the shiny app, and I want to have it inside it, or even better, add a button that allow the user to have it as a popup, but only when asked. However, i can't figure out how to jam the bugger into the actual shiny page.

Here is my minimal example with a single text element and the graph code that (in my case) keeps appearing in a separate window rather than in the app.

install.packages(c("rgl", "car", "shiny"))

library("rgl")
library("car")
library(shiny)

cars$time <- cars$dist/cars$speed


ui <- fluidPage(
  hr("how do we get the plot inside this app window rather than in a popup?"),

  plotOutput("plot",  width = 800, height = 600)
  )


server <- (function(input, output) {


  output$plot <- renderPlot({
    scatter3d(x=cars$speed, y=cars$dist, z=cars$time, surface=FALSE, ellipsoid = TRUE)
    })
})


shinyApp(ui = ui, server = server)

There is also this package, scatterplot3d but that's not interactive http://www.sthda.com/english/wiki/scatterplot3d-3d-graphics-r-software-and-data-visualization

And there are some RGL packages but they have the same issue (seperate window) and don't offer the options I am lookign for.

like image 846
Mark Avatar asked May 21 '17 18:05

Mark


Video Answer


1 Answers

You need to use an rglwidget which takes the last rgl plot and puts in in an htmlwidget. It used to be in a separate package, but it has recently been integrated into `rgl.

Here is the code to do this:

library(rgl)
library(car)
library(shiny)

cars$time <- cars$dist/cars$speed

ui <- fluidPage(
  hr("how do we get the plot inside this app window rather than in a popup?"),

  rglwidgetOutput("plot",  width = 800, height = 600)
)

server <- (function(input, output) {

  output$plot <- renderRglwidget({
    rgl.open(useNULL=T)
    scatter3d(x=cars$speed, y=cars$dist, z=cars$time, surface=FALSE, ellipsoid = TRUE)
    rglwidget()
  })
})   
shinyApp(ui = ui, server = server)

Yielding this:

enter image description here

like image 96
Mike Wise Avatar answered Nov 16 '22 04:11

Mike Wise