✊🏿 Black Lives Matter. Please consider donating to Black Girls Code today.
🐇 Announcing Dash VTK for 3d simulation graphics. Check out the March webinar.

Is it possible to control the color of mesh3d object added with plotlyProxyInvoke?

Again me with the same question, especially because I am not sure is it a bug or defined behaviour. This time I prepared an example with reproducible code. As a starting point, I have a complex figure (initial_plot) that include the surface plot fused with two mesh3d objects, all together plotted within a shiny app. The next step in data processing is the enlarging of mesh3d objects, which is achieved in a loop. After that, the old objects on the plot need to be replaced/updated to a new size. The only way I found it works quite fast and reliable is by adding new traces and immediately deleting the old ones. However, the problem with plotlyProxyInvoke(“addTraces”) is that I cannot find a way to control the colour of newly added mesh3d objects. When the growing event is triggered with the “start” button, objects grow just fine and fast, but their facecolor keeps changing after each iteration, making my plot looks psychedelic. I tried to overcome this by adding several “color” arguments to the list of arg passed to plotlyProxyInvoke(“addTraces”, list ()) (color, facecolor, fill …), but without success. Any ideas about how the color could be stabilised? Or how this growing effect could be produced in completely another way, that includes persistent facecolor? Here is a minimal reproductive code that would help you to see and handle the problem:

library(shiny)
library(plotly)
library(magrittr)

initial_plot <- plot_ly(z = ~volcano, type = "surface")
initial_plot <- initial_plot %>% add_trace(type = 'mesh3d',
                               x = c(0, 0, 33, 33, 0, 0, 33, 33),
                               y = c(0, 33, 33, 0, 0, 33, 33, 0),
                               z = c(0, 0, 0, 0, 33, 33, 33, 33),
                               i = c(7, 0, 0, 0, 4, 4, 6, 6, 4, 0, 3, 2),
                               j = c(3, 4, 1, 2, 5, 6, 5, 2, 0, 1, 6, 3),
                               k = c(0, 7, 2, 3, 6, 7, 1, 1, 5, 5, 7, 6),
                               intensity = 1,
                               colorscale = list(c(0,'dimgrey'),
                                                 c(0.33,'dimgrey'),
                                                 c(0.66, 'dimgrey'),
                                                 c(1, 'dimgrey')), 
                               showscale=F
                               )
initial_plot <- initial_plot %>% add_trace(type = 'mesh3d',
                                           x = c(80, 70, 70, 80, 70, 70, 80, 80),
                                           y = c(90, 70, 70, 90, 90, 80, 80, 80),
                                           z = c(0, 0, 0, 0, 33, 33, 33, 33),
                                           i = c(7, 0, 0, 0, 4, 4, 6, 6, 4, 0, 3, 2),
                                           j = c(3, 4, 1, 2, 5, 6, 5, 2, 0, 1, 6, 3),
                                           k = c(0, 7, 2, 3, 6, 7, 1, 1, 5, 5, 7, 6),
                                           intensity = 1,
                                           colorscale = list(c(0,'forestgreen'),
                                                             c(0.33,'forestgreen'),
                                                             c(0.66, 'forestgreen'),
                                                             c(1, 'forestgreen')), 
                                           showscale=F)

# Define UI for application that draws a histogram
ui <- fluidPage(

  actionButton(inputId = "start", 
               label = "start",
               style = "color: #fff; background-color: #337ab7; border-color: #2e6da4"),
  plotlyOutput("myPlot",
               width = "1000px",
               height = "900px")
  
)

# Define server logic required to draw a histogram
server <- function(input, output, session) {
  output$myPlot <- renderPlotly({
    initial_plot
  })
  
  observeEvent(input$start, {
    
  for(i in 1:15) {
    plotlyProxy("myPlot", session) %>% plotlyProxyInvoke(method = "addTraces", list(type='mesh3d', color= I("dimgrey"),
                                                                                    x = c(0, 0, 33+i, 33+i, 0, 0, 33, 33),
                                                                                    y = c(0, 33, 33+i, 0+i, 0, 33, 33, 0),
                                                                                    z = c(0, 0, 0, 0, 33, 33, 33, 33),
                                                                                    i = c(7, 0, 0, 0, 4, 4, 6, 6, 4, 0, 3, 2),
                                                                                    j = c(3, 4, 1, 2, 5, 6, 5, 2, 0, 1, 6, 3),
                                                                                    k = c(0, 7, 2, 3, 6, 7, 1, 1, 5, 5, 7, 6))
                                                         )
    plotlyProxy("myPlot", session) %>% plotlyProxyInvoke("deleteTraces", 1)
    plotlyProxy("myPlot", session) %>% plotlyProxyInvoke(method = "addTraces", list(type='mesh3d', 
                                                                                    x = c(80, 70, 70, 80, 70, 70, 80, 80),
                                                                                    y = c(90, 70, 70, 90, 90, 80, 80, 80),
                                                                                    z = c(0+i, 0+i, 0+i, 0+i, 33+i, 33+i, 33+i, 33+i),
                                                                                    i = c(7, 0, 0, 0, 4, 4, 6, 6, 4, 0, 3, 2),
                                                                                    j = c(3, 4, 1, 2, 5, 6, 5, 2, 0, 1, 6, 3),
                                                                                    k = c(0, 7, 2, 3, 6, 7, 1, 1, 5, 5, 7, 6), 
                                                                                    intensity = 1,
                                                                                    colorscale = list(c(0,'forestgreen'),
                                                                                                      c(0.33,'forestgreen'),
                                                                                                      c(0.66, 'forestgreen'),
                                                                                                      c(1, 'forestgreen')), 
                                                                                    showscale=F)
                                                         )
    plotlyProxy("myPlot", session) %>% plotlyProxyInvoke("deleteTraces", 1)
    
    
  }
  })
}

# Run the application 
shinyApp(ui = ui, server = server)

plotly