cran checks CRAN status Minimal R VersionLicensedownloadsDOI

hrbrthemes

Additional Themes and Theme Components for ‘ggplot2’


This is a very focused package that provides typography-centric themes and theme components for ggplot2.

The core theme: theme_ipsum (“ipsum” is Latin for “precise”) uses Arial Narrow which should be installed on practically any modern system, so it’s “free”-ish. This font is condensed, has solid default kerning pairs and geometric numbers. That’s what I consider the “font trifecta” must-have for charts. An additional quality for fonts for charts is that they have a diversity of weights. Arial Narrow (the one on most systems, anyway) does not have said diversity but this quality is not (IMO) a “must have”.

The following functions are implemented/objects are exported:

Themes:

Scales (that align with various themes):

Palettes/Named Colors:

Fonts:

Flexoki Color Scales:

Bit12 Color Scales:

Tern & omp Color Scales:

Tern Palettes:

Flexoki Palettes:

Utilities:

Installation

remotes::install_git("https://rud.is/git/hrbrthemes", git = "external")

or

install.packages("hrbrthemes") # NOTE: CRAN version is 0.9.3
# or
remotes::install_git("https://codeberg.org/hrbrmstr/hrbrthemes.git")

NOTE: To use the ‘remotes’ install options you will need to have the {remotes} package installed.

Usage

library(hrbrthemes)
library(gcookbook)
library(tidyverse)

# current version
packageVersion("hrbrthemes")
## [1] '0.9.5'

Base theme (Arial Narrow)

ggplot(mtcars, aes(mpg, wt)) +
  geom_point() +
  labs(x="Fuel efficiency (mpg)", y="Weight (tons)",
       title="Seminal ggplot2 scatterplot example",
       subtitle="A plot that is only useful for demonstration purposes",
       caption="Brought to you by the letter 'g'") +
  theme_ipsum()

Roboto Condensed

ggplot(mtcars, aes(mpg, wt)) +
  geom_point() +
  labs(x="Fuel efficiency (mpg)", y="Weight (tons)",
       title="Seminal ggplot2 scatterplot example",
       subtitle="A plot that is only useful for demonstration purposes",
       caption="Brought to you by the letter 'g'") +
  theme_ipsum_rc()

FT Theme

ggplot(mtcars, aes(mpg, wt)) +
  geom_point(color = ft_cols$yellow) +
  labs(x="Fuel efficiency (mpg)", y="Weight (tons)",
       title="Seminal ggplot2 scatterplot example",
       subtitle="A plot that is only useful for demonstration purposes",
       caption="Brought to you by the letter 'g'") +
  theme_ft_rc()

IBM Plex Sans

ggplot(mpg, aes(displ, hwy)) +
  geom_jitter(aes(color=class, fill=class), size=3, shape=21, alpha=1/2) +
  scale_x_continuous(expand=c(0,0), limits=c(1, 8), breaks=1:8) +
  scale_y_continuous(expand=c(0,0), limits=c(10, 50)) +
  scale_color_ipsum() +
  scale_fill_ipsum() +
  facet_wrap(~class, scales="free") +
  labs(
    title="IBM Plex Sans Test",
    subtitle="This is a subtitle to see the how it looks in IBM Plex Sans",
    caption="Source: hrbrthemes & IBM"
  ) +
  theme_ipsum_ps(grid="XY", axis="xy") +
  theme(legend.position="none") -> gg

flush_ticks(gg)
## theme(axis.text.x=element_text(hjust=c(0, rep(0.5, 6), 1))) +
## theme(axis.text.y=element_text(vjust=c(0, rep(0.5, 3), 1)))

NEW! Archivo

ggplot(mtcars, aes(mpg, wt)) +
  geom_point(aes(color=factor(carb))) +
  labs(x="Fuel efficiency (mpg)", y="Weight (tons)",
       title="Seminal ggplot2 scatterplot example",
       subtitle="A plot that is only useful for demonstration purposes",
       caption="Brought to you by the letter 'g'") +
  scale_color_ipsum() +
  theme_ipsum_archivo()

Scales (Color/Fill)

ggplot(mtcars, aes(mpg, wt)) +
  geom_point(aes(color=factor(carb))) +
  labs(x="Fuel efficiency (mpg)", y="Weight (tons)",
       title="Seminal ggplot2 scatterplot example",
       subtitle="A plot that is only useful for demonstration purposes",
       caption="Brought to you by the letter 'g'") +
  scale_color_ipsum() +
  theme_ipsum_rc()

Scales (Axis)

count(mpg, class) %>%
  mutate(pct=n/sum(n)) %>%
  ggplot(aes(class, pct)) +
  geom_col() +
  scale_y_percent() +
  labs(x="Fuel efficiency (mpg)", y="Weight (tons)",
       title="Seminal ggplot2 column chart example with percents",
       subtitle="A plot that is only useful for demonstration purposes",
       caption="Brought to you by the letter 'g'") +
  theme_ipsum(grid="Y")
ggplot(uspopage, aes(x=Year, y=Thousands, fill=AgeGroup)) +
  geom_area() +
  scale_fill_ipsum() +
  scale_x_continuous(expand=c(0,0)) +
  scale_y_comma() +
  labs(title="Age distribution of population in the U.S., 1900-2002",
       subtitle="Example data from the R Graphics Cookbook",
       caption="Source: R Graphics Cookbook") +
  theme_ipsum_rc(grid="XY") +
  theme(axis.text.x=element_text(hjust=c(0, 0.5, 0.5, 0.5, 1))) +
  theme(legend.position="bottom")
update_geom_font_defaults(font_rc_light)

count(mpg, class) %>%
  mutate(n=n*2000) %>%
  arrange(n) %>%
  mutate(class=factor(class, levels=class)) %>%
  ggplot(aes(class, n)) +
  geom_col() +
  geom_text(aes(label=scales::comma(n)), hjust=0, nudge_y=2000) +
  scale_y_comma(limits=c(0,150000)) +
  coord_flip() +
  labs(x="Fuel efficiency (mpg)", y="Weight (tons)",
       title="Seminal ggplot2 column chart example with commas",
       subtitle="A plot that is only useful for demonstration purposes, esp since you'd never\nreally want direct labels and axis labels",
       caption="Brought to you by the letter 'g'") +
  theme_ipsum_rc(grid="X")

Spellcheck ggplot2 labels

df <- data.frame(x=c(20, 25, 30), y=c(4, 4, 4), txt=c("One", "Two", "Three"))

ggplot(mtcars, aes(mpg, wt)) +
  geom_point() +
  labs(x="This is some txt", y="This is more text",
       title="Thisy is a titlle",
       subtitle="This is a subtitley",
       caption="This is a captien") +
  theme_ipsum_rc(grid="XY") -> gg

gg_check(gg)
## Possible misspelled words in [title]: (Thisy, titlle)
## Possible misspelled words in [subtitle]: (subtitley)
## Possible misspelled words in [caption]: (captien)

Flexoki Color Scales

The Flexoki color system provides both discrete and continuous color scales in light and dark variants.

# Discrete colors example with light variant
ggplot(mpg, aes(class, fill=class)) +
  geom_bar() +
  labs(title="Flexoki Light Colors",
       subtitle="Discrete color scale example",
       caption="Using scale_fill_flexoki_light()") +
  theme_ipsum() +
  scale_fill_flexoki_light() +
  theme(legend.position="none")
# Dark variant with points
ggplot(mpg, aes(displ, hwy, color=class)) +
  geom_point(size=3) +
  labs(title="Flexoki Dark Colors",
       subtitle="Another discrete color example",
       caption="Using scale_color_flexoki_dark()") +
  theme_ipsum_rc() +
  scale_color_flexoki_dark()
library(patchwork)

data.frame(
  x = rep(1:50, 50),
  y = rep(1:50, each=50),
  z = sqrt((rep(1:50, 50)-25)^2 + (rep(1:50, each=50)-25)^2)
) -> grad_df

names(flexoki_dark) |> 
  map(\(.p) {
    ggplot(grad_df, aes(x, y, fill=z)) +
      geom_tile() +
      scale_fill_flexoki_continuous(palette = .p) +
      labs(
        x = NULL, y = NULL
      ) +
      theme_ipsum(grid="") +
      theme(legend.position = "none")
  }) |> 
  do.call(what = "wrap_plots") +
  plot_layout(ncol = 4) +
  plot_annotation(
    title="Flexoki Continuous Color Scales",
    subtitle="All 8 continuous color palettes",
    caption="Using scale_fill_flexoki_continuous()",
    theme = theme_ipsum(grid="")
  )

Bit12 Color Scales

The Bit12 color system provides a set of 12 distinct colors optimized for data visualization.

# Discrete colors example
ggplot(mpg, aes(class, fill=class)) +
  geom_bar() +
  labs(title="Bit12 Color Palette",
       subtitle="A vibrant 12-color categorical palette",
       caption="Using scale_fill_bit12()") +
  theme_ipsum() +
  scale_fill_bit12() +
  theme(legend.position="none")
library(patchwork)

# Taking a subset of the palette for this example
names(bit12)[c(1,3,5,7,9,11)] |> 
  map(\(.p) {
    ggplot(grad_df, aes(x, y, fill=z)) +
      geom_tile() +
      scale_fill_bit12_continuous(palette = .p) +
      labs(
        x = NULL, y = NULL, title = .p
      ) +
      theme_ipsum(grid="") +
      theme(legend.position = "none")
  }) |> 
  do.call(what = "wrap_plots") +
  plot_layout(ncol = 3) +
  plot_annotation(
    title="Bit12 Continuous Color Scales",
    subtitle="Selected continuous color palettes",
    caption="Using scale_fill_bit12_continuous()",
    theme = theme_ipsum(grid="")
  )

Tern & omp Color Scales

Tern is a terminal, and omp draws charts inside it. The tern_* functions match that pairing: theme_tern() follows Tern’s dark-cosmos chrome (page and panel #07070d, muted #8c88a3, dim #66627b, #101019 grid, no axis lines or ticks), while the scales use the series palette omp derives for its chart SVGs. omp starts from the theme accent in OKLCH, picks six hues at least 30 degrees apart, clamps lightness to [0.68, 0.82] in dark themes ([0.52, 0.66] in light ones) and chroma to 0.19. omp_chart_palette() reproduces that derivation, so a different accent yields the palette omp would draw. With the titanium accent the six colors are #00b4ff, #ff8500, #68e371, #b474f4, #f05b93, and #00dfe8.

ggplot(mpg, aes(class, fill=class)) +
  geom_bar() +
  scale_fill_tern() +
  theme_tern() +
  labs(
    title="Tern / omp color palette",
    subtitle="dark-cosmos chrome with the omp chart series colors",
    caption="Using scale_fill_tern() + theme_tern()"
  ) +
  theme(legend.position="none")
ggplot(faithfuld, aes(waiting, eruptions, fill=density)) +
  geom_tile() +
  scale_fill_tern_continuous() +
  theme_tern() +
  labs(
    title="Tern / omp continuous scale",
    subtitle="A Lab ramp through the omp chart palette",
    caption="Using scale_fill_tern_continuous()"
  )

theme_tern() defaults to Geist, the first family in omp’s chart font stack. The package ships Geist TTFs in inst/fonts/geist; run import_geist() to find them and install them on your system before rendering, or pass a different base_family.

omp_chart_palette()
omp_chart_palette("#5b4bb7")  # Tern dark-cosmos accent
omp_chart_palette(light=TRUE)

hrbrthemes Metrics

Lang # Files (%) LoC (%) Blank lines (%) # Lines (%)
R 29 0.44 2395 0.46 405 0.5 1476 0.5
SVG 2 0.03 150 0.03 0 0.0 0 0.0
JSON 2 0.03 50 0.01 0 0.0 0 0.0
SUM 33 0.50 2595 0.50 405 0.5 1476 0.5

{cloc} 📦 metrics for hrbrthemes

Code of Conduct

Please note that this project is released with a Contributor Code of Conduct. By participating in this project you agree to abide by its terms.