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"))