Inconsistent colors with PlotlyProxy for doubles and integers

I'm using the wonderful proxy options of plotly in shiny, and I'm having trouble with restyling the size of the markers:
When I want to resize the markers proxy plotly changes the color of the markers for multiple traces. The weird thing is that it happens when the variable is an integer, but when I tried to do the same thing with a double it worked fine!

I made a reprex, this shiny app includes both cases:

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
library(ggplot2)
library(shiny)
set.seed(123)

vec1 <- rnorm(5)
vec2 <- rnorm(5)
x_int <- 1:5
x_dbl <- runif(5)

dat <- data.frame(y = c(vec1, vec2), x_int = rep(x_int, 2), x_dbl = rep(x_dbl, 2), cat = c(rep("vec1", 5), rep("vec2", 5)))


pltly_int <- ggplotly(
  dat %>%
    ggplot(aes(x = x_int, y = y, group = cat, color = cat)) +
    geom_point() +
    geom_line() +
    theme_bw() +
    scale_color_manual(values = c("yellow", "red"))
)

pltly_dbl <- ggplotly(
  dat %>%
    ggplot(aes(x = x_dbl, y = y, group = cat, color = cat)) +
    geom_point() +
    geom_line() +
    theme_bw() +
    scale_color_manual(values = c("yellow", "red"))
)


ui <- fluidPage(

  titlePanel("Just a RepRex"),

  sidebarLayout(
    sidebarPanel(
      sliderInput("Numbers",
        "Choose a Number",
        min = 1,
        max = 5,
        value = 1
      )
    ),

    mainPanel(
      plotlyOutput("int_plot", height = "200px"),
      plotlyOutput("dbl_plot", height = "200px")
    )
  )
)

server <- function(input, output, session) {
  output$int_plot <- plotly::renderPlotly({
    pltly_int
  })

  output$dbl_plot <- plotly::renderPlotly({
    pltly_dbl
  })

  observe({
    idx <- input$Numbers
    size <- rep(5, 5)
    size[idx] <- 10

    plotly::plotlyProxy("int_plot", session) %>%
      plotly::plotlyProxyInvoke("restyle", list(marker = list(size = size)))

    plotly::plotlyProxy("dbl_plot", session) %>%
      plotly::plotlyProxyInvoke("restyle", list(marker = list(size = size)))
  })
}

shinyApp(ui = ui, server = server)

Hi @Uriah. It is an interesting behaviour of plotly but it was not about the difference between integer and double. It is about the x axis value is ordered or not. You can try the following code ordered the x_dbl and the colours was correct again. However, I still can't explain the reason. Hope others can provide the answer.

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
library(ggplot2)
library(shiny)
set.seed(123)

vec1 <- rnorm(5)
vec2 <- rnorm(5)
x_int <- 1:5
x_dbl <- runif(5)
x_dbl <- x_dbl[order(x_dbl)]

dat <- data.frame(y = c(vec1, vec2), x_int = rep(x_int, 2), x_dbl = rep(x_dbl, 2), cat = c(rep("vec1", 5), rep("vec2", 5)))


pltly_int <- ggplotly(
  dat %>%
    ggplot(aes(x = x_int, y = y, group = cat, color = cat)) +
    geom_point() +
    geom_line() +
    theme_bw() +
    scale_color_manual(values = c("yellow", "red"))
)

pltly_dbl <- ggplotly(
  dat %>%
    ggplot(aes(x = x_dbl, y = y, group = cat, color = cat)) +
    geom_point() +
    geom_line() +
    theme_bw() +
    scale_color_manual(values = c("yellow", "red"))
)


ui <- fluidPage(
  
  titlePanel("Just a RepRex"),
  
  sidebarLayout(
    sidebarPanel(
      sliderInput("Numbers",
                  "Choose a Number",
                  min = 1,
                  max = 5,
                  value = 1
      )
    ),
    
    mainPanel(
      plotlyOutput("int_plot", height = "200px"),
      plotlyOutput("dbl_plot", height = "200px")
    )
  )
)

server <- function(input, output, session) {
  output$int_plot <- plotly::renderPlotly({
    pltly_int
  })
  
  output$dbl_plot <- plotly::renderPlotly({
    pltly_dbl
  })
  
  observe({
    idx <- input$Numbers
    size <- rep(5, 5)
    size[idx] <- 10
    
    plotly::plotlyProxy("int_plot", session) %>%
      plotly::plotlyProxyInvoke("restyle", list(marker = list(size = size)))
    
    plotly::plotlyProxy("dbl_plot", session) %>%
      plotly::plotlyProxyInvoke("restyle", list(marker = list(size = size)))
  })
}

shinyApp(ui = ui, server = server)

2 Likes

Thank you so much! How did you realize that this was the problem?
And another question, it seems that the opacity changes too. Why?

@Uriah. It seems the plotlyProxyInvoke have some default settings. Define your own opacity by adding the marker list with opacity argument to get rid of this.

plotly::plotlyProxy("int_plot", session) %>%
      plotly::plotlyProxyInvoke("restyle", list(marker = list(size = size, opacity = 1)))
    
    plotly::plotlyProxy("dbl_plot", session) %>%
      plotly::plotlyProxyInvoke("restyle", list(marker = list(size = size, opacity = 1)))
1 Like

Thanks, I did exactly that! I also changed the width of the line to zero.

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.