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 emphasis
transition
: 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! 🔥