library(tidyverse)
library(ggtext)
ggplot() +
geom_richtext(
aes(
x = 0,
y = 0,
label = "This is a <b>bold</b> text annotation"
) )
5 Powerful ggplot2
Extensions
ggplot2
is powerful on its own but there are some extensions that make ggplot2
even better. In this blog post, I show you some of the best extensions.
In this blog post, I’ll show you how to make ggplot2
even better. To do so, we are going to look at five must-have extensions that can level up your dataviz game. This blog post is also available as a video on my YouTube channel. You can check it out here:
Text customization with ggtext
One of my absolute go-to packages is ggtext
. It’s a game-changer when it comes to custom text annotations. You can make single words bold, colored, or switch up fonts, all within a single text layer.
And the beauty of ggtext
lies in its ability to handle these modifications for individual parts of your text. This means you can customize specific words or phrases in your text unlike geom_text
which applies the same style to the entire text. Here’s how that could look.
Notice how the word “bold” is now bold . To make this magic happen, a tiny bit of HTML and CSS notation using the <b>
tag does the trick. You could also make a single word colored and larger by using the <span>
tag and specifying the color in the style
argument.
ggplot() +
geom_richtext(
aes(
x = 0,
y = 0,
label = "This is a <span style='color:blue;font-size:20pt'>blue</span> text annotation"
) )
Combine all the plots with patchwork
Next up, let’s talk about patchwork
, i.e. my second most cherished ggplot extension. This package makes it dead-simple to combine multiple plots into one large plot. You can arrange plots side by side by “adding” them or stack them up by dividing them.
library(patchwork)
<- palmerpenguins::penguins |> filter(!is.na(sex))
penguins # First plot
<- penguins |>
p1 ggplot(aes(x = bill_length_mm, y = body_mass_g)) +
geom_point(aes(fill = species), shape = 21, size = 3)
# Second plot
<- penguins |>
p2 ggplot(aes(x = species, y = body_mass_g)) +
geom_violin(aes(fill = species), linewidth = 0.5, alpha = 0.5) +
geom_jitter(width = 0.1, alpha = 0.5, size = 1)
# Arrange them side by side
+ p2 p1
# Stack them up
/ p2 p1
Of course, there’s lots more customization you can do with patchwork
. Custom layouts and combining legends is pretty easy with this great package. For an in-depth guide on navigating patchwork
, here’s one of my YouTube videos.
Patterns galore with ggpattern
Moving on to ggpattern
, a nifty package that injects patterns into your beloved geoms. Whether it’s adding gradients beneath curves or incorporating geometric patterns into bar plots, ggpattern
got your back. To make ggpattern
do what you want, you just have to
- make your standard
geom_*()
intogeom_*_pattern()
- tweaking a few additional options.
library(magick) # gradient pattern requires this
::sp500 |>
gtfilter(date >= make_date(2000)) |>
ggplot(aes(x = date, y = open)) +
::geom_area_pattern(
ggpatterncol = 'dodgerblue4',
pattern = "gradient",
pattern_fill2 = 'dodgerblue3',
pattern_fill = 'white'
+
) theme_minimal()
You can even venture into creating waffle charts with images or icons. For example, that’s what I teach in my data visualization course while creating a waffle plot to show the export of coffee.
All the random things you can imagine with ggforce
ggforce
is a treasure trove of all kinds of add-ons you might want to use. From circle creation with geom_circle
to wrapped bar charts with geom_arc_bar
, the possibilities are wild. And sure you might at first think that you will never need these things. But think again! For example, geom_arc_bar
is a great way to make pie charts, donut chars or sunburst plots. I explain how that works in one of my YT videos:
But hold on, there’s more. ggforce
throws in custom annotations with a neat arrow and label for your charts. This makes for a pretty nice annotation and it’s easy to create too.
library(ggforce)
|>
penguins ggplot(aes(x = bill_length_mm, y = body_mass_g)) +
geom_point(
aes(fill = species),
shape = 21,
size = 3
+
) geom_mark_ellipse(
data = penguins |>
filter(
> 40,
bill_length_mm between(body_mass_g, 4000, 4500)
),aes(
x0 = 30,
y0 = 5000,
label = "These penguins are important",
),color = "black",
fill = "red",
alpha = 0.2
+
) theme_minimal()
Here, we have added a geom_mark_ellipse()
layer to highlight a few points. The trick was to pass the points that we want to highlight to the data
argument and then specify the x0
and y0
arguments to position the annotation.
You can combine this with ggtext
to make the annotation even more powerful. That’s what I did in my video course to concoct a Taylor Swift bubble chart.
Rankings over time with bump charts
Last but not least, let’s talk about ggbump
. This package makes it suuuper easy to show rankings over time with bump charts. Here’s how such a chart could look.
Code
<- readr::read_csv('https://raw.githubusercontent.com/rfordatascience/tidytuesday/master/data/2022/2022-07-12/flights.csv') |>
flights ::clean_names()
janitor
<- flights |>
country_flights_by_year select(year, state = state_name, flights = flt_tot_1) |>
summarise(flights = sum(flights), .by = c(year, state))
<- country_flights_by_year |>
country_rank_by_year mutate(rank = row_number(desc(flights)), .by = year)
<- 6
max_rank <- country_rank_by_year %>%
todays_top filter(year == 2022, rank <= max_rank) %>%
pull(state)
<- country_rank_by_year %>%
selected_countries filter(state %in% todays_top)
<- c(
color_palette "#E69F00", "#009E73", "#0072B2", "#CC79A7", "#999999", "#D55E00"
)names(color_palette) <- todays_top
<- 'grey30'
description_color
<- selected_countries |>
bump_chart ggplot(aes(year, rank, col = state)) +
geom_point(shape = '|', stroke = 9) +
::geom_bump(linewidth = 2) +
ggbumpgeom_text(
data = selected_countries |> filter(year == 2016),
aes(label = state),
hjust = 1,
nudge_x = -0.1,
size = 8,
fontface = 'bold',
family = 'Source Sans Pro'
+
) geom_text(
data = selected_countries |> filter(year == 2022),
aes(label = rank),
hjust = 0,
nudge_x = 0.1,
size = 8,
fontface = 'bold',
family = 'Source Sans Pro'
+
) annotate(
'text',
x = seq(2016, 2022, 2),
y = 0.5,
label = seq(2016, 2022, 2),
hjust = 0.5,
vjust = 1,
size = 6.5,
fontface = 'bold',
color = description_color,
family = 'Source Sans Pro'
+
) scale_color_manual(values = color_palette) +
coord_cartesian(xlim = c(2014.5, 2022.5), ylim = c(6.5, 0.25), expand = F) +
theme_void(base_size = 24, base_family = 'Source Sans Pro') +
theme(
legend.position = 'none',
plot.background = element_rect(fill = 'grey95', color = NA),
plot.margin = margin(t = 2, l = 5, unit = 'mm'),
text = element_text(color = description_color),
plot.title = element_text(
face = 'bold',
family = 'Merriweather',
size = rel(1.3)
)+
) labs(
title = 'European flight ranking',
subtitle = 'Rank by number of incoming and outgoing flights from 2016 to 2022'
) bump_chart
Once you have your data in the right format, then all of those curvy lines are simply created by using geom_bump()
from ggbump
. If you want to find out more about how to make this chart, check out my YouTube video on the topic.
And a cool combo is to combine ggbump
with gghighlight
(which is yet another powerful extension) to make the chart even more interesting.
+
bump_chart ::gghighlight(
gghighlight# `state` column contains country names
== 'United Kingdom',
state use_direct_label = FALSE
)
Here, all you have to do is to add the gghighlight
layer and specify the country you want to highlight. The latter is done with a simple logical statement in the gghighlight
function just like using filter
in dplyr
.
Conclusion
And there you have it, five ggplot extensions (and gghighlight
as a bonus) that can transform your visualizations. If you enjoyed this blog post, then you may also enjoy