'Is there a way to add the bin range label into the tooltip for a histogram using ggplotly in R?

library(tidyverse)
library(ggplot2)
library(plotly)

data(mpg)

ggplotly(
mpg %>% 
  ggplot(aes(x=hwy)) +
  geom_histogram(), 
tooltip = ("all"))

When you hover over the bar, I'd like for the tooltip to show the start and stop of the bin (e.g. 20-21)



Solution 1:[1]

Thanks for the simple plot_ly answer. For other reasons, I'd like to preserve ggplot. Here's one possible solution I came up with that extracts the histogram elements from ggbuild_plot() and plots them as a bar graph.

ggplotly(
ggplot_build(
  mpg %>% 
    ggplot(aes(x=hwy)) +
    geom_histogram()
)$data[[1]] %>% 
  ggplot(aes(x=factor(x), y = count, text = paste0("range: ",round(xmin, 1), " - ", round(xmax,1)))) + 
  geom_bar(stat="identity") + 
  theme(axis.text.x = element_blank()),
tooltip = c("text"))

enter image description here

Solution 2:[2]

In case if it's not mandatory to use ggplot2, an easier fix is to use basic histogram plot:

plot_ly(x = mpg$hwy, type = "histogram")

enter image description here

Solution 3:[3]

I ran into this issue but also needed to label the x-axis with bin ranges, so I built on your answer (which was great!)

I broke it down into three steps: using ggplot to create the first histogram that generates the bin ranges, using ggplot again to create the second histogram that uses those ranges for labels, and then using plotly to make it interactive.

Here's a reprex that should be customizable for other use cases. Once you get the gist you can ditch the intermediate variables and run the whole thing at once with pipes.

library(tidyverse)
library(plotly)

# step 1: create a ggplot histogram, extract the internal data
plot_step1 <- ggplot_build(
  mpg %>% 
    ggplot() + 
    geom_histogram(aes(x=hwy),
                   bins = 11 # set histogram parameters here
    )
)$data[[1]]

# step 2: create a new plot, using the derived xmin and xmax values from the 
# first plot, and set the labels and axes
plot_step2 <- plot_step1 %>% {
  ggplot(data = .,
         aes(x=factor(x), 
             y = count, 
             text = sprintf("Count: %d\nRange (MPG): %.1f-%.1f", y, round(xmin,1), round(xmax,1)))) + 
    scale_x_discrete(labels = sprintf("%.1f-%.1f", .$xmin, .$xmax)) + 
    geom_bar(stat="identity", 
             width = 1) + 
    labs(title = "Histogram: Highway Miles per Gallon",
         x = "MPG",
         y = "Count") +
    theme_minimal() +
    theme(axis.text.x = element_text(angle = 45 ))
}

# step 3: make this new plot interactive
plotly::ggplotly(plot_step2, tooltip = c("text"))

Solution 4:[4]

A solution using library(ggiraph):

library(tidyverse)
library(ggplot2)
library(ggiraph)

p1 <- mpg %>% 
  ggplot(., aes(x=hwy)) +
  geom_histogram_interactive(bins = 20, aes(tooltip =  paste0("[",round(..xmin..,2),",",round(..xmax..,2),"] count: ",..count..)))

ggiraph(ggobj = p1)

Example

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Tyler Knight
Solution 2 massisenergy
Solution 3 Christopher Belanger
Solution 4 Luis Zambrano