Cara Thompson | NHS-R 2022 Conference | 16th November 2022
đź‘© Cara Thompson
👩‍💻 Freelance data consultant specialising in dataviz and “enhanced” reproducible outputs
đź’™ Helping others maximise the impact of their expertise
📢 Three reasons for using a bespoke ggplot
theme & how to create one
Find out more: https://www.interaction-design.org/
📦 = {ggbeeswarm}
+ {palmerpenguins}
+ 🎨{colorblindr}
A first easy tweak: theme_minimal()
Create and apply different text colours
Create and apply different text colours
Create and apply different text colours
Create and apply different text colours
Create and apply different text colours
Add your own fonts
Change the text sizes (relative or absolute)
basic_plot +
theme_minimal() +
theme(
text = element_text(colour = mid_text,
family = "BrandonText"),
plot.title = element_text(colour = dark_text,
family = "EnriquetaSB",
size = rel(1.6)),
plot.subtitle = element_text(size = rel(1.1)),
axis.text.y = element_text(colour = light_text,
size = rel(0.8)),
axis.title.y = element_text(size = 12),
axis.text.x = element_text(colour = mid_text,
size = 12),
plot.caption = element_text(size = rel(0.8))
)
basic_plot +
theme_minimal(base_size = 12) +
theme(
text = element_text(colour = mid_text,
family = "BrandonText"),
plot.title = element_text(colour = dark_text,
family = "EnriquetaSB",
size = rel(1.6)),
plot.subtitle = element_text(size = rel(1.1)),
axis.text.y = element_text(colour = light_text,
size = rel(0.8)),
axis.title.y = element_text(size = 12),
axis.text.x = element_text(colour = mid_text,
size = 12),
plot.caption = element_text(size = rel(0.8))
)
Remove clutter: grid lines
basic_plot +
theme_minimal(base_size = 12) +
theme(
text = element_text(colour = mid_text,
family = "BrandonText"),
plot.title = element_text(colour = dark_text,
family = "EnriquetaSB",
size = rel(1.6)),
plot.subtitle = element_text(size = rel(1.1)),
axis.text.y = element_text(colour = light_text,
size = rel(0.8)),
axis.title.y = element_text(size = 12),
axis.text.x = element_text(colour = mid_text,
size = 12),
panel.grid = element_line(colour = "#F3F4F5"),
plot.caption = element_text(size = rel(0.8))
)
Remove clutter: any unnecessary axis titles
basic_plot +
theme_minimal(base_size = 12) +
theme(
text = element_text(colour = mid_text,
family = "BrandonText"),
plot.title = element_text(colour = dark_text,
family = "EnriquetaSB",
size = rel(1.6)),
plot.subtitle = element_text(size = rel(1.1)),
axis.text.y = element_text(colour = light_text,
size = rel(0.8)),
axis.title.y = element_text(size = 12),
axis.text.x = element_text(colour = mid_text,
size = 12),
axis.title.x = element_blank(),
panel.grid = element_line(colour = "#F3F4F5"),
plot.caption = element_text(size = rel(0.8))
)
Reduce eye movements
basic_plot +
theme_minimal(base_size = 12) +
theme(
text = element_text(colour = mid_text,
family = "BrandonText"),
plot.title = element_text(colour = dark_text,
family = "EnriquetaSB",
size = rel(1.6)),
plot.subtitle = element_text(size = rel(1.1)),
axis.text.y = element_text(colour = light_text,
size = rel(0.8)),
axis.title.y = element_text(size = 12),
axis.text.x = element_text(colour = mid_text,
size = 12),
axis.title.x = element_blank(),
panel.grid = element_line(colour = "#F3F4F5"),
legend.position = "top",
plot.caption = element_text(size = rel(0.8))
)
Reduce eye movements
basic_plot +
theme_minimal(base_size = 12) +
theme(
text = element_text(colour = mid_text,
family = "BrandonText"),
plot.title = element_text(colour = dark_text,
family = "EnriquetaSB",
size = rel(1.6)),
plot.subtitle = element_text(size = rel(1.1)),
axis.text.y = element_text(colour = light_text,
size = rel(0.8)),
axis.title.y = element_text(size = 12),
axis.text.x = element_text(colour = mid_text,
size = 12),
axis.title.x = element_blank(),
panel.grid = element_line(colour = "#F3F4F5"),
legend.position = "top",
legend.justification = 1,
plot.caption = element_text(size = rel(0.8))
)
Add breathing space - line height
basic_plot +
theme_minimal(base_size = 12) +
theme(
text = element_text(colour = mid_text,
family = "BrandonText",
lineheight = 1.1),
plot.title = element_text(colour = dark_text,
family = "EnriquetaSB",
size = rel(1.6)),
plot.subtitle = element_text(size = rel(1.1)),
axis.text.y = element_text(colour = light_text,
size = rel(0.8)),
axis.title.y = element_text(size = 12),
axis.text.x = element_text(colour = mid_text,
size = 12),
axis.title.x = element_blank(),
panel.grid = element_line(colour = "#F3F4F5"),
legend.position = "top",
legend.justification = 1,
plot.caption = element_text(size = rel(0.8))
)
Add breathing space - margins around text items (TR
ouBL
e)
basic_plot +
theme_minimal(base_size = 12) +
theme(
text = element_text(colour = mid_text,
family = "BrandonText",
lineheight = 1.1),
plot.title = element_text(colour = dark_text,
family = "EnriquetaSB",
size = rel(1.6),
margin = margin(12, 0, 8, 0)),
plot.subtitle = element_text(size = rel(1.1),
margin = margin(4, 0, 0, 0)),
axis.text.y = element_text(colour = light_text,
size = rel(0.8)),
axis.title.y = element_text(size = 12,
margin = margin(0, 4, 0, 0)),
axis.text.x = element_text(colour = mid_text,
size = 12),
axis.title.x = element_blank(),
panel.grid = element_line(colour = "#F3F4F5"),
legend.position = "top",
legend.justification = 1,
plot.caption = element_text(size = rel(0.8),
margin = margin(8, 0, 0, 0))
)
Add breathing space - margins around the plot (TR
ouBL
e)
basic_plot +
theme_minimal(base_size = 12) +
theme(
text = element_text(colour = mid_text,
family = "BrandonText",
lineheight = 1.1),
plot.title = element_text(colour = dark_text,
family = "EnriquetaSB",
size = rel(1.6),
margin = margin(12, 0, 8, 0)),
plot.subtitle = element_text(size = rel(1.1),
margin = margin(4, 0, 0, 0)),
axis.text.y = element_text(colour = light_text,
size = rel(0.8)),
axis.title.y = element_text(size = 12,
margin = margin(0, 4, 0, 0)),
axis.text.x = element_text(colour = mid_text,
size = 12),
axis.title.x = element_blank(),
panel.grid = element_line(colour = "#F3F4F5"),
legend.position = "top",
legend.justification = 1,
plot.caption = element_text(size = rel(0.8),
margin = margin(8, 0, 0, 0)),
plot.margin = margin(0.25, 0.25,
0.25, 0.25,
"cm")
)
Add breathing space - adjust text size (🙏 rel()
!)
basic_plot +
theme_minimal(base_size = 11) +
theme(
text = element_text(colour = mid_text,
family = "BrandonText",
lineheight = 1.1),
plot.title = element_text(colour = dark_text,
family = "EnriquetaSB",
size = rel(1.6),
margin = margin(12, 0, 8, 0)),
plot.subtitle = element_text(size = rel(1.1),
margin = margin(4, 0, 0, 0)),
axis.text.y = element_text(colour = light_text,
size = rel(0.8)),
axis.title.y = element_text(size = 12,
margin = margin(0, 4, 0, 0)),
axis.text.x = element_text(colour = mid_text,
size = 12),
axis.title.x = element_blank(),
panel.grid = element_line(colour = "#F3F4F5"),
legend.position = "top",
legend.justification = 1,
plot.caption = element_text(size = rel(0.8),
margin = margin(8, 0, 0, 0)),
plot.margin = margin(0.25, 0.25, 0.25, 0.25, "cm")
)
“Don’t repeat yourself” principle
plot +
theme_minimal(base_size = 12) +
theme(text = element_text(colour = mid_text, family = "BrandonText", lineheight = 1.1),
plot.title = element_text(colour = dark_text, family = "EnriquetaSB", size = rel(1.6), margin = margin(12, 0, 8, 0)),
plot.subtitle = element_text(size = rel(1.1), margin = margin(4, 0, 0, 0)),
axis.text.y = element_text(colour = light_text, size = rel(0.8)),
axis.title.y = element_text(size = 12, margin = margin(0, 4, 0, 0)),
axis.text.x = element_text(colour = mid_text, size = 12),
axis.title.x = element_blank(),
legend.position = "top",
legend.justification = 1,
panel.grid = element_line(colour = "#F3F4F5"),
plot.caption = element_text(size = rel(0.8), margin = margin(8, 0, 0, 0)),
plot.margin = margin(0.25, 0.25, 0.25, 0.25,"cm"))
Package it up as a function
theme_nhsr_demo <- function(base_size = 12) {
theme_minimal(base_size = base_size) +
theme(text = element_text(colour = mid_text, family = "BrandonText", lineheight = 1.1),
plot.title = element_text(colour = dark_text, family = "EnriquetaSB", size = rel(1.6), margin = margin(12, 0, 8, 0)),
plot.subtitle = element_text(size = rel(1.1), margin = margin(4, 0, 0, 0)),
axis.text.y = element_text(colour = light_text, size = rel(0.8)),
axis.title.y = element_text(size = 12, margin = margin(0, 4, 0, 0)),
axis.text.x = element_text(colour = mid_text, size = 12),
axis.title.x = element_blank(),
legend.position = "top",
legend.justification = 1,
panel.grid = element_line(colour = "#F3F4F5"),
plot.caption = element_text(size = rel(0.8), margin = margin(8, 0, 0, 0)),
plot.margin = margin(0.25, 0.25, 0.25, 0.25,"cm"))
}
Package it up as a function
theme_nhsr_demo <- function(base_size = 12,
dark_text = "#1A242F") {
mid_text <- monochromeR::generate_palette(dark_text, "go_lighter", n_colours = 5)[2]
light_text <- monochromeR::generate_palette(dark_text, "go_lighter", n_colours = 5)[3]
theme_minimal(base_size = base_size) +
theme(text = element_text(colour = mid_text, family = "BrandonText", lineheight = 1.1),
plot.title = element_text(colour = dark_text, family = "EnriquetaSB", size = rel(1.6), margin = margin(12, 0, 8, 0)),
plot.subtitle = element_text(size = rel(1.1), margin = margin(4, 0, 0, 0)),
axis.text.y = element_text(colour = light_text, size = rel(0.8)),
axis.title.y = element_text(size = 12, margin = margin(0, 4, 0, 0)),
axis.text.x = element_text(colour = mid_text, size = 12),
axis.title.x = element_blank(),
legend.position = "top",
legend.justification = 1,
panel.grid = element_line(colour = "#F3F4F5"),
plot.caption = element_text(size = rel(0.8), margin = margin(8, 0, 0, 0)),
plot.margin = margin(0.25, 0.25, 0.25, 0.25,"cm"))
}
+
or %+replace%
?
Find out more: ggplot2.tidyverse.org/reference/theme_get
Apply it to any plot you like! 📦{datasets}
Apply it to any plot you like! 📦{datasets}
📦 {geomtextpath}
📦 {geomtextpath}
There’s still room for further modifications if you want to make them!
There’s still room for further modifications if you want to make them!
There’s still room for further modifications if you want to make them!
There’s still room for further modifications if you want to make them!
ToothGrowth_plot +
theme_nhsr_demo() +
theme(
axis.text.x = element_text(colour = light_text, size = rel(0.8)),
axis.title.x = element_text(margin = margin(8, 0, 0, 0)),
strip.background = element_rect(fill = "#F3F4F5", color = "#FFFFFF"),
strip.text = element_text(family = "Enriqueta", size = 14)
)
All in the interest of effortless consistency - R for the Rest of Us
All in the interest of effortless consistency - Misc + theme_nhsr_demo()
Slides and full code: cararthompson.com/talks/nhsr2022-ggplot-themes