Change standard theme of ggplot

ggplot2 is customizeable. Frankly, one can change a heap of details - not everything probably, but a lot. Of course, one can add a theme to the ggplot call, in order to change the theme. However, a more catch-it-all approach would be to change the standard theme of ggplot itself. In this post, we’ll investigate this option.

Load some data and the right packages:

data(mtcars)
library(tidyverse)

Here’s the standard theme of ggplot, let’s have a look at it

theme_gray
#> function (base_size = 11, base_family = "", base_line_size = base_size/22, 
#>     base_rect_size = base_size/22) 
#> {
#>     half_line <- base_size/2
#>     t <- theme(line = element_line(colour = "black", linewidth = base_line_size, 
#>         linetype = 1, lineend = "butt"), rect = element_rect(fill = "white", 
#>         colour = "black", linewidth = base_rect_size, linetype = 1), 
#>         text = element_text(family = base_family, face = "plain", 
#>             colour = "black", size = base_size, lineheight = 0.9, 
#>             hjust = 0.5, vjust = 0.5, angle = 0, margin = margin(), 
#>             debug = FALSE), axis.line = element_blank(), axis.line.x = NULL, 
#>         axis.line.y = NULL, axis.text = element_text(size = rel(0.8), 
#>             colour = "grey30"), axis.text.x = element_text(margin = margin(t = 0.8 * 
#>             half_line/2), vjust = 1), axis.text.x.top = element_text(margin = margin(b = 0.8 * 
#>             half_line/2), vjust = 0), axis.text.y = element_text(margin = margin(r = 0.8 * 
#>             half_line/2), hjust = 1), axis.text.y.right = element_text(margin = margin(l = 0.8 * 
#>             half_line/2), hjust = 0), axis.ticks = element_line(colour = "grey20"), 
#>         axis.ticks.length = unit(half_line/2, "pt"), axis.ticks.length.x = NULL, 
#>         axis.ticks.length.x.top = NULL, axis.ticks.length.x.bottom = NULL, 
#>         axis.ticks.length.y = NULL, axis.ticks.length.y.left = NULL, 
#>         axis.ticks.length.y.right = NULL, axis.title.x = element_text(margin = margin(t = half_line/2), 
#>             vjust = 1), axis.title.x.top = element_text(margin = margin(b = half_line/2), 
#>             vjust = 0), axis.title.y = element_text(angle = 90, 
#>             margin = margin(r = half_line/2), vjust = 1), axis.title.y.right = element_text(angle = -90, 
#>             margin = margin(l = half_line/2), vjust = 0), legend.background = element_rect(colour = NA), 
#>         legend.spacing = unit(2 * half_line, "pt"), legend.spacing.x = NULL, 
#>         legend.spacing.y = NULL, legend.margin = margin(half_line, 
#>             half_line, half_line, half_line), legend.key = element_rect(fill = "grey95", 
#>             colour = NA), legend.key.size = unit(1.2, "lines"), 
#>         legend.key.height = NULL, legend.key.width = NULL, legend.text = element_text(size = rel(0.8)), 
#>         legend.text.align = NULL, legend.title = element_text(hjust = 0), 
#>         legend.title.align = NULL, legend.position = "right", 
#>         legend.direction = NULL, legend.justification = "center", 
#>         legend.box = NULL, legend.box.margin = margin(0, 0, 0, 
#>             0, "cm"), legend.box.background = element_blank(), 
#>         legend.box.spacing = unit(2 * half_line, "pt"), panel.background = element_rect(fill = "grey92", 
#>             colour = NA), panel.border = element_blank(), panel.grid = element_line(colour = "white"), 
#>         panel.grid.minor = element_line(linewidth = rel(0.5)), 
#>         panel.spacing = unit(half_line, "pt"), panel.spacing.x = NULL, 
#>         panel.spacing.y = NULL, panel.ontop = FALSE, strip.background = element_rect(fill = "grey85", 
#>             colour = NA), strip.clip = "inherit", strip.text = element_text(colour = "grey10", 
#>             size = rel(0.8), margin = margin(0.8 * half_line, 
#>                 0.8 * half_line, 0.8 * half_line, 0.8 * half_line)), 
#>         strip.text.x = NULL, strip.text.y = element_text(angle = -90), 
#>         strip.text.y.left = element_text(angle = 90), strip.placement = "inside", 
#>         strip.placement.x = NULL, strip.placement.y = NULL, strip.switch.pad.grid = unit(half_line/2, 
#>             "pt"), strip.switch.pad.wrap = unit(half_line/2, 
#>             "pt"), plot.background = element_rect(colour = "white"), 
#>         plot.title = element_text(size = rel(1.2), hjust = 0, 
#>             vjust = 1, margin = margin(b = half_line)), plot.title.position = "panel", 
#>         plot.subtitle = element_text(hjust = 0, vjust = 1, margin = margin(b = half_line)), 
#>         plot.caption = element_text(size = rel(0.8), hjust = 1, 
#>             vjust = 1, margin = margin(t = half_line)), plot.caption.position = "panel", 
#>         plot.tag = element_text(size = rel(1.2), hjust = 0.5, 
#>             vjust = 0.5), plot.tag.position = "topleft", plot.margin = margin(half_line, 
#>             half_line, half_line, half_line), complete = TRUE)
#>     ggplot_global$theme_all_null %+replace% t
#> }
#> <bytecode: 0x7fc3fc834400>
#> <environment: namespace:ggplot2>

Now let’s make a copy of it, to be on the save side:

theme_gray2 <- theme_gray

Here’s a demo plot, assuming we want to change some aspects of the theme, such as color or font type.

ggplot(mtcars, aes(x = cyl, y = mpg)) +
  geom_jitter()

The standard theme is theme_gray, which can easily be updated in this way:

theme_update(text = element_text(family = "Times",
                            colour = "red"))

Here comes the new (updated) theme:

ggplot(mtcars, aes(x = cyl, y = mpg)) +
  geom_jitter()

Alternatively, we could just apply our new theme:

theme_test <- theme_grey() +
  theme(text = element_text(family = "Times",
                            color = "blue"))


ggplot(mtcars, aes(x = cyl, y = mpg)) +
  geom_jitter() + 
  theme_test