Faking plotly’s ‘y unified’ tooltip in ggiraph
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.
Problem
A ggiraph tooltip head scratcher (and the fix!)
We settled on ggiraph as our interactive visualisation package for a new Shiny dashboard. The goal was simple: capture the Y-axis value, grouped by the X-axis to display in a tooltip when a user hovers over an element. I’ve used plotly before, and it has a handy “y unified” argument that does this perfectly (see plotly reference). The hitch? ggiraph doesn’t offer that option.
The Solution: This little snag is now sorted! I’m writing this blog post to solidify the lesson for myself and hopefully save others the headache if they run into the same problem. Let’s start with the setup.
# Load packages
library(dplyr)
library(lubridate)
library(stringr)
library(patchwork)
library(glue)
library(ggplot2)
library(ggiraph)
# Set ggplot theme and default palette
theme_set(theme_minimal())
options(ggplot2.discrete.fill="viridis")
# Promise data
data("lakers")
Solution
The below summaries the data and makes use of one of my favourite functions stringr::str_flatten_comma() to create the “y unified” tooltip alongside a few friends in glue & str_replace_all for my use case.
# Summarise data
ppp_top_3 <- lakers |>
filter(period != 5) |>
group_by(period, player) |>
summarise(total_points = sum(points), .groups = "drop_last") |>
slice_max(n = 3, order_by = total_points) |>
# Creating tooltip, adding <br> to neatly format tooltip
mutate(tooltip = glue(
"Total Points<br>",
str_flatten_comma(glue(" - {player} {total_points}"))
) |>
str_replace_all(",", ",<br>")) |>
ungroup()
Plot prep
Before we can see the results let’s codes the plots. For those familiar with ggplot2 you’ll be able to spot the few differences. I think ggiraph's homepage provides a clean, short, and simple overview of the differences.
p <- ppp_top_3 |>
ggplot(aes(x = period, y = total_points, fill = player)) +
geom_col_interactive(position = position_dodge2()) +
labs(title = "Top 3 scoring Lakers players per period (2008-2009 Season)",
subtitle = "No Tooltip",
x = "Period",
y = "") +
theme(plot.title.position = "plot",
legend.position = "right",
legend.title = element_blank())
p_tooltip <- ppp_top_3 |>
ggplot(aes(x = period,
y = total_points,
fill = player,
tooltip = tooltip,
data_id = period)) +
geom_col_interactive(position = position_dodge2()) +
labs(subtitle = "With Tooltip",
x = "Period",
y = "") +
theme(plot.title.position = "plot",
legend.position = "right",
legend.title = element_blank())
plots <- p + p_tooltip + plot_layout(ncol = 2,
axes = "collect",
guides = "collect")
Plot
Try it out!
girafe(
ggobj = plots,
options = list(
opts_hover_inv(css = "opacity:0.2"),
opts_toolbar(saveaspng = FALSE),
opts_zoom(max = 1),
opts_tooltip(
opacity = 0.8,
use_fill = TRUE,
use_stroke = FALSE,
css = "padding:5pt;color:white"
),
opts_selection(type = "none", only_shiny = FALSE),
opts_hover(css = girafe_css(
css = glue::glue("transition: all 0.5s ease;stroke: black; stroke-width: 1px;"),
text = glue::glue("fill-opacity:1;")
))
)
)
Conclusion
The method of creating your tooltip in the data frame ahead of time could even work with plotly and gives you more flexibility on design.
Acknowledgements
r-bloggers.com for the reach, platform, and content
Packages and package maintainer(s):
- dplyr | Hadley Wickham
- lubridate | Vitalie Spinu
- stringr | Hadley Wickham
- patchwork | Thomas Lin Pedersen
- glue | Jennifer Bryan
- ggplot2 | Thomas Lin Pedersen
- ggiraph | David Gohel
R-bloggers.com offers daily e-mail updates about R news and tutorials about learning R and many other topics. Click here if you're looking to post or find an R/data-science job.
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.