Search code examples
rplotlyr-plotly

How to group datapoints independently from coloring in plotly without splitting the legend?


I want to plot multiple points connected by lines in plotly. While there should be exactly one line per id-group (as defined in the dataset), the color of those lines should depend on a different column in the data.

Consider this example data:

 df <- data.frame(
   x = c(1,2,3,4,5,6),
   y = c(0,0,3,1,4,5),
   id= c(1,1,2,2,3,3), # defines belonging to line
   group = c("A","A","A","A","B","B") # defines color of the point and line
 )

if I plot it this way, it kind of works:

 plot_ly(df,type = "scatter", mode = "lines+markers",
         x = ~x,
         y = ~y,
         split = ~id,
         color = ~group)
 

Unfortunately, the legend is also split along split and color:Plot with split legend

I only want it to display the color part of the legend. In this example case the legend would only have two entries. One for "A" and one for "B".

Is there a simple way to do this that I am not seeing here?

Addendum: An id is always linked to one group only. There are no id values, that are shared bewtween multiple different group values


Solution

  • plotly's color parameter will always create traces based on the provided data (just like split, but with colors mapped).

    However, we can combine the separate legend items via legendgroup and display only one of them:

    library(plotly)
    
    DF <- data.frame(
      x = c(1,2,3,4,5,6),
      y = c(0,0,3,1,4,5),
      id= c(1,1,2,2,3,3), # defines belonging to line
      group = c("A","A","A","A","B","B") # defines color of the point and line
    )
    
    fig <- plot_ly(DF, type = "scatter", mode = "lines+markers",
                   x = ~x,
                   y = ~y,
                   split = ~id,
                   color = ~group,
                   name = ~group,
                   legendgroup = ~group) %>%
           layout(showlegend = TRUE) %>%
           style(showlegend = FALSE, traces = 1)
    
    fig
    

    result

    Please check my answer here for a more general approach.