ggplot2
Misc
Packages
- {ggreveal} - Reveal a ggplot Incrementally (e.g. groups, facets)
- {thematic} - Enables automatic styling of R plots in Shiny, R Markdown, and RStudio
- {hrbrthemes} - hrbrmstr’s collection of themes
- {{brand_yml}} - Create reports, apps, dashboards, plots and more that match your company’s brand guidelines with a single
_brand.yml
file- For Quarto dashboards, websites, reports, etc.
- For Python shiny, seaborn, matplotlib, etc.
- For R shiny, ggplot2, plot, RMarkdown
- {ggblanket} - Similar ggplot ui but with simpler structure. Stuff that would require multiple geoms are replaced with one geom and basic arguments. Compatible with popular ggplot extensions
Resources
Don’t use stat calculating geoms and set axis limits with scale_y_continuous
- See examples of the behavior in this thread
Defaults for any {ggplot2} geom using the default_aes field (i.e.
GeomBlah$default_aes
)Basic Function
<- viz_monthly function(df, y_var, threshhold = NULL) { ggplot(df, aes(x = .data[["day"]], y = .data[[y_var]])) + geom_line() + geom_hline(yintercept = threshhold, color = "red", linetype = 2) + scale_x_continuous(breaks = seq(1, 29, by = 7)) + theme_minimal() }
Storing geom settings in a dataframe (source)
<- data.frame(x = seq(from = 1, to = 20, by = 1), df y = rnorm(20, mean = 50, sd = 4), limits = "c(0,30)") ggplot(data = df, aes(x = x, y = y)) + geom_line() + scale_y_continuous(limits= eval(parse(text=df$limits)))
FIltering Data in Geoms (source)
|> mtcars rownames_to_column() |> ggplot(aes(mpg, hp)) + geom_point() + geom_label( aes(label = rowname), data = ~slice_max(.x, hp,n = 2), nudge_x = 3 )
Dynamic Axis Limits (source)
ggplot(...) + + ... scale_x_continuous( breaks = seq(2021, 2023, 1), limits = c(min(df$year) - .1, max(df$year) + .1), position = "top", labels = c("Baseline", "2022", "2023") )
Themes
Docs
Theme Elements Cheatsheet (source)
Use the same font family to all
geom_text
elementsupdate_geom_defaults( geom = "text", aes(family = "Open Sans") )
geom_text
is not impacted by theme settings, so setting this option keeps you from having to manually add the font family to each instance.
Setting color defaults (source)
# Discrete with a list options(ggplot2.discrete.colour = list_of_colors) # Continuous with a function options( ggplot2.continuous.colour = \(...){ ::scale_color_scico( scicopalette = "batlow", ... ) } ) # Ordinal with a function options( ggplot2.ordinal.colour = \(...){ scale_color_viridis_d( option = "G", direction = -1, ... ) } )
- If you have a particular set of palettes you like to use for projects, these options can be put into a R file and loaded via
source
e.g.source(here::here("_defaults.R"))
- If you have a particular set of palettes you like to use for projects, these options can be put into a R file and loaded via
Basic Syntax
<- function() { theme_psc theme_void(base_family = "Open Sans") + theme() }
Transparent Background
+ p theme( panel.background = element_rect(fill='transparent'), #transparent panel bg plot.background = element_rect(fill='transparent', color=NA), #transparent plot bg panel.grid.major = element_blank(), #remove major gridlines panel.grid.minor = element_blank(), #remove minor gridlines legend.background = element_rect(fill='transparent'), #transparent legend bg legend.box.background = element_rect(fill='transparent') #transparent legend panel )ggsave('myplot.png', p, bg='transparent')
theme_notebook
<- function(...) { theme_notebook theme_minimal() %+replace% theme( panel.background = element_rect(fill='#FFFDF9FF'), panel.grid.minor = element_blank(), plot.background = element_rect(fill='#FFFDF9FF', color=NA), legend.background = element_rect(fill='#FFFDF9FF'), legend.box.background = element_rect(fill='#FFFDF9FF'), ... ) }
Cedric Sherer (article)
theme_set(theme_minimal(base_size = 15, base_family = "Anybody")) theme_update( axis.title.x = element_text(margin = margin(12, 0, 0, 0), color = "grey30"), axis.title.y = element_text(margin = margin(0, 12, 0, 0), color = "grey30"), panel.grid.minor = element_blank(), panel.border = element_rect(color = "grey45", fill = NA, linewidth = 1.5), panel.spacing = unit(.9, "lines"), strip.text = element_text(size = rel(1)), plot.title = element_text(size = rel(1.4), face = "bold", hjust = .5), plot.title.position = "plot" )
Eric Bickel
::theme_set( ggplot2theme_bw(base_size = 12) + theme( plot.title = element_text(face = 'bold', hjust = 0), text = element_text(colour = '#4e5c65'), panel.background = element_rect('#ffffff'), strip.background = element_rect('#ffffff', colour = 'white'), plot.background = element_rect('#ffffff'), panel.border = element_rect(colour = '#ffffff'), panel.grid.major.x = element_blank(), panel.grid.major.y = element_blank(), panel.grid.minor.y = element_blank(), legend.background = element_rect('#ffffff'), legend.title = element_blank(), legend.position = 'right', legend.direction = 'vertical', legend.key = element_blank(), strip.text = element_text(face = 'bold', size = 10), axis.text = element_text(face = 'bold', size = 9), axis.title = element_blank(), axis.ticks = element_blank() )
Bespoke
- Comparison Plot (source)
-
Code
library(tidyverse) library(scales) <- comparison_plot function( df, highlight_town, value_type, highlight_color ) { <- plot |> df ggplot( aes( x = value, y = 1 )+ ) # Light gray lines for all towns geom_point( shape = 124, color = "gray80" + ) # Line for town to highlight geom_point( data = df |> filter(location == highlight_town), shape = 124, color = highlight_color, size = 10 ) if (value_type == "percent") { <- plot + final_plot scale_x_continuous( labels = percent_format(accuracy = 1) ) } if (value_type == "number") { <- plot + final_plot scale_x_continuous( labels = comma_format(accuracy = 1) ) } } comparison_plot( df = single_family_homes, highlight_town = "Hartford", value_type = "percent", highlight_color = psc_blue + ) theme_whatever() <- big_number_plot function(value, text, value_color ) {ggplot() + # Add value geom_text( aes( x = 1, y = 1, label = value ),color = value_color, fontface = "bold", size = 20, hjust = 0 + ) # Add text geom_text( aes( x = 1, y = 2, label = str_to_upper(text) ),color = "gray70", size = 7, hjust = 0 ) } big_number_plot( value = "19%", text = "Single-Family Homes as\nPercent of All Homes", value_color = psc_blue + ) theme_whatever() # should start with theme_void
-