library(tidyverse)
library(palmerpenguins)
# Compute
penguins_medians <- penguins |> 
  summarize(bill_length_mm_median = median(bill_length_mm, na.rm = TRUE),
            bill_depth_mm_median = median(bill_depth_mm, na.rm = TRUE))If you use ggplot2, you are probably used to creating plots with geom_line() and geom_point(). You may also have ventured into to the broader ggplot2 ecosystem to use geoms like geom_density_ridges() from ggridges or geom_signif() from ggsignif. But have you ever wondered how these extensions were created? Where did the authors figure out how to create a new geom? And, if the plot of your dreams doesn’t exist, how would you make your own?
Enter the exciting world of creating your own ggplot2 extensions.
I had the pleasure of meeting Gina Reynolds when I first began my job at Posit (then RStudio) and she was contributing a blog post on flipbookr. Since then, we’ve kept in touch through the ggextenders extension club. Every few months, the club meets virtually to hear from a ggextender (someone who works with ggplot2 extensions). The speaker can talk about a custom geom they’ve created for the community or more general R visualization topics. Each presentation is insightful and interesting. I’ve had the opportunity to learn about cool packages like ggstats. Join us sometime by filling out this questionnaire!
However, I was never a “ggextender” myself (having just used and never developed extenders). I found the idea of creating an extension daunting. That is, until recently!
Gina held a focus group that worked through the Easy geom recipes, a series of tutorials on creating ggplot2 extensions. Following “recipes”, you methodically create three extensions. Each time, certain key knowledge points are reinforced and new variations are introduced.
So, say we want to create a new geom_*() that adds a point on the median of the x-axis and y-axis variables of a plot. We will call it geom_medians(). Let’s follow the recipe:
And then you’re done! You’ve created your first ggplot extension 🥳.
Going through the recipes is a great way to ease into your ggplot2 extension journey. They offer three well-crafted examples with a clear structure and sequence of steps. The boilerplate code looks daunting, but you can copy/paste it and edit it depending on what you are creating; if you want to go into more detail as to what it’s actually doing, the tutorials provide additional resources. A fun note is that the geom recipes website uses webR and Quarto Live to embed interactive code chunks directly in the tutorial. It makes for an immersive experience while going through the exercises.
Want to try your own hand at creating geom_means()? Go through the interactive tutorial in Easy geom recipes!
Resources
It’s a delight going through Gina’s resources, from seeing the adorable ggextenders hex to reading all the touching notes about ggplot2, comparing it to art, food, poetry, and more. It’s a testament to how a tool can inspire so many. Here are some of my favorites quotations and metaphors:
- “ggplot2 lets users ‘speak their plots into existence’” — Thomas Lin Pedersen
 - “You are a composer of ‘graphical poems’” — Hadley Wickham
 
Learn more about Gina’s work here:
- ggplot2 extenders club website: See previous talks and sign up for future webinars
 - Everyday ggplot2 extension: Education materials for potential extenders
 - ggplot2 extension cookbook: Guide that presents extension strategies in a consistent and accessible way
 - Easy geom recipes: A series of tutorials on creating a tutorial
 
There is a comprehensive list of resources on the ggplot2 extenders club website.
Many thanks to Andrew Bray, James Goldie, and the QMD Lab for Closeread, a Quarto extension for scrollytelling, which walked through the ggextender steps, and Gina, for both organizing the ggplot2 extenders club and reviewing this post!


