Search code examples
rplotlyr-plotly

how to change order of R plotly hover labels with "x unified" mode


I'm looking to see if there's a way to change the order of the hoverlabels when using hovermode = "x unified" in the newest version of the R package of plotly (4.9.3). Alternatively, is it possible to revert back to the way the old version of plotly displayed the hoverlabels while still using the current version of the plotly package? From a data visualization perspective, the old way is much clearer in my opinion.

I've included a minimum reproducible example below. When I run this using plotly v4.9.2.1, I get the result shown in Figure A and when I run it in plotly v4.9.3, I get the result shown in Figure B. The benefits to Figure A over Figure B are:

  • Figure A labels are in descending order relative to the data on each line at the time specified. Also this is reactive to the time period, so if one line moves above another at a different time period, the relative positioning of the label also moves to reflect the ordering of the data. You can see in Figure B that the dark green (y1) line has the lowest value (66) yet it is shown at the top of the hoverlabel box. In figure B, the y1 label is at the bottom.
  • Figure A labels are attached to the individual lines, so its easier to see the hovertext as it applies to the line in question

Figure A:

enter image description here

Figure B:

enter image description here

Code:

library(plotly)
library(tidyr)

df <- data.frame(Date = seq(as.Date("2018-01-01"),
                         as.Date("2021-01-01"),
                         by = "months"),
                 stringsAsFactors = F)
df$y1 <- seq(0, 100, length.out = nrow(df))
df$y2 <- seq(0, 600, length.out = nrow(df))
df$y3 <- seq(0, 300, length.out = nrow(df))
df$y4 <- seq(0, 200, length.out = nrow(df))
df <- df %>%
  pivot_longer(cols = -Date,
               names_to = "yname",
               values_to = ) %>%
  arrange(yname, Date)
  

mycols <- c("#006633", "#70AD47", "#1F4E78", "#2F75B5", "#C65911", "#EF8C4F", 
            "#C00000", "#FF8B8B", "#7030A0", "#9966FF")
mycols <- mycols[1:length(unique(df$yname))]

p <- plot_ly()

p <- p %>%
  add_trace(data = df,
            x = ~Date,
            y = ~value,
            text = ~yname,
            hovertemplate = paste('<b>%{text}</b>',
                                  '<br>%{x}',
                                  '<br>%{y}',
                                  '<extra></extra>'),
            color = ~yname, colors = mycols,
            name = ~yname, yaxis = "y",
            type = "scatter", mode = "lines",
            showlegend = T)

p <- p %>%
  layout(hovermode = "x unified",
         legend = list(x = 1.12, y = .5, xanchor = "left"),
         yaxis = list(fixedrange = T),
         xaxis = list(title = "",
                      fixedrange = T,
                      hoverformat = "%b %d, %Y"),
         showlegend = T)
p

Solution

  • Two answers:

    1. the ordering of traces in the unified hoverlabel is always the same, regardless of the relative Y values of the traces. The order is the same as in the legend, so it will follow the ordering of the colors.
    2. You can revert to the previous behavior with hovermode = "x" rather than hovermode = "x unified"