Home > Back-end >  How to customize hover window in plotly?
How to customize hover window in plotly?

Time:06-04

My df has two numerical variables (positive and negative values) and 2 categorical variables. since I want to plot negative bars with same coloured shape/boundaries I specify colours manually in the dataframe and use code below. Howvwer when I move mouse around bars, information is not shown properly, so can I customize hover in ggplotly?

df <- data.frame(model  = c("A","B","C","D","B","C"),
                  category = c("origin", "origin","origin","abroad","abroad","abroad"),
                 pos = c(40,50,45,100,105,80),
                 neg = c(-10,-5,-4,-16,-7,-2),
                 Colour = c("chocolate","deeppink4","yellow","steelblue3","deeppink4","yellow"))

Colour <- as.character(df$Colour)
Colour <- c(Colour,"white")
names(Colour) <- c(as.character(df$model),"white")



df <- df %>% pivot_longer(., cols=c('pos','neg'),
                           names_to = 'sign') %>% 
  mutate(Groups = paste(category, model),
         sign = factor(sign, levels = c("neg", "pos")))


plot <- ggplot()  
  # plot positive with fill and colour based on model
  geom_col(aes(value, tidytext::reorder_within(model, value, category),
               fill = model, color = model), 
           data = df[df$sign == "pos", ],
           position = "stack")  
  # plot negative with colour from based on model, but fill fixed as "white"
  geom_col(aes(value, tidytext::reorder_within(model, value, category),
               color = model), 
           data = df[df$sign == "neg", ], 
           fill = "white",
           position = "stack")  
  # the rest is same as OP's code
  tidytext::scale_y_reordered()  
  labs(fill = "model")  
  facet_grid(category ~ ., switch = "y",scales = "free_y")  
  theme(axis.text.x = element_text(angle = 90),
        strip.background = element_rect(fill = "white"),
        strip.placement = "outside",
        strip.text.y.left = element_text(angle = 0),
        panel.spacing = unit(0, "lines"))   
  theme(legend.position="none")   
  labs( title = "BarPlot",
        subtitle = "changes",
        y = " ")


ggplotly(plot)

enter image description here

CodePudding user response:

I don't know exactly how you want your labels to look. I tried to provide enough code comments so that you could tailor this as you see fit.

To change this plot, I started with using plotly_build on the ggplot object. Then I extracted the important elements from the existing text from each trace: the model, category, and values. Then I reassembled the information and injected it back into the plot.

plt <- plotly_build(plot)

invisible(
  lapply(1:length(plt$x$data),
         function(i){
           tx <- plt$x$data[[i]]$text
           tr <- strsplit(tx, "<br />")
           mo <- strsplit(tr[[1]][3], ": ")[[1]][2]  # extract the model
           ca <- strsplit(tr[[1]][2], "___")[[1]][2] # extract the category
           va <- strsplit(tr[[1]][1], ": ")[[1]][2]  # extract the value
           str <- paste0("Model: ", mo, "<br />",
                         "Category: ", ca, "<br />",
                         "Value: ", va)
           plt$x$data[[i]]$text <<- str          # update the plot object
         })
)

plt

enter image description here

enter image description here

  • Related