How to render scatter3d inside shiny page instead

2020-03-05 03:55发布

问题:

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.

回答1:

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:



标签: r plot 3d shiny rgl