--- title: "Advanced Customization" output: rmarkdown::html_vignette vignette: > %\VignetteIndexEntry{Advanced Customization} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- ```{r setup, include = FALSE} knitr::opts_chunk$set( collapse = TRUE, comment = "#>", fig.width = 7, fig.height = 5 ) ``` ## Introduction This vignette dives deeper into BFHtheme for users who need more than the out-of-the-box defaults. You will learn how to: - fine-tune theme parameters and override individual elements, - craft bespoke colour palettes and gradients, - add BFH-branded annotations such as footers, logos, and colour bars, - organise multi-panel figures, and - optimise fonts and performance for production workflows. | Customisation area | Key functions | | --- | --- | | Theme tweaks | `theme_bfh_*()`, `theme()` | | Colours & palettes | `bfh_cols()`, `bfh_pal()`, `scale_*_bfh_*()` | | Branding elements | `add_bfh_logo()`, `add_bfh_footer()` | | Layout helpers | `bfh_combine_plots()`, `bfh_save()` | ```{r load, message=FALSE} library(BFHtheme) library(ggplot2) ``` ## Theme Customization ### Modifying Base Theme Parameters All BFH themes expose the standard ggplot2 base arguments. Adjust them to fit specific deliverables—larger fonts for accessibility, a fixed typeface for compliance, or heavier lines for print. ```{r theme-params} ggplot(mtcars, aes(x = wt, y = mpg)) + geom_point() + labs(title = "Custom Base Size") + theme_bfh( base_size = 14, # Larger text base_family = "Arial", # Specific font base_line_size = 0.6, # Thicker lines base_rect_size = 0.6 # Thicker rectangles ) ``` ### Overriding Theme Elements Layer additional ggplot2 theme calls on top of the BFH defaults to fine-tune individual components such as titles, panels, or grids. ```{r theme-override} ggplot(mtcars, aes(x = wt, y = mpg)) + geom_point() + labs(title = "Custom Theme Elements") + theme_bfh() + theme( plot.title = element_text(color = bfh_cols("hospital_blue"), size = 18), axis.title.x = element_text(face = "bold"), panel.grid.major = element_line(color = "grey90", linewidth = 0.3) ) ``` ### Legend Customisation Legends inherit BFH styling but can be repositioned or reformatted to suit the layout. ```{r legend-custom} ggplot(mtcars, aes(x = wt, y = mpg, color = factor(cyl))) + geom_point(size = 3) + labs( title = "Custom Legend Position", color = "Cylinders" ) + scale_color_bfh() + theme_bfh() + theme( legend.position = "top", legend.direction = "horizontal", legend.box = "horizontal" ) ``` ## Colour Palette Customisation ### Using Different Palettes Switch palettes dynamically to emphasise different aspects of the brand. ```{r palettes} p <- ggplot(mtcars, aes(x = factor(cyl), fill = factor(cyl))) + geom_bar() + labs(title = "Hospital Blues Palette") + theme_bfh() p + scale_fill_bfh(palette = "hospital_blues") ``` ### Reversing Palettes Reverse the palette order when a gradient needs to flow in the opposite direction. ```{r reverse-palette} ggplot(mtcars, aes(x = wt, y = mpg, color = hp)) + geom_point(size = 3) + labs(title = "Reversed Colour Scale") + scale_color_bfh_continuous(palette = "blues", reverse = TRUE) + theme_bfh() ``` ### Creating Custom Palettes Combine individual colours or build a bespoke gradient with `bfh_pal()` to match department-specific requirements. ```{r custom-palette} # Create a custom palette with specific colours custom_colors <- c( bfh_cols("hospital_primary"), bfh_cols("regionh_grey"), bfh_cols("regionh_primary") ) ggplot(mtcars, aes(x = factor(cyl), fill = factor(cyl))) + geom_bar() + labs(title = "Custom Colour Selection") + scale_fill_manual(values = custom_colors) + theme_bfh() ``` ### Working with Colour Functions Use `bfh_pal()` to generate smooth gradients or truncate palettes for a precise number of categories. ```{r palette-function} # Generate colour ramp blues_pal <- bfh_pal("hospital_blues") # Use in continuous scale ggplot(faithfuld, aes(waiting, eruptions, fill = density)) + geom_tile() + scale_fill_gradientn(colours = blues_pal(100)) + theme_bfh() ``` ## Plot Enhancements Extend a finished plot with branded components and annotations to convey context, ownership, or emphasis without redesigning the underlying chart. ### Adding BFH Branding Anchor a plot with official branding using `add_bfh_footer()`: ```{r footer, eval=FALSE} p <- ggplot(mtcars, aes(x = wt, y = mpg)) + geom_point() + theme_bfh() add_bfh_footer( p, text = "Bispebjerg og Frederiksberg Hospital - 2024", color = bfh_cols("hospital_primary") ) ``` ### Multi-Panel Figures Combine multiple plots with a shared legend for consistent storytelling: ```{r multi-panel, eval=FALSE} library(patchwork) p1 <- ggplot(mtcars, aes(wt, mpg, color = factor(cyl))) + geom_point() + labs(title = "Weight vs MPG") + scale_color_bfh() + theme_bfh() p2 <- ggplot(mtcars, aes(hp, mpg, color = factor(cyl))) + geom_point() + labs(title = "Horsepower vs MPG") + scale_color_bfh() + theme_bfh() # Combine with shared legend p1 + p2 + plot_layout(guides = "collect") & theme(legend.position = "bottom") ``` Alternatively, call the BFH helper directly: ```{r combine-plots, eval=FALSE} plots <- list(p1, p2) bfh_combine_plots(plots, ncol = 2, legend_position = "bottom") ``` ## Axis Customisation ### Formatting Axes Tidy up axes with breaks, limits, and units that match your narrative: ```{r axis-format} ggplot(mtcars, aes(x = wt, y = mpg)) + geom_point() + labs( title = "Custom Axis Formatting", x = "Vehicle Weight (1000 lbs)", y = "Fuel Efficiency (MPG)" ) + scale_y_continuous( breaks = seq(10, 35, 5), limits = c(10, 35) ) + theme_bfh() ``` ### Date Axes For time-series data, combine date scales with BFH colours: ```{r date-axis, eval=FALSE} library(lubridate) date_data <- data.frame( date = seq(as.Date("2024-01-01"), by = "month", length.out = 12), value = cumsum(rnorm(12, 10, 3)) ) ggplot(date_data, aes(x = date, y = value)) + geom_line(color = bfh_cols("hospital_primary"), linewidth = 1) + labs( title = "Monthly Trends", x = "Month", y = "Value" ) + scale_x_date( date_breaks = "2 months", date_labels = "%b %Y" ) + theme_bfh() ``` ## Text and Labels Typography and copy tone are central to the BFH identity. These helpers keep labels consistent while still giving you room for context-specific annotations. ### Uppercase Labels Use `bfh_labs()` to align subtitles, axis titles, and captions with the uppercase convention while preserving the main title casing: ```{r uppercase-labels} ggplot(mtcars, aes(x = wt, y = mpg)) + geom_point() + bfh_labs( title = "Fuel efficiency analysis", # Title unchanged subtitle = "Motor trend data", # Converted to uppercase x = "weight (1000 lbs)", # Converted to uppercase y = "miles per gallon", # Converted to uppercase caption = "Source: Motor Trend, 1974" # Converted to uppercase ) + theme_bfh() ``` ### Uppercase Axis Tick Labels For complete typographic consistency, use the position scale functions to convert axis tick labels (the actual values on the axes) to uppercase. This is particularly useful for date labels and categorical data: ```{r uppercase-axis-labels} # Discrete/categorical data with uppercase labels ggplot(mtcars, aes(x = factor(cyl), y = mpg)) + geom_boxplot() + scale_x_discrete_bfh() + # "4" becomes "4", but categories like "low" become "LOW" bfh_labs( title = "Fuel efficiency by cylinder count", x = "cylinders", y = "miles per gallon" ) + theme_bfh() # Date data with uppercase month labels df <- data.frame( date = seq.Date(as.Date("2023-01-01"), as.Date("2023-12-31"), by = "month"), value = rnorm(12, mean = 100, sd = 10) ) ggplot(df, aes(x = date, y = value)) + geom_line(color = bfh_cols("hospital_primary"), linewidth = 1) + scale_x_date_bfh(date_labels = "%b %Y") + # "Jan 2023" becomes "JAN 2023" scale_y_continuous_bfh() + bfh_labs( title = "Monthly trends", x = "month", y = "value" ) + theme_bfh() ``` The available position scale functions with uppercase support are: - `scale_x_continuous_bfh()` / `scale_y_continuous_bfh()` - For numeric axes - `scale_x_discrete_bfh()` / `scale_y_discrete_bfh()` - For categorical data - `scale_x_date_bfh()` / `scale_y_date_bfh()` - For date axes - `scale_x_datetime_bfh()` / `scale_y_datetime_bfh()` - For datetime axes All functions accept a custom `labels` argument if you need different formatting. ### Advanced: Integration with scales Package The BFH position scales integrate seamlessly with the `scales` package for even smarter formatting. You can use `breaks_pretty()` for intelligent break positioning and any `label_*()` function—output is automatically uppercased: ```{r scales-integration} library(scales) # Use label_date_short() for compact, hierarchical labels ggplot(df, aes(x = date, y = value)) + geom_line(color = bfh_cols("hospital_primary"), linewidth = 1) + scale_x_date_bfh( breaks = breaks_pretty(n = 8), # Smart break positioning labels = label_date_short() # Compact labels (auto-uppercased) ) + bfh_labs( title = "Compact date labels with breaks_pretty", x = "date", y = "value" ) + theme_bfh() # Combine custom formatting with breaks ggplot(df, aes(x = date, y = value)) + geom_line(color = bfh_cols("hospital_blue"), linewidth = 1) + scale_x_date_bfh( breaks = breaks_width("2 months"), # Break every 2 months labels = label_date("%B") # Full month names (uppercased) ) + bfh_labs( title = "Full month names with custom breaks", x = "month", y = "value" ) + theme_bfh() ``` **Useful scales functions:** - `breaks_pretty(n)` - Pretty breaks with desired count - `breaks_width("2 weeks")` - Breaks at regular intervals - `label_date("%b %Y")` - Custom date format - `label_date_short()` - Compact hierarchical labels - `label_time()` - Time formatting ### Best Practice: label_date_short() for Space Efficiency The `label_date_short()` function is particularly powerful for time series with many data points. It creates a hierarchical labeling system that only shows what has changed, dramatically reducing horizontal space requirements: ```{r label-date-short-example} # Standard labels - repetitive and space-consuming ggplot(df, aes(x = date, y = value)) + geom_line(color = bfh_cols("hospital_primary"), linewidth = 1) + scale_x_date_bfh( date_breaks = "2 months", labels = label_date("%b %Y") # "JAN. 2023", "MAR. 2023", etc. ) + bfh_labs(title = "Standard labels", x = "date", y = "value") + theme_bfh() + theme(axis.text.x = element_text(angle = 45, hjust = 1)) # Rotation needed! # label_date_short() - compact and hierarchical ggplot(df, aes(x = date, y = value)) + geom_line(color = bfh_cols("hospital_primary"), linewidth = 1) + scale_x_date_bfh( date_breaks = "2 months", labels = label_date_short() # Shows year only when it changes ) + bfh_labs(title = "Compact hierarchical labels", x = "date", y = "value") + theme_bfh() # No rotation needed! ``` **Recommended combinations based on data duration:** ```{r eval=FALSE} # Short time series (< 1 year) scale_x_date_bfh() # Default is fine # Medium time series (1-3 years) scale_x_date_bfh( breaks = breaks_pretty(n = 6), labels = label_date_short() ) # Long time series (> 3 years) scale_x_date_bfh( breaks = breaks_pretty(n = 8), labels = label_date_short() ) # Weekly data scale_x_date_bfh( breaks = breaks_width("2 weeks"), labels = label_date_short() ) ``` ### Custom Text Elements Layer additional annotations for storytelling while staying within the BFH colour system: ```{r annotations} ggplot(mtcars, aes(x = wt, y = mpg)) + geom_point() + annotate( "text", x = 4.5, y = 30, label = "High efficiency zone", color = bfh_cols("hospital_primary"), size = 4 ) + annotate( "rect", xmin = 1.5, xmax = 3.5, ymin = 25, ymax = 35, alpha = 0.1, fill = bfh_cols("hospital_blue") ) + labs(title = "Annotated Plot") + theme_bfh() ``` ## Faceting Facets inherit BFH defaults, but subtle tweaks can make multi-panel layouts feel polished and balanced. ### Facet Customisation Adjust strip backgrounds and text to reinforce brand colours: ```{r facets} ggplot(mtcars, aes(x = wt, y = mpg)) + geom_point(color = bfh_cols("hospital_primary")) + facet_wrap(~cyl, labeller = labeller(cyl = function(x) paste(x, "cylinders"))) + labs(title = "Fuel Efficiency by Cylinder Count") + theme_bfh() + theme( strip.background = element_rect(fill = bfh_cols("hospital_light_blue1")), strip.text = element_text(color = bfh_cols("hospital_primary"), face = "bold") ) ``` ## Export and File Formats Produce publication-ready figures while keeping file sizes manageable. ### High-Resolution Export Use `bfh_save()` presets for common outputs, or override the size when you need an exact width and height. ```{r export, eval=FALSE} p <- ggplot(mtcars, aes(x = wt, y = mpg)) + geom_point() + theme_bfh() # High-resolution PNG bfh_save("figure.png", p, preset = "report_full", dpi = 600) # Vector format for editing bfh_save("figure.pdf", p, preset = "report_full") # Custom dimensions bfh_save("figure.png", p, width = 10, height = 8, units = "cm", dpi = 300) ``` ### Dimension Presets Query the recommended sizes directly from the helper for reproducible reporting: ```{r dimensions} # Get dimensions for different output types (internal function) report_dims <- BFHtheme:::get_bfh_dimensions(type = "report", format = "standard") print(report_dims) presentation_dims <- BFHtheme:::get_bfh_dimensions(type = "presentation", format = "wide") print(presentation_dims) ``` ## Performance Optimisation Keep your workflow responsive when working with fonts or large datasets. ### Font Caching Font detection results are cached for speed. Clear or refresh the cache after adding or removing fonts mid-session: ```{r cache, eval=FALSE} # Font detection is cached automatically get_bfh_font() # First call: detects font get_bfh_font() # Subsequent calls: uses cache # Clear cache if needed clear_bfh_font_cache() # Force re-detection get_bfh_font(force_refresh = TRUE) ``` ### Large Datasets High-volume data can strain rendering. Consider these approaches: ```{r performance, eval=FALSE} # Use alpha for overplotting ggplot(large_data, aes(x, y)) + geom_point(alpha = 0.3) + theme_bfh() # Use geom_hex or geom_bin2d ggplot(large_data, aes(x, y)) + geom_hex() + scale_fill_bfh_continuous(palette = "blues") + theme_bfh() # Reduce point size ggplot(large_data, aes(x, y)) + geom_point(size = 0.5) + theme_bfh() ``` ## Wrap-Up - Revisit `vignette("getting-started")` for the foundational workflow. - Explore `vignette("theming")` when you need hospital vs Region H branding. - Consult the function reference (`help(package = "BFHtheme")`) for parameter details.