R plotly - how to update colour in a bubble chart without redrawing the plot in shiny

134 views Asked by At

I would like to update particular bubbles in a plotly bubble chart with a different colour, based on user selection in a shiny app. I do not want to completely the redraw the plot. I attempted to do this by adding a different coloured trace using plotlyProxyInvoke, but I can't work out how to specify the size of the bubble. It seems to just ignore whatever size info I give it.

How it looks:

How it is meant to look:

Is there a correct way to specify size for bubble charts in plotlyProxyInvoke? Or is there some other way to update the colour in the plot without redrawing it?

Below is a minimal example of what I tried.

library(shiny)
library(plotly)

d <- mtcars

ui <- fluidPage(
  fluidRow(column(12, numericInput("rownum", label = "RowID to change bubble colour", value = NULL, min = 1, max = 32))),
  fluidRow(column(12, plotlyOutput("plot")))
)

server <- function(input, output, session) {
  
  output$plot <- renderPlotly({
    plot_ly(d, x = ~wt, y = ~mpg, size = ~disp, type = "scatter", mode = "markers",  fill = ~'',  
            marker = list(sizemode = "diameter", line = list(width = 2, color = "white")))
  })
  
  observeEvent(input$rownum, {
    
    plot_d <- d[input$rownum, ]
    plotlyProxy("plot", session) %>%
      plotlyProxyInvoke("addTraces", list(x = c(plot_d$wt, plot_d$wt),
                                          y = c(plot_d$mpg, plot_d$mpg),
                                          size = c(plot_d$disp, plot_d$disp),
                                          type = "scatter", mode = "markers",  fill = ~'', 
                                          marker = list(sizemode = "diameter", color = "black",
                                                        line = list(width = 2, color = "white"))))
    
  })
  
}

shinyApp(ui, server)
1

There are 1 answers

1
Stéphane Laurent On

I think you have to invoke the restyle method:

library(shiny)
library(plotly)

d <- mtcars

ui <- fluidPage(
  fluidRow(column(12, actionButton("btn", "Change color"))),
  fluidRow(column(12, plotlyOutput("plot")))
)

server <- function(input, output, session) {
  
  output$plot <- renderPlotly({
    plot_ly(d, x = ~wt, y = ~mpg, size = ~disp, type = "scatter", 
            mode = "markers",  fill = ~'', 
            marker = list(
              sizemode = "diameter", 
              line = list(width = 2, color = "white"))
            )
  })
  
  observeEvent(input$btn, {
    plotlyProxy("plot", session) %>%
      plotlyProxyInvoke(
        "restyle", 
        list(marker = list(color = "red", size = mtcars$disp/2))
      )
  })
  
}

shinyApp(ui, server)

That works for the color. However I don't understand what happens for the size. If I put list(marker = list(color = "red", size = mtcars$disp)) then the circles are very bigger than the original ones.


Edit

This is consistent if you set the size in the marker list:

  output$plot <- renderPlotly({
    plot_ly(d, x = ~wt, y = ~mpg, type = "scatter", 
            mode = "markers",  fill = ~'', 
            marker = list(
              size = d$disp,
              sizemode = "diameter", 
              line = list(width = 2, color = "white"))
            )
  })

enter image description here