This post
explains how to use the ggiraph
package to create interactive graph and how to
customize it with additional CSS, with reproducible code and
explanations.
For an introduction to ggiraph
, check
the dedicated post
First we need to load the ggiraph and ggplot2 libraries.
The input dataset is about consumer confidence in 9 different countries at differente dates:
# library
library(ggplot2)
library(ggiraph)
library(tidyverse)
# Create data
data <- read.csv("https://raw.githubusercontent.com/holtzy/R-graph-gallery/master/DATA/dataConsumerConfidence.csv") %>%
mutate(date = lubridate::my(Time)) %>%
select(-Time) %>%
pivot_longer(!date, names_to = "country", values_to = "value") %>%
na.omit() %>%
mutate(country = as.factor(country))
The ggiraph
package in R is an extension of the ggplot2
package, designed to simplify the process of creating
interactive charts.
It offers a set of function to add interactivity
such as geom_point_interactive()
for an interactive version
of geom_point()
, geom_sf_interactive()
for an
interactive version of geom_sf()
etc.
Let’s start with a simple interactive version of
this line chart. It uses the geom_line_interactive()
function to replace the geom_line()
one and make it
interactive.
plot <- data %>%
ggplot(mapping = aes(
x = date,
y = value,
color = country,
tooltip = country,
data_id = country
)) +
geom_line_interactive(hover_nearest = TRUE) +
theme_classic()
interactive_plot <- girafe(ggobj = plot)
htmltools::save_html(interactive_plot, "HtmlWidget/geom-line-interactive-1.html")
Although CSS
is primarily used for styling web
pages, it can also be relevant in customizing visuals in
R, especially when dealing with web-based outputs like
interactive charts or Shiny applications.
CSS
code has the following structure: a property named
(such as font-size
), a colon (:
), and the
value of that property (such as 14px
). Each element is then
separated by a ;
.
The easiest way to add CSS
in ggiraph is to use the
girafe_options()
function.
Then we use
opts_hover(css = "fill:#ffe7a6;stroke:black;cursor:pointer;")
to fill the lines on hover with a given color and
change the color of the lines to black.
plot <- data %>%
ggplot(mapping = aes(
x = date,
y = value,
color = country,
tooltip = country,
data_id = country
)) +
geom_line_interactive(hover_nearest = TRUE) +
theme_classic()
interactive_plot <- girafe(ggobj = plot)
interactive_plot <- girafe_options(
interactive_plot,
opts_hover(css = "fill:#ffe7a6;stroke:black;cursor:pointer;"),
opts_selection(type = "single", css = "fill:red;stroke:black;"),
opts_toolbar(saveaspng = FALSE)
)
htmltools::save_html(interactive_plot, "HtmlWidget/geom-line-interactive-2.html")
When displaying multiple lines in a single chart, it’s easy to end up with a cluttered spaghetti chart. One effective way to enhance readability is by implementing a hover effect that elegantly fades out non-hovered lines while highlighting the selected line.
This can be achieved using CSS with the following properties:
stroke
: Change the color of the hovered line (e.g.,
stroke: #69B3A2;
)stroke-width
: Increase the width of the hovered line
for emphasistransition
: Add a smooth transition effect (e.g.,
transition: all 0.3s ease;
)opacity
: Reduce the opacity of non-hovered lines (e.g.,
opacity: 0.5;
)filter
: Apply a grayscale effect to non-hovered lines
(e.g., filter: grayscale(90%);
)library(hrbrthemes) # for the `theme_ipsum()`
plot <- data %>%
ggplot(mapping = aes(
x = date,
y = value,
color = country,
tooltip = country,
data_id = country
)) +
geom_line_interactive(hover_nearest = TRUE) +
theme_ipsum()
interactive_plot <- girafe(ggobj = plot)
interactive_plot <- girafe_options(
interactive_plot,
opts_hover(css = "stroke:#69B3A2; stroke-width: 3px; transition: all 0.3s ease;"),
opts_hover_inv("opacity:0.5;filter:saturate(10%);"),
opts_toolbar(saveaspng = FALSE)
)
htmltools::save_html(interactive_plot, "HtmlWidget/geom-line-interactive-3.html")
plot <- data %>%
ggplot(mapping = aes(
x = date,
y = value,
color = country,
tooltip = country,
data_id = country
)) +
geom_line_interactive(hover_nearest = TRUE) +
theme_classic()
interactive_plot <- girafe(ggobj = plot)
hover_css <- "
fill: #ffe7a6;
fill-opacity: 0.5;
stroke: black;
stroke-width: 7px;
stroke-dasharray: 5,5;
transition: fill-opacity 0.5s, stroke-width 0.5s, stroke-dasharray 0.5s, filter 0.5s;
filter: drop-shadow(0 0 5px rgba(0,0,0,0.5));
"
interactive_plot <- girafe_options(
interactive_plot,
opts_hover(css = hover_css),
opts_toolbar(saveaspng = FALSE)
)
htmltools::save_html(interactive_plot, "HtmlWidget/geom-line-interactive-4.html")
Since CSS
provides an infinite number of possibilities,
you can use it to create very original charts!
Hover CSS:
stroke: black;
: Sets the outline color of the hovered
element to black.stroke-width: 1px;
: Sets the width of the outline to 1
pixel.r: 8px;
: Sets the radius of circular elements (like
points) to 8 pixels, making them larger on hover.transition: all 0.3s ease;
: Applies a smooth transition
effect for all property changes, lasting 0.3 seconds.Tooltip CSS:
background-color: #2C3E50;
: Sets a dark blue background
for the tooltip.color: #ECF0F1;
: Sets the text color to a light
gray.padding: 10px;
: Adds 10 pixels of space inside the
tooltip around its content.border-radius: 5px;
: Rounds the corners of the
tooltip.font-family: 'Arial', sans-serif;
: Sets the font to
Arial or a sans-serif fallback.font-size: 14px;
: Sets the text size to 14 pixels.box-shadow: 0px 0px 10px rgba(0,0,0,0.5);
: Adds a
subtle shadow effect to the tooltip.plot <- data %>%
ggplot(mapping = aes(
x = date,
y = value,
color = country,
group = country,
tooltip = paste("Country:", country, "<br>Date:", date, "<br>Value:", round(value, 2)),
data_id = country
)) +
geom_line_interactive(size = 1.2, hover_nearest = TRUE) +
geom_point_interactive(aes(size = value), alpha = 0.7) +
scale_color_viridis_d() +
scale_size_continuous(range = c(1, 2)) +
theme_minimal(base_size = 14) +
labs(
title = "Interactive Country Data Visualization",
subtitle = "Try to hover and click on the lines!",
caption = "R-Graph-Gallery.com",
x = "Date",
y = "Consumer Confidence"
) +
theme(
plot.title = element_text(hjust = 0.5, size = 20, face = "bold"),
plot.subtitle = element_text(hjust = 0.5, size = 16, face = "italic"),
legend.position = "none",
panel.grid.minor = element_blank(),
panel.background = element_rect(fill = "ivory", color = NA),
plot.background = element_rect(fill = "ivory", color = NA)
)
interactive_plot <- girafe(ggobj = plot)
hover_css <- "
stroke: black;
stroke-width: 1px;
r: 8px;
transition: all 0.3s ease;
"
tooltip_css <- "
background-color: #2C3E50;
color: #ECF0F1;
padding: 10px;
border-radius: 5px;
font-family: 'Arial', sans-serif;
font-size: 14px;
box-shadow: 0px 0px 10px rgba(0,0,0,0.5);
"
interactive_plot <- girafe_options(
interactive_plot,
opts_hover(css = hover_css),
opts_tooltip(css = tooltip_css, use_fill = TRUE),
opts_selection(type = "multiple", only_shiny = FALSE),
opts_zoom(min = 0.5, max = 2),
opts_toolbar(saveaspng = TRUE, position = "topright", pngname = "country_data_plot"),
opts_sizing(rescale = TRUE)
)
htmltools::save_html(interactive_plot, "HtmlWidget/geom-line-interactive-5.html")
You might be interested in:
👋 After crafting hundreds of R charts over 12 years, I've distilled my top 10 tips and tricks. Receive them via email! One insight per day for the next 10 days! 🔥