--- title: "Styling & Customization" author: "Gilles Colling" date: "`r Sys.Date()`" output: rmarkdown::html_vignette vignette: > %\VignetteIndexEntry{Styling & Customization} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- ```{r setup, include = FALSE} knitr::opts_chunk$set( collapse = TRUE, comment = "#>", fig.width = 6, fig.height = 4 ) library(ggguides) library(ggplot2) # Theme with transparent backgrounds for pkgdown light/dark mode theme_set( theme_grey() + theme( plot.background = element_rect(fill = "transparent", color = NA), panel.background = element_rect(fill = "transparent", color = NA), legend.background = element_rect(fill = "transparent", color = NA), legend.key = element_rect(fill = "transparent", color = NA), legend.box.background = element_rect(fill = "transparent", color = NA) ) ) ``` ## Overview ggguides provides styling functions to customize legend appearance without diving into ggplot2's theme element hierarchy. The main functions are: - `legend_style()` - Comprehensive styling (fonts, backgrounds, borders) - `legend_keys()` - Override key appearance (size, alpha, shape) - `legend_order()` - Reorder legend entries - `legend_wrap()` - Multi-column/row layouts - `legend_reverse()` - Reverse entry order - `colorbar_style()` - Customize continuous color bar legends ## Font Styling ### Font Size Adjust the overall text size (applies to both title and labels): ```{r style-size, fig.show='hold', out.width='48%'} p <- ggplot(mtcars, aes(mpg, wt, color = factor(cyl))) + geom_point(size = 3) + labs(color = "Cylinders") p + ggtitle("Default size") p + legend_style(size = 14) + ggtitle("size = 14") ``` ### Font Family Change the font family for legend text: ```{r style-family, fig.show='hold', out.width='48%'} p + legend_style(family = "serif") + ggtitle("serif") p + legend_style(family = "mono") + ggtitle("mono") ``` ### Title Emphasis Make the title stand out with separate size and face settings: ```{r style-title} p + legend_style( size = 12, title_size = 14, title_face = "bold" ) ``` ## Text Rotation For legends with long category names, rotate the labels to save space: ### Basic Rotation ```{r rotation-basic, fig.width=7} p_long <- ggplot(mpg, aes(displ, hwy, color = class)) + geom_point() p_long + legend_style(angle = 45) ``` ### Vertical Labels Use 90 degrees for fully vertical text. Key height is automatically adjusted to prevent label overlap: ```{r rotation-vertical, fig.width=7} p_long + legend_style(angle = 90) ``` ### Title Rotation Rotate the legend title independently: ```{r rotation-title, fig.show='hold', out.width='48%'} p_long + legend_style(title_angle = 90, title_hjust = 0.5) + ggtitle("Rotated title only") p_long + legend_style(angle = 45, title_angle = 90) + ggtitle("Both rotated") ``` ## Background and Border Add visual containers around the legend: ```{r style-background} p + legend_style( background = "#FFF3E0" ) ``` ```{r style-border} p + legend_style( background = "#FFF3E0", background_color = "#FF9800" ) ``` ## Key Size Adjust the size of legend keys (color swatches): ```{r style-key} p + legend_style( key_width = 1.5, key_height = 1.5 ) ``` ## Margin Control spacing around the legend: ```{r style-margin} p + legend_style( background = "#FFF3E0", margin = 0.5 ) ``` ## Full Styling Example Combine all styling options: ```{r style-full} p + legend_style( size = 11, title_size = 13, title_face = "bold", family = "sans", key_width = 1.2, background = "#FFF3E0", background_color = "#FF9800", margin = 0.3 ) ``` ## Wrapping Legend Entries For legends with many entries, `legend_wrap()` creates multi-column or multi-row layouts. ### By Columns ```{r wrap-ncol, fig.width=7} ggplot(mpg, aes(displ, hwy, color = class)) + geom_point() + legend_wrap(ncol = 2) ``` ### By Rows ```{r wrap-nrow, fig.width=7} ggplot(mpg, aes(displ, hwy, color = class)) + geom_point() + legend_wrap(nrow = 2) ``` ### With Bottom Position Wrapping works well with horizontal legends: ```{r wrap-bottom, fig.width=7} ggplot(mpg, aes(displ, hwy, color = class)) + geom_point() + legend_wrap(nrow = 2) + legend_bottom() ``` ## Customizing Legend Keys When plot aesthetics like small point sizes or low alpha values make legend keys hard to read, `legend_keys()` overrides the key appearance without affecting the plot. ### Enlarging Small Points ```{r keys-size, fig.show='hold', out.width='48%'} p_small <- ggplot(mtcars, aes(mpg, wt, color = factor(cyl))) + geom_point(size = 1) + labs(color = "Cylinders") p_small + ggtitle("Small points in legend") p_small + legend_keys(size = 4) + ggtitle("Enlarged legend keys") ``` ### Removing Transparency ```{r keys-alpha, fig.show='hold', out.width='48%'} p_alpha <- ggplot(mtcars, aes(mpg, wt, color = factor(cyl))) + geom_point(alpha = 0.3, size = 3) + labs(color = "Cylinders") p_alpha + ggtitle("Transparent legend keys") p_alpha + legend_keys(alpha = 1) + ggtitle("Opaque legend keys") ``` ### Combining Overrides ```{r keys-combined} ggplot(mtcars, aes(mpg, wt, color = factor(cyl))) + geom_point(alpha = 0.3, size = 1) + legend_keys(size = 4, alpha = 1) ``` ### Targeting Specific Aesthetics By default, `legend_keys()` applies to both colour and fill legends. Target specific aesthetics with the `aesthetic` parameter: ```{r keys-fill} ggplot(mtcars, aes(factor(cyl), mpg, fill = factor(cyl))) + geom_boxplot(alpha = 0.5) + legend_keys(alpha = 1, aesthetic = "fill") ``` ### Changing Symbol Shapes Use named shapes for clarity instead of numeric codes: ```{r keys-shape, fig.show='hold', out.width='48%'} p + legend_keys(shape = "square") + ggtitle("Square") p + legend_keys(shape = "diamond") + ggtitle("Diamond") ``` Available shape names include: `"circle"`, `"square"`, `"diamond"`, `"triangle"`, `"plus"`, `"cross"`, `"asterisk"`. ### Filled Shapes with Outlines Shapes 21-25 (or names ending in `_filled`) support both outline and fill colors, making legends more visible against any background: ```{r keys-outline, fig.show='hold', out.width='48%'} # White fill with colored outline - works with color mapping only p + legend_keys(shape = "circle_filled", fill = "white", stroke = 1.5) + ggtitle("White fill, colored outline") # Colored fill with black outline - requires mapping BOTH color and fill ggplot(mtcars, aes(mpg, wt, color = factor(cyl), fill = factor(cyl))) + geom_point(size = 3, shape = 21, stroke = 1) + legend_keys(colour = "black", stroke = 1) + ggtitle("Colored fill, black outline") ``` Note: For colored fills with a custom outline, you must map both `color` and `fill` in the plot aesthetics. This is a ggplot2 limitation—`override.aes` can only set static values, it cannot make fill inherit from color. Shape types: | Type | Shapes | Fill from | Outline from | |------|--------|-----------|--------------| | Outline only | `"circle_open"`, `"square_open"`, `"diamond_open"` | N/A | `colour` | | Solid filled | `"circle"`, `"square"`, `"diamond"` | `colour` | N/A | | Fill + outline | `"circle_filled"`, `"square_filled"`, `"diamond_filled"` | `fill` | `colour` | ## Reordering Legend Entries `legend_order()` changes the order of legend entries without modifying factor levels in your data. ### Explicit Order Specify the exact order you want: ```{r order-explicit} p + legend_order(c("8", "6", "4")) ``` ### Using Functions Apply functions like `rev` or `sort` to the current order: ```{r order-rev, fig.show='hold', out.width='48%'} p + legend_order(rev) + ggtitle("Reversed") p + legend_order(sort) + ggtitle("Sorted") ``` ### Other Aesthetics Reorder legends for fill, shape, or other aesthetics: ```{r order-fill} ggplot(mtcars, aes(factor(cyl), fill = factor(cyl))) + geom_bar() + legend_order(c("8", "4", "6"), aesthetic = "fill") ``` ## Reversing Legend Order For simple reversal, `legend_reverse()` is a convenient shorthand: ```{r reverse} p + legend_reverse() ``` ## Combining Style Functions All ggguides functions compose with `+`: ```{r combined-styling, fig.width=7} ggplot(mpg, aes(displ, hwy, color = class)) + geom_point() + legend_left() + legend_style( size = 11, title_face = "bold", background = "#FFF3E0" ) ``` ```{r combined-wrap-style, fig.width=7} ggplot(mpg, aes(displ, hwy, color = class)) + geom_point() + legend_wrap(ncol = 2) + legend_bottom() + legend_style(size = 10, title_face = "bold") ``` ## Styling Continuous Color Bars For continuous scales, `colorbar_style()` customizes the color bar appearance. ### Basic Usage ```{r colorbar-basic} p_cont <- ggplot(faithfuld, aes(waiting, eruptions, fill = density)) + geom_tile() p_cont ``` ### Size Adjustments Create taller, thinner bars: ```{r colorbar-size} p_cont + colorbar_style(width = 0.5, height = 10, aesthetic = "fill") ``` ### Horizontal Orientation ```{r colorbar-horizontal} p_cont + colorbar_style(width = 10, height = 0.5, direction = "horizontal", aesthetic = "fill") + legend_bottom() ``` ### Adding a Frame ```{r colorbar-frame, fig.show='hold', out.width='48%'} p_cont + colorbar_style(frame = TRUE, aesthetic = "fill") + ggtitle("Black frame") p_cont + colorbar_style(frame = "#FF9800", aesthetic = "fill") + ggtitle("Orange frame") ``` ### Removing Ticks ```{r colorbar-noticks} p_cont + colorbar_style(ticks = FALSE, frame = "#FF9800", aesthetic = "fill") ``` ### Combined Customization ```{r colorbar-full} p_cont + colorbar_style( width = 0.5, height = 8, frame = "#E65100", ticks_length = 0.3, aesthetic = "fill" ) ``` ## Summary | Function | Purpose | Key Parameters | |----------|---------|----------------| | `legend_style()` | Comprehensive styling | `size`, `title_size`, `title_face`, `family`, `angle`, `background`, `margin` | | `legend_keys()` | Override key appearance | `size`, `alpha`, `shape`, `fill`, `colour`, `stroke`, `aesthetic` | | `legend_order()` | Reorder entries | `order` (vector or function), `aesthetic` | | `legend_wrap()` | Multi-column layout | `ncol`, `nrow` | | `legend_reverse()` | Reverse entry order | None | | `colorbar_style()` | Continuous color bar | `width`, `height`, `frame`, `ticks`, `direction` | **Learn more:** - [Legend Positioning](positioning.html) for placement control - [Patchwork Integration](patchwork.html) for multi-panel workflows