Hi, I’m Sharon Machlis at IDG, here with Episode 63 of Do More With R: Create interactive
ggplot graphics with the ggiraph R package. Static visualizations are often enough to
tell stories with your data. But there are times you want interactivity, so users can
hover to see underlying or linked data. R has a number of packages for interactive
graphics, including echarts4r, plotly, and highcharter. I like and use all of those.
But today, I’ll demo another one that’s fairly new to me (and maybe to you): the ggiraph
package - that’s g-g-i-r-a-p-h - to turn ggplot graphics into interactive Web visualizations.
I especially like ggiraph for how easy it is to make a 2nd plot also react when you
hover over a first graphic. Let’s take a look.
There are three easy ggiraph steps to make your ggplots interactive:
1. Use a ggiraph interactive geom instead of a “regular” ggplot geom. The format
is super easy to remember: Just add underscore interactive to your usual geom. So, geom_col()
for a regular bar chart would be geom_col_underscore_interactive(). Geom_point() would be geom_point_underscore
interactive(), and so on. 2. Add at least one interactive argument to
the graph: tooltip, data_id, or onclick. You add those to a ggplot a-e-s aesthetics mapping.
That data_id argument is very useful, because it’s the one that lets you hover over one
graphic and affect another one – all without Shiny. We’ll see that in a bit.
3. After creating your ggiraph dataviz object, you turn it into an actual Web graphic with
the girafe() function. The package is g-g-i-r-a-p-h, but the function is spelled g-i-r-a-f-e (like
the animal, but with one f. That’s how you spell it in French, and the creator of ggiraph,
David Gohel, is in Paris.) Let’s start with a simple tooltip example.
If you’d like to follow along, these are the packages I’ll be using: ggplot2, ggiraph,
dplyr, patchwork, and for a map at the end, Bob Rudis’s albersusa package. albersusa
isn’t on CRAN; you’ll need to install it from GitHub.
For data, I’m going to use recent US Covid vaccination data by state available from the
Our World in Data GitHub repository. You can see the URL for the data. If you’re following
along and don’t want to type out that long URL, go to bit-dot-l-y-slash-VaxData, capital
V and D, which will redirect there. Here I’m reading in the data, and changing
“New York State” to just “New York”. That next part creates a vector of entries
that aren’t US states or DC, so my chart doesn’t have too many rows. You don’t
have to do that, but it’s helpful so the chart isn’t so large.
This code filters the data to create a data set I can use to visualize the latest data
for each state and DC, excluding the others. I’m also rounding the percent vaccinated
to one decimal point, selecting just the state and vax percent columns, and renaming them
to State and PctFullyVaccinated. Here’s a basic (static) ggplot bar chart
of the data. X axis is originally the state, reordered based on percent vaccinated. y is
the vax level. I use geom_col() for a bar chart with my typical blue bars outlined in
black, minimal theme, 10-point axis text. At the end I flip the x and y coordinates
so it’s easier to read the state names. Now I want to turn this into a Web graphic
where I can hover and see the underlying data. ggiraph only lets me use one column for the
tooltip info, but I want both state and rate in there. Easy solution: I add my own tooltip
column to the data frame with both state and rate in there. I did that with the new tooltip_text
column. So my interactive latest_vax_graph code looks
pretty similar to my ggplot code. I added tooltip and data_id to the a.e.s mapping,
and I changed geom_col() to geom_col_interactive(). I also reduced the size of the axis labels,
because the ggplot 9 size ended up being too large for my slide display.
Then on the code at the right, I displayed the graph with the girafe function. I set
the ggobject to be my latest_vax_graph object, and I was also able to set the SVG width and
height. The graph may looks pretty much the same as the ggplot version – but now I can
hover over the bars and see the underlying data.
One thing that really makes ggiraph shine is how easy it is to link up multiple graphs.
Here I’m creating data for a second graph for February 14 rates, and then I make another
ggiraph graph the same way. But linking them is where this gets special.
Here’s the code. I load the patchwork library, then use the girafe() function to say I want
to print the early_vax_graph plus the latest_vax_graph; and when I hover, I want the bars to turn
cyan color. Here’s what that looks like. Now we can explore what happened to state
rankings between February
and July. It’s that easy to link up 2 graphs! I want to show you one more linking example,
this time with a map. I got the idea from Kyle Walker, who did a demo of using his tidycensus
package to create a map linked with a chart. I’ll use the same idea with this data.
Here’s the code. us_sf is a simple features geospatial object using the “lcc” projection.
state_map creates a ggiraph map object of the US from that. The map uses typical ggplot()
syntax, but instead of geom_sf() it’s geom_sf_interactive(). I’ve also added tooltip and data_id arguments
to the aes() mapping, and I’ve eliminated any background or axes with theme_void()
The next code block uses girafe() to print both the map and the vax graph. There’s
a slightly different girafe() syntax here, which Kyle Walker used: Instead of the code
equal print argument I used before, he used ggobject equals first viz plus second viz.
Everything else is the same. Let’s see what that looks like.
Now I can hover over a state on the map and see where it shows up on the bar graph! Seriously,
how cool is that - with so little R code needed! That’s it for this episode, thanks for watching!
For more R tips, head to the Do More With R page at bit-dot-l-y slash do more with R,
all lowercase except for the R. You can also find the Do More With R playlist on YouTube’s
IDG Tech Talk channel where you can subscribe so you never miss an episode. Hope to see
you next time. Stay healthy and safe, everyone!