Interactive plots with ggiraph


June 29, 2023


ggiraph logo

ggiraph allows for the creation of interactive plots in documents that will output as HTML or in Shiny. In static HTML pages, ggiraph allows for tooltips, mouseover highlighting, and JavaScript on click. In Shiny documents there is additional interactivity available—but since this document is static HTML, I won’t cover these here.

(For more details, see the ggiraph overview, and for even more details, see the ggiraph book; some examples here come from those sources.)

(You may also be interested in the plotly package as another option for adding interactivity to plots.)

Simple example

As a simple example, here is a plot of the palmerpenguins dataset, showing bill_depth_mm vs. bill_length_mm; species are shown by color, and hovering over a point shows which island the sample was collected on (and highlights all other points from that island):

library(palmerpenguins) # Load penguins dataset

plot_1 <- penguins |> 
    x = bill_depth_mm, y = bill_length_mm,
    tooltip = paste("Island:", island),
    data_id = island, color = species
    )) +
     hover_nearest = TRUE

girafe(ggobj = plot_1)

The data_id argument is how items will be grouped for tooltips and hover effects—here, we want all the dots from the same island to behave together.

Note, too, the ggobj argument to girafe(). The actual first argument to girafe() is not a ggplot object; this means the ggobj argument needs to be called explicitly, and also makes piping into girafe a bit annoying (hence saving the plot to plot_1 and referring to that within the girafe() call.

Slightly more complicated example

In this slightly more complicated example, the weight of chicks is shown over time. Hovering over a line highlights all chicks in that diet (and dims those in other diets)1, and shows the chick number in a tooltip.

The styling of moused-over elements is controlled with the css argument to opts_hover (which is called inside girafe()). I like making non-moused-over elements gray (in opts_hover_inv) and leaving the moused-over elements with their original color by specifiying `css=““.

plot_2 <- ChickWeight |>
    x = Time, y = weight, color = Diet,
    group = Chick,
    tooltip = paste0("Diet ", Diet, " (Chick ", Chick, ")"),
    data_id = Diet
    )) +
     hover_nearest = TRUE

girafe(ggobj = plot_2,
      options = list(
        opts_hover(css = ""), # Don't change CSS for selected group
        opts_hover_inv(css = "opacity: 0.1"), # CSS for other groups
        opts_toolbar(saveaspng = FALSE) # Don't include save button

Javascript on click

The onclick aesthetic allows for execution of JavaScript on click. This is probably more useful in a Shiny project, but it does work even on static HTML pages. Here we get an alert when we click:

plot_3 <- penguins |> 
  ggplot(aes(x = species, fill = island,
             tooltip = sprintf('Island: %s | Species: %s', island, species),
             data_id = island,
             onclick = sprintf('alert("Island: %s | Species: %s");', island, species)
         ) +

girafe(ggobj = plot_3,
       options = list(
         opts_hover(css = ""), # Don't change CSS for selected group
         opts_hover_inv(css = "fill: gray"), # CSS for non-selected groups
         opts_toolbar(saveaspng = FALSE) # Don't include save button


  1. For similar functionality in static graphs (i.e., highlighting one particular group), the gghighlight package.↩︎