This text expects a basic understanding of fonts and typography. If you feel like you could use a brush-up you can consult this light introduction to the subject.
systemfonts is designed to give R a modern text rendering stack. That’s unfortunately impossible without coordination with the graphics device, which means that to use all these features you need a supported graphics device. There are currently two options:
You might notice there’s currently a big hole in this workflow: PDFs. This is something we plan to work on in the future.
With all that said, how do you actually use systemfonts to use custom fonts in your plots? First, you’ll need to use ragg or svglite.
While there is no way to unilaterally make
ragg::agg_png() the default everywhere, it’s possible to
get close:
Positron: recent versions automatically use ragg for the plot pane if it’s installed.
RStudio IDE: set “AGG” as the backend under Global Options > General > Graphics.
ggplot2::ggsave(): ragg will be automatically used
for raster output if installed.
R Markdown and Quarto: you need to set the dev
option to "ragg_png". You can either do this with code:
Or in Quarto, you can set it in the yaml metadata:
If you want to use a font installed on your computer, you’re done!
grid::grid.text(
"Spectral 🎉",
gp = grid::gpar(fontfamily = "Spectral", fontface = 2, fontsize = 30)
)Or, if using ggplot2
library(ggplot2)
ggplot(na.omit(penguins)) +
geom_point(aes(x = bill_len, y = body_mass, colour = species)) +
labs(x = "Bill Length", y = "Body Mass", colour = "Species") +
theme_minimal(base_family = "Spectral")If the results don’t look as you expect, you can use various systemfonts helpers to diagnose the problem:
systemfonts::match_fonts("Spectral", weight = "bold")
#> # A tibble: 1 × 4
#> path index features variations
#> <chr> <int> <list> <list>
#> 1 /Users/thomas/Library/Fonts/Spectral 700.ttf 0 <font_ftr> <fnt_vrtn>
systemfonts::font_fallback("🎉", family = "Spectral", weight = "bold")
#> path index
#> 1 /System/Library/Fonts/Apple Color Emoji.ttc 0If you want to see all the fonts that are available for use, you can
use systemfonts::system_fonts()
As we discussed above, the R interface only allows you to select
between four styles: plain, italic, bold, and bold-italic. If you want
to use a thin font, you have no way of communicating this wish to the
device. To overcome this, systemfonts provides
register_variant() which allows you to register a font with
a new typeface name. For example, to use the light font from the
Spectral typeface you can register it as follows:
Now you can use Spectral Light where you would otherwise specify the typeface:
grid::grid.text(
"Light weight is soo classy",
gp = grid::gpar(fontfamily = "Spectral Light", fontsize = 30)
)register_variant() also allows you to turn on font
features otherwise hidden away:
systemfonts::register_variant(
name = "Spectral Small Caps",
family = "Spectral",
features = systemfonts::font_feature(
letters = "small_caps"
)
)
grid::grid.text(
"All caps — Small caps",
gp = grid::gpar(fontfamily = "Spectral Small Caps", fontsize = 30)
)Historically, systemfonts primary role was to access the font
installed on your computer, the system fonts. But what
if you’re using a computer where you don’t have the rights to install
new fonts, or you don’t want the hassle of installing a font just to use
it for a single plot? That’s the problem solved by
systemfonts::add_font() which makes it easy to use a font
based on a path. But in many cases you don’t even need that as
systemfont now scans ./fonts and ~/fonts and
adds any font files it find. This means that you can put personal fonts
in a fonts folder in your home directory, and project fonts in a fonts
directory at the root of the project. This is a great way to ensure that
specific fonts are available when you deploy some code to a server.
And you don’t even need to leave R to populate these folders.
systemfonts::get_from_google_fonts() will download and
install a google font in ~/fonts:
systemfonts::get_from_google_fonts("Barrio")
grid::grid.text(
"A new font a day keeps Tufte away",
gp = grid::gpar(fontfamily = "Barrio", fontsize = 30)
)