Interactive plots
Introduction
In this worksheet, we will discuss how to combine several ggplot2 plots into one compound figure.
First we need to load the required R packages. Please wait a moment until the live R session is fully set up and all packages are loaded.
Next we set up the data.
We will be working with the dataset texas_counties
. This dataset contains various pieces of information about each county in Texas, such as the number of people living in the county in 2010 (pop2010
), the size of each county (column area
), and the median income (median_income
). The column popratio
is the ratio of the number of inhabitants to the median across all counties. The dataset also contains the shape information about each county (stored in the geometry
column). The column FIPS
contains a five-digit id code that uniquely represents each county.
Interactice scatterplots
The ggiraph package provides the simplest means towards adding a moderate amount of interactivity into ggplot2 plots. It makes it quite straightforward to produce interactive tooltips, interactive highlighting, and the ability to execute actions in the browser (such as opening a new page) when the user clicks on specific elements in the plot.
As a first example, we will create an interactive version of the following plot, which shows median income in Texas counties versus the number of inhabitants of that county.
To turn this plot interactive, we need to make at least the following three modifications:
Replace the geom with the appropriate interactive version. For example,
geom_point()
is replaced bygeom_point_interactive()
.Add an interactive aesthetic. For example, the
tooltip
aesthetic sets the contents of tooltips that show when hovering over the data points.Display the interactive plot object by calling the
girafe()
function with the argumentggobj
. For example, if your ggplot2 plot is stored in a variablep
, you would callgirafe(ggobj = p)
.
Make these modifications to the above plot to create an interactive version.
<- texas_counties |>
texas_scatter ggplot(aes(pop2010, median_income)) +
geom_point_interactive(
aes(tooltip = ___),
na.rm = TRUE, size = 2
+
) scale_x_log10()
girafe(
ggobj = ___
)
<- texas_counties |>
texas_scatter ggplot(aes(pop2010, median_income)) +
geom_point_interactive(
aes(tooltip = county),
na.rm = TRUE, size = 2
+
) scale_x_log10()
girafe(
ggobj = texas_scatter
)
In addition to the tooltip
aesthetic, there is also the data_id
aesthetic, which enables highlighting of the selected point(s). If each element has its own data_id
then elements get highlighted individually. Alternatively, if elements share their data_id
value then they get highlighted jointly.
First, try individual highlighting, by using county
as the data_id
.
<- texas_counties |>
texas_scatter ggplot(aes(pop2010, median_income)) +
geom_point_interactive(
aes(
tooltip = county,
data_id = ___
),na.rm = TRUE, size = 2
+
) scale_x_log10()
girafe(
ggobj = texas_scatter
)
<- texas_counties |>
texas_scatter ggplot(aes(pop2010, median_income)) +
geom_point_interactive(
aes(
tooltip = county,
data_id = county
),na.rm = TRUE, size = 2
+
) scale_x_log10()
girafe(
ggobj = texas_scatter
)
Next, try joint highlighting, by creating two groups: one for counties with a median income above $60,000 and one for all other counties.
<- texas_counties |>
texas_scatter mutate(
income = ifelse(___)
|>
) ggplot(aes(pop2010, median_income, color = ___)) +
geom_point_interactive(
aes(
tooltip = county,
data_id = ___
),na.rm = TRUE, size = 2
+
) scale_x_log10()
girafe(
ggobj = texas_scatter
)
<- texas_counties |>
texas_scatter mutate(
income = ifelse(median_income > 60000, "high", "low")
|>
) ggplot(aes(pop2010, median_income, color = income)) +
geom_point_interactive(
aes(
tooltip = county,
data_id = income
),na.rm = TRUE, size = 2
+
) scale_x_log10()
girafe(
ggobj = texas_scatter
)
You can customize how tooltips and highlighted data points appear by providing the argument options
in the girafe()
function. Options are separated out by tooltip options, hover options, etc. which are provided inside a list()
. Tooltip options are set via opts_tooltip()
, and hover options are set via opts_hover()
. Both functions take an argument css
which takes CSS declarations such as background: #F5F5F5;
or fill: blue;
. Thus, customization code could look as follows:
girafe(
ggobj = texas_scatter,
options = list(
opts_tooltip(
css = "background: #F5F5F5; color: black;"
),opts_hover(
css = "fill: orange;"
)
) )
Try this out.
<- texas_counties |>
texas_scatter ggplot(aes(pop2010, median_income)) +
geom_point_interactive(
aes(
tooltip = county,
data_id = county
),na.rm = TRUE, size = 2
+
) scale_x_log10()
girafe(
ggobj = texas_scatter,
options = list(
opts_tooltip(
css = ___
),opts_hover(
css = ___
)
) )
<- texas_counties |>
texas_scatter ggplot(aes(pop2010, median_income)) +
geom_point_interactive(
aes(
tooltip = county,
data_id = county
),na.rm = TRUE, size = 2
+
) scale_x_log10()
girafe(
ggobj = texas_scatter,
options = list(
opts_tooltip(
css = "background: #F5F5F5; color: #191970;"
),opts_hover(
css = "fill: #D83832;"
)
) )
Also try different CSS properties to see which effect they have. For example, for the tooltip CSS, try padding
(docs). For the hove CSS, try stroke
(docs) or stroke-width
(docs).
Interactive maps
We can also make interactive maps. This requires using geom_sf_interactive()
instead of geom_sf()
, and again using aesthetics such as tooltip
or data_id
.
As an example, consider this non-interactive plot of median income in Texas counties.
Make it interactive, such that by hovering over the map counties get highlighted and a tooltip shows the county name.
<- texas_counties %>%
texas_county_map ggplot(aes(fill = median_income)) +
geom_sf_interactive(
aes(
tooltip = county,
data_id = county
),size = 0.2, color = "black"
+
) scale_fill_viridis_c(option = "E") +
theme_minimal()
girafe(
ggobj = texas_county_map
)
We can also make the counties in the map clickable, by providing an onclick
aesthetic. The aesthetic needs to be provided with strings holding JavaScript code that should be executed when the user clicks on the element. For example, to open the Wikipedia page for Travis County we would need to provide the following code snippet:
window.open("https://en.wikipedia.org/wiki/Travis County, Texas")
Integrate this into the previous map by writing code that generates the JavaScript snippets for each county and maps them onto the onclick
aesthetic. Hint: The glue()
function will be very helpful here.
<- texas_counties %>%
texas_county_map mutate(
onclick = glue(___)
%>%
) ggplot(aes(fill = median_income)) +
geom_sf_interactive(
aes(
tooltip = county,
data_id = county,
onclick = ___
),size = 0.2, color = "black"
+
) scale_fill_viridis_c(option = "E") +
theme_minimal()
girafe(
ggobj = texas_county_map
)
<- texas_counties %>%
texas_county_map mutate(
onclick = glue('window.open("https://en.wikipedia.org/wiki/{county} County, Texas")')
%>%
) ggplot(aes(fill = median_income)) +
geom_sf_interactive(
aes(
tooltip = county,
data_id = county,
onclick = onclick
),size = 0.2, color = "black"
+
) scale_fill_viridis_c(option = "E") +
theme_minimal()
girafe(
ggobj = texas_county_map
)
Interactive maps become particularly useful if you combine them with one or more additional plots that show further information, e.g. a scatterplot. Then, we can highlight a county in the map and the corresponding data point in the scatterplot or vice versa. We will do this by combining the scatter plot from the previous section with the Texas map from this section. You can combine two plots with the function plot_grid()
, which takes as argument the two plots to combine, e.g. plot_grid(texas_scatter, texas_county_map)
. This can be used as the ggobj
in girafe()
.
Hint: Set width_svg = 8
and height_svg = 4
in the girafe()
function to obtain an appropriate plot layout.
# first make the scatter plot
<- texas_counties %>%
texas_scatter ggplot(aes(pop2010, median_income)) +
geom_point_interactive(
aes(
tooltip = county,
data_id = county
),na.rm = TRUE, size = 3
+
) scale_x_log10() +
theme_bw()
# first make the scatter plot
<- texas_counties %>%
texas_scatter ggplot(aes(pop2010, median_income)) +
geom_point_interactive(
aes(
tooltip = county,
data_id = county
),na.rm = TRUE, size = 3
+
) scale_x_log10() +
theme_bw()
# then make the map
<- texas_counties %>%
texas_county_map ggplot() +
geom_sf_interactive(
aes(
tooltip = county,
data_id = county
),size = 0.2, color = "black"
+
) theme_void()
# first make the scatter plot
<- texas_counties %>%
texas_scatter ggplot(aes(pop2010, median_income)) +
geom_point_interactive(
aes(
tooltip = county,
data_id = county
),na.rm = TRUE, size = 3
+
) scale_x_log10() +
theme_bw()
# then make the map
<- texas_counties %>%
texas_county_map ggplot() +
geom_sf_interactive(
aes(
tooltip = county,
data_id = county
),size = 0.2, color = "black"
+
) theme_void()
# then combine
girafe(
ggobj = (___ | ___),
width_svg = 8,
height_svg = 4
)
# first make the scatter plot
<- texas_counties %>%
texas_scatter ggplot(aes(pop2010, median_income)) +
geom_point_interactive(
aes(
tooltip = county,
data_id = county
),na.rm = TRUE, size = 3
+
) scale_x_log10() +
theme_bw()
# then make the map
<- texas_counties %>%
texas_county_map ggplot() +
geom_sf_interactive(
aes(
tooltip = county,
data_id = county
),size = 0.2, color = "black"
+
) theme_void()
# then combine
girafe(
ggobj = (texas_scatter | texas_county_map),
width_svg = 8,
height_svg = 4
)