ggplot2 data visualisationsR/Pharma 2026
Data visualisation specialist, mainly working with R, Python, and D3.js.
Background in statistics, operational research, and data science consultancy.
Co-author of Royal Statistical Society’s Best Practices for Data Visualisation guidance.
Author of The Art of Data Visualization with ggplot2.
ggplot2 basicsggplot() (data and mapping)aes()geom_*()scales()theme()ggplot2 issues?ggplot2 issues?ggplot2 issues?ggplot2ggplot2 changesHave you ever spent ages tinkering with a plot you’re previewing in RStudio…
…and then used ggsave() to save an image, and ended up with something like this:
This happens because we preview the chart at 96dpi (low resolution) in RStudio, but save the chart at 300dpi (high resolution) using the defaults for ggsave().
We could set ggsave(dpi = 96) but we usually don’t want to save a low resolution image.
Instead we want to preview the chart in RStudio at the higher resolution we’ll be saving it at.
ggview: github.com/idmn/ggview
ggplot2 output directly with your specifications in RStudio IDE - you’ll get what you seeggviewggviewSome common problems:
theme text
geom text
axis text
ggplot2 extensionsggplot2 extensionsggplot2ggridges, ggdist, ggh4x …Manual solutions
\n directly to the text stringstr_wrap() to add line breaks and set the number of characters per lineAutomated solutions
ggtextmarqueeggtext for wrapping long titles and subtitlesmarquee for wrapping long titles and subtitlesThere are many packages for working with annotations in ggplot2:
ggplot2ggtextcowplotggannotateggrepelggannotateggh4xggtextcowplotggrepelTip: use
glueto create data-driven annotations
ggplot2 and I()at_panel() from ggh4x to place annotations on facetsggtext or marquee to ensure the subtitle text wraps onto multiple lines.ggtext or marquee to make sure country names are all visible in the facet labels."Australia" facet.ggplot2 workflowsCreate variable for colours:
Remembering all of the theme elements is tricky
ggplot2 charts (optional)Create a template file (inside or outside of a package) that contains the theme() defaults you want to use.
# Load packages -----------------------------------------------------------
library(tidyverse)
library(showtext)
library(ggtext)
library(glue)
library(ggview)
# Load data ---------------------------------------------------------------
# Load fonts --------------------------------------------------------------
font_add_google("Oswald")
font_add_google("Nunito")
showtext_auto()
showtext_opts(dpi = 300)
title_font <- "Oswald"
body_font <- "Nunito"
# Define colours and fonts-------------------------------------------------
bg_col <- "#F2F4F8"
text_col <- "#151C28"
highlight_col <- "#7F055F"
# Data wrangling ----------------------------------------------------------
# Define text -------------------------------------------------------------
title <- ""
st <- ""
cap <- ""
# Plot --------------------------------------------------------------------
theme_minimal(base_size = 10, base_family = body_font) +
theme(
plot.margin = margin(5, 5, 5, 5),
plot.title.position = "plot",
plot.caption.position = "plot",
plot.background = element_rect(fill = bg_col, colour = bg_col),
panel.background = element_rect(fill = bg_col, colour = bg_col),
plot.title = element_textbox_simple(
colour = text_col,
hjust = 0,
halign = 0,
margin = margin(b = 5, t = 5),
family = title_font,
face = "bold",
size = rel(1.5)
),
plot.subtitle = element_textbox_simple(
colour = text_col,
hjust = 0,
halign = 0,
margin = margin(b = 5, t = 5),
family = body_font
),
plot.caption = element_textbox_simple(
colour = text_col,
hjust = 0,
halign = 0,
margin = margin(b = 0, t = 10),
family = body_font
),
strip.text = element_textbox_simple(
face = "bold",
margin = margin(t = 10),
size = rel(0.9)
),
panel.grid.minor = element_blank()
) +
canvas(
width = 7, height = 5,
units = "in", bg = bg_col,
dpi = 300
) # -> p
# Save --------------------------------------------------------------------
save_ggplot(
plot = p,
file = "image.png"
)theme() function
ggtext and marquee to auto-wrap texttheme() function
ggtext and marquee to auto-wrap textggplot2 documentation: ggplot2.tidyverse.org/index.html
ggplot2 extensions gallery: exts.ggplot2.tidyverse.org/gallery
The Art of Data Visualization with ggplot2: nrennie.rbind.io/art-of-viz
More resources: nrennie.rbind.io/resources