Search code examples
rplotlyr-plotly

R Plotly 3D: Add Mesh to Scatter plot without inheriting color scheme


Basically I have a scatter 3d Scatter plot with the points in two categories (selected, unselected) which are represented in red and grey. To better visualize the selected volume I want to add a cube with low opacity in blue. However, when I add the mesh for the cube, the cube appears in green and the unselected points in orange instead of grey.

In short: Why is the cube not blue and the unselected points not grey and how can I make them do so?

library(shiny)
library(plotly)


ui <- fluidPage(
  tags$h2("This is my 3D plot."),
  plotlyOutput("Plot3d", width = "1000px", height = "1000px")
)

server <- function(input, output, session){
  output$Plot3d <- renderPlotly ({

    #Defining data frame for scatter
    df_scatter <- data.frame(X_VAL = rnorm(50, mean = 0.5, sd = 0.15),
                             Y_VAL = rnorm(50, mean = 0.5, sd = 0.15),
                             Z_VAL = rnorm(50, mean = 0.5, sd = 0.15),
                             SCATTER_COL = rep("unselected", 50))
    
    #Every point inside of the cube is labeled "selected" 
    for (i in 1:nrow(df_scatter)){

      if (df_scatter$X_VAL[i] < 0.5 && df_scatter$Y_VAL[i] < 0.5 && df_scatter$Z_VAL[i]< 0.5) {
        df_scatter$SCATTER_COL[i] <- "selected"
      }
    }
    df_scatter$SCATTER_COL <- factor(df_scatter$SCATTER_COL, levels = c("selected", "unselected"))
    
    
    #Defining data frame for mesh
    df_mesh <- data.frame(X_VAL = c(0, 0, 0.5, 0.5, 0, 0, 0.5, 0.5),
                          Y_VAL = c(0, 0.5, 0.5, 0, 0, 0.5, 0.5, 0),
                          Z_VAL = c(0, 0, 0, 0, 0.5, 0.5, 0.5, 0.5),
                          MESH_COL = factor(rep("CUBE", 8), levels = c("CUBE")))
    
    
    
    plot_ly()%>%
      add_markers(type = "scatter3d", 
                  mode = "markers", 
                  data = df_scatter, 
                  x = ~X_VAL, 
                  y = ~Y_VAL, 
                  z = ~Z_VAL, 
                  color = ~SCATTER_COL, 
                  colors = c('red', 'grey')) %>%
      
      #Here the trouble starts
      add_trace(type = 'mesh3d',
               data = df_mesh,
               x = ~X_VAL,
               y = ~Y_VAL,
               z = ~Z_VAL,
               i = c(7, 0, 0, 0, 4, 4, 6, 1, 4, 0, 3, 6),
               j = c(3, 4, 1, 2, 5, 6, 5, 2, 0, 1, 6, 3),
               k = c(0, 7, 2, 3, 6, 7, 1, 6, 5, 5, 7, 2),
               color = ~MESH_COL,
               colors = c("blue"),
               inherit = FALSE,
               opacity = 0.1
      )
  })  
}
shinyApp(ui = ui, server=server)



Any help is greatly appreciated.


Solution

  • Try facecolor:

    library(shiny)
    library(plotly)
    #> Loading required package: ggplot2
    #> 
    #> Attaching package: 'plotly'
    #> The following object is masked from 'package:ggplot2':
    #> 
    #>     last_plot
    #> The following object is masked from 'package:stats':
    #> 
    #>     filter
    #> The following object is masked from 'package:graphics':
    #> 
    #>     layout
    
    mycolors <- colours()[2:10]
    ui <- fluidPage(
        tags$h2("This is my 3D plot."),
        plotlyOutput("Plot3d", width = "1000px", height = "1000px")
    )
    
    server <- function(input, output, session){
        output$Plot3d <- renderPlotly ({
            
            #Defining data frame for scatter
            df_scatter <- data.frame(X_VAL = rnorm(50, mean = 0.5, sd = 0.15),
                                     Y_VAL = rnorm(50, mean = 0.5, sd = 0.15),
                                     Z_VAL = rnorm(50, mean = 0.5, sd = 0.15),
                                     SCATTER_COL = rep("unselected", 50))
            
            #Every point inside of the cube is labeled "selected" 
            for (i in 1:nrow(df_scatter)){
                
                if (df_scatter$X_VAL[i] < 0.5 && df_scatter$Y_VAL[i] < 0.5 && df_scatter$Z_VAL[i]< 0.5) {
                    df_scatter$SCATTER_COL[i] <- "selected"
                }
            }
            df_scatter$SCATTER_COL <- factor(df_scatter$SCATTER_COL, levels = c("selected", "unselected"))
            
            
            #Defining data frame for mesh
            df_mesh <- data.frame(X_VAL = c(0, 0, 0.5, 0.5, 0, 0, 0.5, 0.5),
                                  Y_VAL = c(0, 0.5, 0.5, 0, 0, 0.5, 0.5, 0),
                                  Z_VAL = c(0, 0, 0, 0, 0.5, 0.5, 0.5, 0.5))
            
            plot_ly()%>%
                add_markers(type = "scatter3d", 
                            mode = "markers", 
                            data = df_scatter, 
                            x = ~X_VAL, 
                            y = ~Y_VAL, 
                            z = ~Z_VAL, 
                            color = ~SCATTER_COL, 
                            colors = c('red', 'grey')) %>%
                add_trace(type = 'mesh3d',
                          data = df_mesh,
                          x = ~X_VAL,
                          y = ~Y_VAL,
                          z = ~Z_VAL,
                          i = c(7, 0, 0, 0, 4, 4, 6, 1, 4, 0, 3, 6),
                          j = c(3, 4, 1, 2, 5, 6, 5, 2, 0, 1, 6, 3),
                          k = c(0, 7, 2, 3, 6, 7, 1, 6, 5, 5, 7, 2),
                          facecolor = rep("blue", 12),
                          opacity = 0.1
                )
        })  
    }
    shinyApp(ui = ui, server=server)
    

    Created on 2020-07-02 by the reprex package (v0.3.0)