Ah, Ha, Ha, Ha, Parameterise!

Dataviz
Coding tips
Parameterise

RMedicine 2024 talk where I create and refine a parameterised plot function, with an exploration of how this approach can contribute to flexible and reproducible data-to-viz workflows across the team.

Published

June 14, 2024

Recording

Final code

library(tidyverse)

theme_demo <- function(base_size = 12, 
                          dark_text = "#222222") {
  
  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 = "Work Sans", lineheight = 1.1, face = "bold"),
          plot.title = ggtext::element_textbox_simple(colour = dark_text, family = "Poppins", size = rel(1.6), 
                                                      face = "bold",
                                                      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), family = "Work Sans"),
          axis.text.x = element_text(colour = light_text, size = rel(0.8), family = "Work Sans"),
          axis.title.y = element_text(margin = margin(0, 0, 0, 12)),
          legend.position = "bottom",
          legend.justification = 1,
          panel.grid = element_line(colour = "#FFFFFF"),
          panel.background = element_rect(colour = "#FFFFFF",
                                          fill = "#FEFDFA"),
          plot.background = element_rect(fill = "#FEFDFA",
                                         colour = "#FEFDFA"),
          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"))
}

penguin_colours <- c(Adelie = "orange",
                     Chinstrap = "pink",
                     Gentoo = "darkgreen",
                     Biscoe = "steelblue",
                     Torgersen = "turquoise",
                     Dream = "skyblue",
                     male = "#2C3D4F",
                     female = "#28A569")

make_penguin_plot <- function(df = palmerpenguins::penguins,
                              colours = penguin_colours,
                              grouping_variable = "species",
                              subtitle = NA,
                              add_labels = TRUE,
                              ...) {
  
  mean_x_y <- df |>
    group_by(get(grouping_variable)) |>
    summarise(mean_x = mean(bill_length_mm, na.rm = TRUE),
              mean_y = mean(flipper_length_mm, na.rm = TRUE),
              mean_weight = mean(body_mass_g, na.rm = TRUE),
              count = length(get(grouping_variable)))
  
  unlabelled_plot <- df |>
    ggplot() +
    geom_point(aes(x = bill_length_mm,
                   y = flipper_length_mm,
                   colour = get(grouping_variable),
                   size = body_mass_g),
               size = 5, 
               alpha = 0.9) +
    labs(title = paste0("Flipper lengths are proportional to bill lengths within each ",
                        grouping_variable),
         x = "Bill length (mm)",
         y = "Flipper length (mm)",
         colour = "") +
    theme_demo(16) +
    scale_colour_manual(values = colours) +
    theme(...)
  
  if(add_labels == TRUE) {
    plot_to_export <- unlabelled_plot + 
      ggtext::geom_textbox(data = mean_x_y,
                           aes(x = mean_x,
                               y = mean_y,
                               label = paste0("**", `get(grouping_variable)`, "**",
                                              " (N = ", count, ")",
                                              "<br>Mean weight: ", janitor::round_half_up(mean_weight/1000, 2), "kg")),
                           size = 7,
                           family = "Work Sans",
                           width = unit(20, "lines"),
                           fill = "#FEFDFA",
                           box.colour = NA,
                           alpha = 0.9,
                           halign = 0.5) +
      theme(legend.position = "none")
  } else {
    plot_to_export <- unlabelled_plot
  }
  
  if(!is.na(subtitle)) {
    plot_to_export +
      labs(subtitle = subtitle)
  } else {
    plot_to_export
  }
  
}

And now, all we need to do is…

make_penguin_plot()

Reuse

Citation

For attribution, please cite this work as:
“Ah, Ha, Ha, Ha, Parameterise!” 2024. June 14, 2024. https://www.cararthompson.com/talks/ah-ha-ha-ha-parameterise.