Designing Custom ggplot2 Themes. Give your graphs an attitude | by Nancy Organ | Towards Data Science

The R versus Python debate is a favorite among data scientists. When it comes to data visualization, however, yours truly has a very clear preference: ggplot2 in R all the way.
Ease of data handling and formatting aside, ggplot2 shines in its customizability. The defaults look great, albeit very distinct, but with a bit of planning you can totally transform visualizations to fit any imaginable aesthetic. In this article I’ll walk through how to create a custom ggplot2 theme that can be applied to your graphs.
Open up a new R script that will contain your customizations. You’ll run this script before building any visualizations in order to make your settings available. You can package it up into a library, too, though that’s not strictly necessary.
Make sure to load up the necessary libraries. There’s nothing surprising here, just make sure ggplot and scales are loaded in before you do anything else.
library("ggplot2")library("scales")
New font, new you. Right? There are several options for using a custom font in your graphs.
The first option involves using the fonts that are already on your machine. To access them, load the extrafont library and import all fonts to R. Warning: This is slow. Once you’ve run font_import(), comment it out and leave it alone. If you’re not sure what fonts are possible, use system_fonts() to see a list.
library("extrafont")font_import() # only run this once then comment out. It's slow!extrafont::loadfonts()library("systemfonts")system_fonts() # shows you available fonts
The second option is to add in a Google font. The showtext library will let you import a font from the Google font page using the font_add_google() function. In this example, I’m importing the Reenie Beanie font for a fun handwriting effect.
library("showtext")## Loading Google fonts (https://fonts.google.com/)graphFont = "Reenie Beanie"font_add_google(graphFont)
Under normal circumstances you might use the theme() argument to make small changes to the default settings. Because ggplot2 is layered, adding +theme() to the end of a visualization will override any preceding settings.
We can take advantage of this behavior by defining a bespoke theme that can be added at the end of any visualization. This means you could even go back to old work and apply your new theme to achieve a consistent portfolio. In this example, I’ve defined a straightforward theme that makes all the text black, specifies various background fills, and sets the font. Running theme without the parentheses in R will show you all possible theme options.
theme_custom = function(){  theme(    panel.background = element_blank(),    panel.grid = element_blank(),    axis.ticks = element_blank(),    axis.text = element_text(color = "black"),    legend.box.background = element_blank(),    legend.key = element_rect(fill = NA),    text = element_text(graphFont),    plot.title = element_text(size = 16)  )}
Setting up color pre-planned color scales can be a huge time saver—say goodbye to guessing which shade of magenta you used last time. I like to use the coolors app to create color palettes, and then create a vector of hex codes.
Remember that you’ll need to set a scale for both scale_color_manual() and scale_fill_manual() to account for the different geoms.
pal_custom = c("#9e0a0a", "#115035", "#ff9e97", "#f6cb4c")### Scales custom_color_manual = function(){  scale_color_manual(values = pal_custom)}custom_fill_manual = function(){  scale_fill_manual(values = pal_custom)
If you would like specific behavior for certain types of graphs, customizing the geoms is the way to go. The update_geom_defaults() function does the trick. In these examples, I’ve requested that points be at least size 3, bars have white outlines, and lines are size 1.
update_geom_defaults("point", list(size = 3))update_geom_defaults("bar", list(color = "white"))update_geom_defaults("line", list(size = 1))
As if one theme wasn’t enough, you can actually layer themes. If, for example, you are only making small changes to an existing ggplot theme, you can run the original first, and add your changes afterward.
In this example, I used the xkcd theme by Emilio Torres-Manzanera to achieve a hand-drawn look on the axes, and then applied my custom theme at the end.
ggplot(data=iris, aes(x=Sepal.Width)) +   geom_histogram(binwidth=0.1, aes(fill=Species)) +   custom_fill_manual() +   xlab("X-axis title") +    ylab("Y-axis title") +   ggtitle("Main chart title") +   theme_xkcd() +  xkcdaxis(range(iris$Sepal.Width),range(c(0, 30)))  +   theme_custom()
This particular theme might not be your cup of tea, but it’s certainly different from the default look:
Establishing a custom aesthetic for your visualizations will take some iteration and testing. I recommend building a few test visuals that you can run when you update your theme—this will let you preview the effects on different chart types. Having a handful of test figures will also allow you to conduct accessibility checks and ensure that your theme is user-friendly. I use the Sim Daltonism app to evaluate color palettes and the Accessibility Insights extension to check web elements.
A knitr (.Rnw) or R Markdown (.Rmd) script works nicely for testing because it can be easily recompiled to produce a sharable document. Something as simple as this will do the trick:
\documentclass[a4paper]{article}\begin{document}<<projections, include=FALSE, cache=FALSE>>==source("branding.R")opts_chunk$set(dev='cairo_pdf')@<<renderimage, echo = FALSE, fig.height = 3, fig.width = 5, fig.align='center'>>==ggplot(data=iris, aes(x=Sepal.Width)) +   geom_histogram(binwidth=0.1, aes(fill=Species)) +   custom_fill_manual() +   xlab("X-axis title") +    ylab("Y-axis title") +   ggtitle("Main chart title") +   theme_xkcd() +  xkcdaxis(range(iris$Sepal.Width),range(c(0, 30)))  +   theme_custom()@\end{document}
And that’s it! I hope this gives you a few ideas on how you can create a custom theme for your own ggplot2 work. Start small, see what works, and build from there. Your graphs will be turning heads in no time.
Thinking about accessibility in data visualization? Great! Here are some ways to get started: