Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to add custom hovertext in R plotly to two series that reference each other

Tags:

r

plotly

I currently have plotly code (see code below) that produces outputs that look like this:

Current

Whereas what I want to produce will be more like this:

enter image description here

i.e. I would like custom text hoverinfo that, for either series, shows the corresponding information for the other series at the same time, and reports on which is higher or lower.

Code to produce the first image:

require(tidyverse)
require(plotly)

data("beavers")

beaver_tidy <- beaver1 %>% 
  mutate(label = "a") %>% 
  bind_rows(
    beaver2 %>% 
      mutate(label = "b")
  ) %>% 
  mutate(daytime  = day * max(time) + time) %>% 
  as_tibble()


beaver_tidy %>% 
  group_by(label) %>% 
  plot_ly(
    x = ~ time, y = ~temp, color = ~label
  ) %>% 
  add_lines(
  )

I would like to be able to set the hoverinfo argument in plot_ly or add_lines to "text", and then add a text argument to adapt the above code to produce the mocked-up image shown above.

like image 896
JonMinton Avatar asked Jul 11 '19 12:07

JonMinton


1 Answers

A slightly hacky solution but it works with your example. It might be worth breaking the pipe down to see how the character variables are formed.

library(tidyverse)
library(plotly)
library(glue)

beaver_tidy %>%
  group_by(time) %>%
  #utilise glue to add temperature value to a string
  mutate(main_label = glue("{label} value is {temp}"),
  #now add another variable with the opposite value (with conditions)
  opp_label = case_when(
    #n() counts the number of rows in the time group
    label == "a" & n() == 2 ~ lead(main_label),
    label == "b" & n() == 2 ~ lag(main_label),
       n() == 1 ~ ""),
     #add a string with difference calculated (gives some NA values)
     diff = glue("difference is {round(temp - lead(temp),2)}"),
     #combine strings into one variable with conditions
     comb = case_when(
       diff == "difference is NA" & n() == 1 ~ str_c(main_label, 
                                                     "<br>",
                                                     "No corresponding value", 
                                                      sep = " "),
       diff == "difference is NA" & n() == 2 ~ str_c(main_label, 
                                                     "<br>",
                                                     opp_label, 
                                                     "<br>",
                                                     lag(diff),
                                                     sep = " "),
       TRUE ~ str_c(main_label, 
                    "<br>",
                    opp_label,
                    "<br>",
                     diff, 
                     sep = " ") )) %>%
#and pipe into the original plot
group_by(label) %>% 
plot_ly(x = ~ time, 
        y = ~temp, 
        color = ~label) %>% 
add_lines() %>% 
#add in the hover text
add_trace(x = ~ time, 
          y = ~temp, 
          text = ~comb, 
          hoverinfo = "text")

This give the following output

like image 177
davidhen Avatar answered Nov 15 '22 09:11

davidhen