Search code examples
rggplot2plotlyr-plotly

Conditionally coloring segments in plotly incorrectly rendering in legend when turned off


I have a function which generates a plot in which the user can specify whether to color the line segments according to a grouping variable:

## libraries
library(tidyverse)
library(plotly)

## data
df <- data.frame(grp = c("a", "b"),
                 val_start = c(1, 2),
                 val_end = c(5, 6))

df_long <- df %>% 
  pivot_longer(cols = -grp, names_to = "metric", values_to = "val")

## function
plot_func <- function(plot_color) {
  ## create main plot object
  plot_obj <- df %>% 
    plot_ly()
  ## generate colored/non-colored segments depending on user selection
  if(plot_color == T) {
    plot_obj <- plot_obj %>% 
      add_segments(x = ~val_start,
                   xend = ~val_end,
                   y = ~grp,
                   yend = ~grp,
                   color = ~grp,
                   colors = c("a" = "red", "b" = "blue"))
  } else  {
    plot_obj <- plot_obj %>% 
      add_segments(x = ~val_start,
                   xend = ~val_end,
                   y = ~grp,
                   yend = ~grp)
  }
  ## generate primary colors
  plot_obj %>% 
    add_markers(inherit = F,
                data = df_long,
                x = ~val,
                y = ~grp,
                showlegend = F,
                marker = list(color = "green")) %>% 
    ## generate goal marker
    add_markers(name = "goal",
                x = 4,
                y = ~grp,
                marker = list(color = "black"))
}

As shown below, the function works correctly when the user choses to color the plot:

## render plot
plot_func(plot_color = T)

enter image description here

However, when the user choses not to color the plot, the function annoyingly generates a legend trace for the non-colored line, where all I would like to be shown is the goal marker legend.

## render plot
plot_func(plot_color = F)

enter image description here

Does anyone know how to fix this? I've tried specifying showlegend = T or showlegend = F in each of the respective traces, but when I do that, the legend appears when color is turned on, but then disappears completely when color is turned off.


Solution

  • You need to "globally" activate showlegend via layout(showlegend = TRUE) for your plot_obj:

    ## libraries
    library(tidyr)
    library(plotly)
    
    ## data
    df <- data.frame(grp = c("a", "b"),
                     val_start = c(1, 2),
                     val_end = c(5, 6))
    
    df_long <- df %>% 
      pivot_longer(cols = -grp, names_to = "metric", values_to = "val")
    
    ## function
    plot_func <- function(plot_color) {
      ## create main plot object
      plot_obj <- df %>% 
        plot_ly() %>% layout(showlegend = T)
      ## generate colored/non-colored segments depending on user selection
      if(plot_color == T) {
        plot_obj <- plot_obj %>% 
          add_segments(x = ~val_start,
                       xend = ~val_end,
                       y = ~grp,
                       yend = ~grp,
                       color = ~grp,
                       colors = c("a" = "red", "b" = "blue"))
      } else  {
        plot_obj <- plot_obj %>% 
          add_segments(x = ~val_start,
                       xend = ~val_end,
                       y = ~grp,
                       yend = ~grp,
                       showlegend = F)
      }
      ## generate primary colors
      plot_obj %>% 
        add_markers(inherit = F,
                    data = df_long,
                    x = ~val,
                    y = ~grp,
                    showlegend = F,
                    marker = list(color = "green")) %>% 
        ## generate goal marker
        add_markers(name = "goal",
                    x = 4,
                    y = ~grp,
                    marker = list(color = "black"))
    }
    
    plot_func(plot_color = F)
    

    result