Moving beyond theme_gray: Exploring customized themes for improved visualizations in ggplot2

Presentation by Emma Skarstein

October 2021

Aim

Show how to set up custom themes to make effective data visualizations in less time.

Why make your own themes?

  • Consistent graphical expression

  • Save time

  • Modify theme to match presentation or poster

Plan

  • Look at the data: Tate art collection artwork and artists, set up basic visualization
  • Build a custom theme and apply to plot
  • Look at BBC’s custom theme

Dataset: Tate art collection

# Read in with tidytuesdayR package 
# Install from CRAN via: install.packages("tidytuesdayR")
# This loads the readme and all the datasets for the week of interest

tuesdata <- tidytuesdayR::tt_load(2021, week = 3)
artwork <- tuesdata$artwork
artists <- tuesdata$artists
art_artist <- right_join(artists, artwork, by = c("name" = "artist")) %>%
  filter(year>1700) %>% drop_na(gender)
  • each row is a piece of art at the Tate art museum
  • we have artist info such as name, gender, year of birth and death, place of birth and death
  • we have artwork info such as year of creation, year of acquisition, height and width of painting, medium

Basic visualization

basic <- ggplot(art_artist, aes(x = year, fill = gender)) +
  geom_bar()
basic

ggplot2 themes

Setting up a theme

my_basic_theme <- function(DEFAULT ARGUMENTS){
  return_theme <- theme(
    # (TEXT FORMAT)
    ...

    # AXIS FORMAT
    axis...

    # LEGEND FORMAT
    legend...

    # BACKGROUND FORMAT
    panel...
    plot...
    
    # FACETING FORMAT
    strip...

  return(return_theme)
}

Basic visualization

My theme

my_basic_theme <- function(base_size = 12,
                           base_family = 'sans'){
  return_theme <- theme(
    # TEXT FORMAT
    text = element_text(family = base_family, size = base_size),
    axis.text = element_text(size = 10,
                             color = "black"),
    plot.title = element_text(size = 20,
                              margin = margin(b = 5)),
    plot.subtitle = element_text(size = 15,
                                 margin = margin(b = 10)),

    # AXIS FORMAT
    axis.title = element_blank(),

    # LEGEND FORMAT
    legend.position = "top",
    legend.title = element_blank(),
    legend.justification = 0,
    legend.text = element_text(size = 15,
                               family = base_family),

    # BACKGROUND FORMAT
    panel.grid = element_blank(),
    panel.background = element_rect(fill = "#F9F8F8"),
    panel.border = element_rect(color = "gray", fill = NA))

  return(return_theme)
}

My theme

# my_basic_theme
basic + my_basic_theme()

My theme +++

# Specify this for font
font_add_google(name = "Nunito", family = "Nunito")
#font_families()
showtext_auto()

basic +
  scale_fill_manual(values = c("#EC7238", "#66B4C0", "#1E4A76")) +
  scale_x_continuous(breaks = seq(1700, 2012, by = 50),
                     expand = c(0.05, 0.05)) +
  scale_y_continuous(limits = c(0, 3300),
                     expand = c(0.001, 0)) +
  labs(title = "TATE ART MUSEUM: Pieces created each year",
       subtitle = "1700 - 2012",
       caption = "Source: Tate Art Museum / TidyTuesday | Visualization: Emma Skarstein") +
  my_basic_theme(base_family = "Nunito")

My theme +++

BBC rCookbook

BBC graphics

BBC’s theme

bbc_style <- function() {
  font <- "Helvetica"

  ggplot2::theme(

  #Text format:
  #This sets the font, size, type and colour of text for the chart's title
  plot.title = ggplot2::element_text(family=font,
                            size=28,
                            face="bold",
                            color="#222222"),
  #This sets the font, size, type and colour of text for the chart's subtitle, as well as setting a margin between the title and the subtitle
  plot.subtitle = ggplot2::element_text(family=font,
                               size=22,
                               margin=ggplot2::margin(9,0,9,0)),
  plot.caption = ggplot2::element_blank(),
  #This leaves the caption text element empty, because it is set elsewhere in the finalise plot function

  #Legend format
  #This sets the position and alignment of the legend, removes a title and backround for it and sets the requirements for any text within the legend. The legend may often need some more manual tweaking when it comes to its exact position based on the plot coordinates.
  legend.position = "top",
  legend.text.align = 0,
  legend.background = ggplot2::element_blank(),
  legend.title = ggplot2::element_blank(),
  legend.key = ggplot2::element_blank(),
  legend.text = ggplot2::element_text(family=font,
                             size=18,
                             color="#222222"),

  #Axis format
  #This sets the text font, size and colour for the axis test, as well as setting the margins and removes lines and ticks. In some cases, axis lines and axis ticks are things we would want to have in the chart - the cookbook shows examples of how to do so.
  axis.title = ggplot2::element_blank(),
  axis.text = ggplot2::element_text(family=font,
                           size=18,
                           color="#222222"),
  axis.text.x = ggplot2::element_text(margin=ggplot2::margin(5, b = 10)),
  axis.ticks = ggplot2::element_blank(),
  axis.line = ggplot2::element_blank(),

  #Grid lines
  #This removes all minor gridlines and adds major y gridlines. In many cases you will want to change this to remove y gridlines and add x gridlines. The cookbook shows you examples for doing so
  panel.grid.minor = ggplot2::element_blank(),
  panel.grid.major.y = ggplot2::element_line(color="#cbcbcb"),
  panel.grid.major.x = ggplot2::element_blank(),

  #Blank background
  #This sets the panel background as blank, removing the standard grey ggplot background colour from the plot
  panel.background = ggplot2::element_blank(),

  #Strip background (#This sets the panel background for facet-wrapped plots to white, removing the standard grey ggplot background colour and sets the title size of the facet-wrap title to font size 22)
  strip.background = ggplot2::element_rect(fill="white"),
  strip.text = ggplot2::element_text(size  = 22,  hjust = 0)
  )
}

BBC’s theme

#devtools::install_github('bbc/bbplot')
library(bbplot)

basic + scale_fill_manual(values = c("#1380A1", "#FAAB18")) +
  scale_x_continuous(breaks = seq(1700, 2012, by = 50),
                     expand = c(0.05, 0.05)) +
  scale_y_continuous(limits = c(0, 3300),
                     expand = c(0.001, 0)) +
  labs(title = "TATE ART MUSEUM\nPieces created each year",
       subtitle = "1700 - 2012",
       caption = "Source: Tate Art Museum / TidyTuesday | Visualization: Emma Skarstein") +
  bbc_style()

BBC’s theme

Other visualizations

Maia Pelletier

Georgios Karamanis

Further resources