rshinyrglr-carscatter3d

scatter3d ellipsoid argument inside shiny R failing


Two steps forward, one step back. The last weeks I've run into a few issues that I could not solve on my own as a self tought user with 1 year experience in R, but fortunatly there are great people on this site that have helped me a lot! First of all, thanks for that guys.

Seems now that we have found a way to get scatter3d plots into the Shiny App i'm building, and get the left mouse button to work (see my previous questions) I've now come across a bug that I don't understand.

The bug says this: the leading minor of order 3 is not positive definite after a while of puzzling, I found out that it is inside the ellipsoid argument of scatter3d.

running this works fine:

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

colors <- rep("grey", 25)  ### dummy palette of all greys
groups <- as.factor(rep(1:25,2)) ### make 5 categories 

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=F)
    scatter3d(x=cars$speed, y=cars$dist, z=cars$time, surface=FALSE, ellipsoid = FALSE, groups = groups, surface.col = colors)
    par3d(mouseMode = "trackball")
    rglwidget()
  })
})   
shinyApp(ui = ui, server = server)

Switching to ellipsoid = TRUE gives the error and nothing renders in shiny

Running the graph without shiny by just running these lines:

rgl.open(useNULL=F)
    scatter3d(x=cars$speed, y=cars$dist, z=cars$time, surface=FALSE, ellipsoid = TRUE, groups = groups, surface.col = colors)

works as in that it renders inside the rgl window, but still prints the error of course.

changing the number of groups to less than 14 seems to solve it: groups <- as.factor(rep(1:13,5)) groups <- groups[1:50]
gives no error. groups <- as.factor(rep(1:14,5)) groups <- groups[1:50] gives the error..... very strange.

At first I thought it might be linked to the build in nr of colors of scatter3d because up to 8 groups, it colors things automatically without specifying surface.col. As soon as you have 9 groups, you need to give it a palette yourself, but this nr 13 cutoff seems rather awkward....


Solution

  • Your problem is you simply do not have enough data. This is causing it to try and calculate an ellipsoid when it does not have enough points (needs at least 3 per group I imagine). The error message could obviously be better, but it is not wrong, it refers to what is going wrong in the calculation.

    I created a parameterized ncars that is just a bigger re-sampling of your original data, so it ought to look similar.

    Here it is:

    library(rgl)
    library(car)
    library(shiny)
    
    makebigcars <- function(n){
      newspeed <- sample(cars$speed,n,replace=T)
      newdist <- sample(cars$dist,n,replace=T)
      bigcars <- data.frame(speed=newspeed,dist=newdist)
      bigcars$time = bigcars$dist/bigcars$speed
      return(bigcars)
    }
    ncars <- makebigcars(150)
    
    n <- nrow(ncars)
    colors <- rep("grey", n)  ### dummy palette of all greys
    groups <- as.factor(rep(1:5,n))[1:n] ## groups
    
    ui <- fluidPage(
      hr("Scatter3d"),
    
      rglwidgetOutput("plot",  width = 800, height = 600)
    )
    
    server <- (function(input, output) {
    
      output$plot <- renderRglwidget({
        rgl.open(useNULL=F)
        scatter3d(x=ncars$speed, y=ncars$dist, z=ncars$time, surface=FALSE, 
                    ellipsoid = T, groups = groups, surface.col = colors)
        par3d(mouseMode = "trackball")
        rglwidget()
      })
    })   
    shinyApp(ui = ui, server = server)
    

    and here is a plot:

    enter image description here