How to use custom typefaces in ggplot2 [macOS only]

Methods
Author

Stefano Coretta

Published

December 21, 2020

I keep hitting my head against this particular (and seemingly simple) task: using custom typefaces in ggplot2 plots and being able to knit to PDF.

The main reason for why I would want to do that is that I often find myself in need of including IPA symbols in plots (more often than not, it’s vowels) and that I want those plots to be included in a knitted PDF.

For some reason, when I think I got it, I have to search again because the solution I previously found no longer works.

So now I took the time to play around with different options and packages, and I found the minimal configuration one needs to use custom typefaces in ggplot2 plots and get a PDF document with those plots embedded in it (it is working as of December 2020, not sure what the year will bring).

In the following sections I will show what this configuration looks like. Note that this post covers only R running on macOS and that things will be different perhaps on Linux and for sure on Windows (maybe I’ll cover those OSs in an update later on).

You can check out my full session info below, but just be aware that I am using R 4.0.3 in macOS Big Sur 11.1, with the latest version of the tidyverse packages at the time of writing.

Enable custom typefaces in ggplot2 plots when knitting to PDF

I was surprised to find out that to include custom typefaces in ggplot2 plots and knit the .Rmd to a PDF document, you just need the following options in your YAML preamble (no need for extra packages!!!).

---
output:
  pdf_document:
    latex_engine: xelatex
    dev: cairo_pdf
---

In particular, the dev option sets cairo_pdf() (shipped with ggplot2) as the default device for rendering the plots within the knitted PDF document.

As Miranda Priestly would say, that’s all…1

Within your document you can then specify the typeface you want to use in the plots. The most straightforward way is to set a ggplot2 theme and specify the base_family argument.

I chose the Fira Sans fonts here because they include the Unicode range of the IPA.

Both when running a chunk with a ggplot2 plot interactively in the .Rmd file and when knitting the .Rmd to a PDF, the plot typeface will be Fira Sans. And we are done.

Extra: Saving ggplot2 plots to a file

Now, what if you want to save the plots with your custom typeface to a file that you can include in another document?

You have two options:

  • You can save the plot as a standalone PDF file (with embedded fonts).
  • Or you can save the plot as a .png image.

Achieving that is quite simple with ggsave():

The magic is done by ggsave(..., device = cairo_pdf) (that’s the same cairo_pdf device we set in the YAML preamble). Note that it’s cairo_pdf and not cairo_pdf() (for reasons beyond my comprehension, it does not work if you add the parentheses).

Here you find a gist with an example .Rmd file that you can download on your machine and knit as a test.

Supported fonts

As far as I can tell, any .ttf (TrueType font) installed on your system with Font Book can be set as the typeface to be used in the ggplot2 plots.

Session info

─ Session info ───────────────────────────────────────────────────────────────
 setting  value
 version  R version 4.3.2 (2023-10-31)
 os       macOS Sonoma 14.0
 system   aarch64, darwin20
 ui       X11
 language (EN)
 collate  en_US.UTF-8
 ctype    en_US.UTF-8
 tz       Europe/London
 date     2023-12-25
 pandoc   3.1.11 @ /opt/homebrew/bin/ (via rmarkdown)

─ Packages ───────────────────────────────────────────────────────────────────
 ! package     * version date (UTC) lib source
 P cachem        1.0.8   2023-05-01 [?] CRAN (R 4.3.0)
 P callr         3.7.3   2022-11-02 [?] CRAN (R 4.3.0)
 P cli           3.6.2   2023-12-11 [?] RSPM (R 4.3.0)
 P crayon        1.5.2   2022-09-29 [?] CRAN (R 4.3.0)
 P devtools      2.4.5   2022-10-11 [?] CRAN (R 4.3.0)
 P digest        0.6.33  2023-07-07 [?] CRAN (R 4.3.0)
 P ellipsis      0.3.2   2021-04-29 [?] CRAN (R 4.3.0)
 P evaluate      0.22    2023-09-29 [?] CRAN (R 4.3.1)
 P fastmap       1.1.1   2023-02-24 [?] CRAN (R 4.3.0)
 P fs            1.6.3   2023-07-20 [?] CRAN (R 4.3.0)
 P glue          1.6.2   2022-02-24 [?] CRAN (R 4.3.0)
 P htmltools     0.5.7   2023-11-03 [?] CRAN (R 4.3.1)
 P htmlwidgets   1.6.2   2023-03-17 [?] CRAN (R 4.3.0)
 P httpuv        1.6.11  2023-05-11 [?] CRAN (R 4.3.0)
 P jsonlite      1.8.7   2023-06-29 [?] CRAN (R 4.3.0)
 P knitr         1.44    2023-09-11 [?] CRAN (R 4.3.0)
 P later         1.3.1   2023-05-02 [?] CRAN (R 4.3.0)
 P lifecycle     1.0.4   2023-11-07 [?] CRAN (R 4.3.1)
 P magrittr      2.0.3   2022-03-30 [?] CRAN (R 4.3.0)
 P memoise       2.0.1   2021-11-26 [?] CRAN (R 4.3.0)
 P mime          0.12    2021-09-28 [?] CRAN (R 4.3.0)
 P miniUI        0.1.1.1 2018-05-18 [?] CRAN (R 4.3.0)
 P pkgbuild      1.4.2   2023-06-26 [?] CRAN (R 4.3.0)
 P pkgload       1.3.3   2023-09-22 [?] CRAN (R 4.3.1)
 P prettyunits   1.2.0   2023-09-24 [?] CRAN (R 4.3.1)
 P processx      3.8.2   2023-06-30 [?] CRAN (R 4.3.0)
 P profvis       0.3.8   2023-05-02 [?] CRAN (R 4.3.0)
 P promises      1.2.1   2023-08-10 [?] CRAN (R 4.3.0)
 P ps            1.7.5   2023-04-18 [?] CRAN (R 4.3.0)
 P purrr         1.0.2   2023-08-10 [?] CRAN (R 4.3.0)
 P R6            2.5.1   2021-08-19 [?] CRAN (R 4.3.0)
 P Rcpp          1.0.11  2023-07-06 [?] CRAN (R 4.3.0)
 P remotes       2.4.2.1 2023-07-18 [?] CRAN (R 4.3.0)
   renv          1.0.3   2023-09-19 [1] CRAN (R 4.3.1)
 P rlang         1.1.2   2023-11-04 [?] CRAN (R 4.3.1)
 P rmarkdown     2.25    2023-09-18 [?] CRAN (R 4.3.1)
 P rstudioapi    0.15.0  2023-07-07 [?] CRAN (R 4.3.0)
 P sessioninfo   1.2.2   2021-12-06 [?] CRAN (R 4.3.0)
 P shiny         1.7.5.1 2023-10-14 [?] CRAN (R 4.3.1)
 P stringi       1.7.12  2023-01-11 [?] CRAN (R 4.3.0)
 P stringr       1.5.0   2022-12-02 [?] CRAN (R 4.3.0)
 P urlchecker    1.0.1   2021-11-30 [?] CRAN (R 4.3.0)
 P usethis       2.2.2   2023-07-06 [?] CRAN (R 4.3.0)
 P vctrs         0.6.5   2023-12-01 [?] CRAN (R 4.3.1)
 P xfun          0.40    2023-08-09 [?] CRAN (R 4.3.0)
 P xtable        1.8-4   2019-04-21 [?] CRAN (R 4.3.0)
 P yaml          2.3.8   2023-12-11 [?] RSPM (R 4.3.0)

 [1] /Users/ste/repos/stefanocoretta.github.io/renv/library/R-4.3/aarch64-apple-darwin20
 [2] /Users/ste/Library/Caches/org.R-project.R/R/renv/sandbox/R-4.3/aarch64-apple-darwin20/ac5c2659

 P ── Loaded and on-disk path mismatch.

──────────────────────────────────────────────────────────────────────────────