The theme of a plot refers to all the parts that are not linked to data. This includes titles, axis lables, as well as the labelling of the axis labels or legends (also known as guides). It also includes text characteristics (font, size, colour, bold, italics) and the colour and placement of axes, tick marks, boxes around the plot and legend.
There is a single function, theme that controls most of these features, with many options. I’ll give examples showing how to control many aspects of the theme.
Within a presentation or report, we often want to use a consistent theme for all figures. You can define many features of a theme and store them in an object in your R environment. You can then use this theme for all your figures. Changing the theme for many figures is then possible with only a single change in one location.
There are many add on packages for working with themes. I’ll give examples from ggtext, ggthemes, and patchwork.
32.1 Example plots for customization
We’ll use a couple of plots repeatedly: one with facets, and one with many other elements, but no facets.
p1<-penguins|>ggplot(aes(x =body_mass_g, y =flipper_length_mm, color =species, shape =sex))+geom_point()p1
p2<-mpg|>unglue_unnest(trans, "{trans_type}({trans_code})")|>ggplot(aes(x =displ, y =hwy, color =trans_type))+geom_point()+facet_wrap(~factor(cyl))p2
32.2 Built-in themes
There are many themes available that change the whole look of your plot. I’ve used theme_bw many times already, so here are a couple of other examples. For each you can use the base_size option (default value 11) to scale text elements and base_line_size to scale line elements of the figure.
Another collection of themes is available in ggthemer. The main goal of this lesson is to give you the vocabulary and skills to customize the theme of your plot, so I won’t spend any more time on theme packages. On to the details!
32.3 Customizing text on a figure
The most common change I want to make to a plot’s theme (after axis and guide labels) is to increase the size of the text. This can be done using theme(text= ...) or for specific elements, theme(axis.title=...) (see the help page for more elements of the theme that can be set with a text element.) On the right side of the equals sign, you need the function element_text which allows you to control 10 different characteristics of your text. Here is an example of a few of the features.
Themes are controlled hierarchically, so adjusting text affects all text on the plot. Adjusting axis.title affects both axis.title.x and axis.title.y.
Compare this with the original version of the plot and play “spot the differences”.
32.4 Customizing borders, ticks, axis labels
There are many elements on a plot drawn with lines. These too can be customized all at once using theme(line = ...) or element by element using, for example theme(axis.line.x=...) or theme(axis.ticks.y=...). The grid lines can be adjusted using panel.grid.major and panel.grid.minor. These elements are named and controlled hierarchically as well. The right hand size of the expressions above must have an element_line function which allows you to control color, size, linetype and other features like arrows.
Warning: The `size` argument of `element_line()` is deprecated as of ggplot2 3.4.0.
ℹ Please use the `linewidth` argument instead.
32.5 Enhanced text
The ggtext package allows you to use markdown and HTML code in any text element on your plot. You need to use element_markdown (or element_textbox_simple) instead of element_text for each element you want to use this enhanced formatting method with.
Unlike other theme elements, you can’t easily use ggtext formatting hierarchically: you can’t simply set all text to use elemment_markdown or even both axis labels. You must control each element individually.
p1+labs(title ="_Penguin data from **Palmer station**, Antarctica_<sup>1</sup>", x ="<span style = 'color:red;'>body mass (g)</span>", y ="flipper length (mm)", caption ="<sup>1</sup>Collected by K. Gorman")+theme(plot.title =element_markdown(lineheight =1.2), plot.caption =element_markdown(), axis.title.x =element_textbox_simple(halign =0.5))