Files
civilyticsR/README.Rmd
T
jared 31d3e2886d
R-CMD-check / R CMD check (push) Successful in 3m36s
feat: bump title sizes, add font_scale to logo functions, ship SVGs
- Change rel_large default from 16/14 to 20/14 (~1.43x) to match the
  Civilytics editorial design system. Subtitle now renders at 1.0x base
  instead of 0.86x.
- Switch axis.text to rel() sizing so all text elements cascade from the
  root font_size, enabling uniform scaling.
- Add font_scale parameter (default 1.1) to civilytics_logo(),
  add_logo(), and add_logo_ga() — inflates text by ~10% before
  arrangeGrob composition to compensate for viewport shrinkage.
- Ship SVG logo variants (mark, wordmark, pulse) in inst/img/ for
  Quarto/HTML templates.
- Add "Maintaining brand assets" section to README documenting inst/img/
  file inventory and update workflow.
- Document full font size hierarchy in theme_civilytics() roxygen.
2026-05-19 12:51:23 -06:00

286 lines
8.4 KiB
Plaintext

---
output: github_document
---
```{r setup, include = FALSE}
knitr::opts_chunk$set(
collapse = TRUE,
comment = "#>",
fig.path = "man/figures/README-",
fig.retina = 2,
dpi = 150,
out.width = "100%"
)
```
# civilytics
Brand themes, color palettes, and utility functions for
[Civilytics Consulting](https://www.civilytics.com). The package provides a
complete ggplot2 theme system drawn from the Civilytics design system ---
warm paper backgrounds, civic-navy ink, and editorial typography --- along
with 10 curated color palettes, logo composition helpers, and data-wrangling
utilities for public-sector analysis.
## Installation
Install from the Civilytics Gitea server:
```r
# install.packages("remotes")
remotes::install_git("https://gitea.civilytics.org/Civilytics/civilyticsR.git")
```
## Quick start
```{r quickstart, fig.height = 4, fig.width = 7, message = FALSE}
library(civilytics)
library(ggplot2)
ggplot(mpg, aes(displ, hwy, colour = class)) +
geom_point(size = 2.5) +
scale_color_civilytics() +
labs(
title = "Fuel economy by engine displacement",
subtitle = "Highway MPG vs. engine size for 234 vehicles",
caption = "Source: EPA fuel economy data (ggplot2::mpg)",
x = "Engine displacement (litres)",
y = "Highway MPG"
) +
theme_civilytics()
```
## Color palettes
The package ships 53 named brand colors in `civilytics_colors` and 10
curated palettes in `civilytics_palettes`. Use `civilytics_palette()` to
retrieve colors by name, or pass palettes directly to the ggplot2 scales.
### Palette gallery
```{r palette-gallery, echo = FALSE, fig.height = 9, fig.width = 7}
show_palette <- function(name, colors) {
n <- length(colors)
df <- data.frame(
x = seq_len(n),
fill = factor(seq_len(n), levels = seq_len(n))
)
ggplot(df, aes(x, y = 1, fill = fill)) +
geom_tile(width = 0.9, height = 0.9, show.legend = FALSE) +
scale_fill_manual(values = colors) +
scale_x_continuous(expand = expansion(add = 0.5)) +
labs(title = name) +
theme_void() +
theme(
plot.title = element_text(
family = "Libre Franklin", face = "bold", size = 11,
hjust = 0, margin = margin(b = 2)
),
plot.margin = margin(4, 4, 4, 4)
)
}
plots <- mapply(
show_palette,
names(civilytics_palettes),
civilytics_palettes,
SIMPLIFY = FALSE
)
gridExtra::grid.arrange(grobs = plots, ncol = 1)
```
### Using palettes
```{r palette-usage, fig.height = 3.5, fig.width = 7}
# Discrete fill with the qualitative palette
ggplot(mpg, aes(class, fill = class)) +
geom_bar(show.legend = FALSE) +
scale_fill_civilytics() +
labs(title = "Vehicle counts by class", x = NULL, y = NULL) +
theme_civilytics(grid = "y")
# Continuous fill with a sequential palette
ggplot(faithfuld, aes(waiting, eruptions, fill = density)) +
geom_tile() +
scale_fill_civilytics("seq_ember", discrete = FALSE) +
labs(title = "Old Faithful eruption density") +
theme_civilytics(grid = "none")
```
## Themes
Three theme variants cover the most common output contexts. All share the
same typographic structure and accept `grid` and `paper_bg` parameters.
### Editorial (default)
The default theme uses a warm paper background with horizontal gridlines ---
an editorial, Pew-style layout.
```{r theme-editorial, fig.height = 4, fig.width = 7}
base_plot <- ggplot(mpg, aes(displ, hwy)) +
geom_point(aes(colour = factor(cyl)), size = 2) +
scale_color_civilytics() +
labs(
title = "Engine size vs. highway fuel economy",
subtitle = "Colored by number of cylinders",
caption = "Source: ggplot2::mpg",
colour = "Cylinders",
x = "Displacement (L)", y = "Highway MPG"
)
base_plot + theme_civilytics()
```
### Grid options
The `grid` parameter controls which major gridlines are drawn.
```{r theme-grids, echo = FALSE, fig.height = 6.5, fig.width = 7}
grid_opts <- c("y", "x", "both", "none")
grid_plots <- lapply(grid_opts, function(g) {
base_plot +
theme_civilytics(grid = g) +
labs(title = paste0("grid = \"", g, "\""), subtitle = NULL, caption = NULL)
})
gridExtra::grid.arrange(grobs = grid_plots, ncol = 2)
```
### Dark
Dark navy background with light text, suitable for presentations or
dashboards on dark surfaces.
```{r theme-dark, fig.height = 4, fig.width = 7}
base_plot + theme_civilytics_dark()
```
### Slide
Transparent background and larger base font (18 pt), sized for Reveal.js
slides or PowerPoint exports.
```{r theme-slide, fig.height = 4, fig.width = 7}
base_plot + theme_civilytics_slide()
```
### Facets
Facet strips use the `paper_2` tint, with the title font.
```{r theme-facets, fig.height = 5, fig.width = 7}
ggplot(mpg, aes(displ, hwy)) +
geom_point(colour = civilytics_colors["navy_600"], size = 1.5) +
facet_wrap(~class, ncol = 4) +
labs(
title = "Highway MPG by vehicle class",
x = "Displacement (L)", y = "Highway MPG"
) +
theme_civilytics(grid = "y")
```
## Logo utilities
Add the Civilytics logo to any ggplot using the pipe-friendly
`civilytics_logo()` or the lower-level `add_logo()` / `make_logo_grob()`.
The logo is automatically right-aligned below the plot area. Wrap the
ggplot chain in parentheses before piping --- R's `|>` binds tighter
than `+`.
### Wordmark on a light plot
```{r logo-wordmark, fig.height = 4.5, fig.width = 7}
p <- ggplot(mpg, aes(displ, hwy, colour = class)) +
geom_point(size = 2) +
scale_color_civilytics() +
labs(
title = "Fuel economy by engine displacement",
caption = "Source: EPA fuel economy data (ggplot2::mpg)",
x = "Displacement (L)", y = "Highway MPG"
) +
theme_civilytics()
grid::grid.draw(civilytics_logo(p))
```
### Compact mark
Use `type = "mark"` for the compact C-pulse icon instead of the full
wordmark.
```{r logo-mark, fig.height = 4.5, fig.width = 7}
p2_logo <- ggplot(mpg, aes(displ, hwy, colour = factor(cyl))) +
geom_point(size = 2) +
scale_color_civilytics() +
labs(
title = "Engine size vs. highway fuel economy",
colour = "Cylinders",
x = "Displacement (L)", y = "Highway MPG"
) +
theme_civilytics()
grid::grid.draw(civilytics_logo(p2_logo, type = "mark"))
```
### Multi-plot layout with logo
Use `add_logo_ga()` to attach a single logo below a row of plots.
```{r logo-multi, fig.height = 4.5, fig.width = 9}
p1 <- ggplot(mpg, aes(class, fill = class)) +
geom_bar(show.legend = FALSE) +
scale_fill_civilytics() +
labs(title = "Vehicle counts", x = NULL, y = NULL) +
theme_civilytics(grid = "y")
p2 <- ggplot(mpg, aes(displ, hwy)) +
geom_point(colour = civilytics_colors["navy_600"], size = 1.5) +
labs(title = "Displacement vs. MPG", x = "Displacement (L)", y = "Highway MPG") +
theme_civilytics(grid = "y")
logo <- make_logo_grob()
grid::grid.draw(add_logo_ga(list(p1, p2), logo))
```
## Other utilities
The package also includes helpers for public-sector data analysis:
| Function | Purpose |
|:---------|:--------|
| `pretty_count()` / `pretty_per()` | Format numbers and percentages |
| `grade_level_to_num()` | Convert grade labels (KG, 01--12) to numeric |
| `race_short_names()` | Standardize NCES race/ethnicity categories |
| `get_fips()` / `get_stabbr()` | State FIPS code lookups |
| `clopper_pearson()` / `agresti_coull_interval()` | Proportion confidence intervals |
| `match_test()` / `trunc_match()` | Fuzzy join diagnostics |
| `perturb_count()` / `random_round()` | Privacy-preserving data perturbation |
## Maintaining brand assets
Logo and brand mark files live in `inst/img/`. The package ships both
PNG (for ggplot2 raster composition) and SVG (for Quarto/HTML output)
variants:
| File | Format | Used by |
|:-----|:-------|:--------|
| `civilytics-wordmark.png` / `.svg` | Full "Civilytics" lockup | `make_logo_grob("wordmark", "light")`, Quarto templates |
| `civilytics-wordmark-reverse.png` / `.svg` | Light-on-dark wordmark | `make_logo_grob("wordmark", "dark")`, dark slides |
| `civilytics-mark.png` / `.svg` | Compact C-pulse icon | `make_logo_grob("mark", "light")` |
| `civilytics-mark-reverse.svg` | Light-on-dark mark | `make_logo_grob("mark", "dark")` |
| `civilytics-pulse.svg` | Standalone waveform glyph | Quarto slide footer chrome |
To update the logos, replace the files in `inst/img/` with new versions
using the same filenames. The PNG files must be raster images (the
ggplot2 logo functions read them via `png::readPNG()`). SVG files are
passed through as-is by Quarto and HTML templates.
After replacing files, re-render the README gallery to update the
screenshots:
```r
devtools::load_all()
rmarkdown::render("README.Rmd")
```