6

I've written a function to share among colleagues for graphing, and my organization prefers Calibri to the ggplot2 default Arial for the text. If I were the only person who'd be using this function, I would first do this at the top of my script:

 library(extrafont)
 font_import()
 loadfonts(device="win")

and then make my ggplot2 graph. I seem to only have to do font_import() once on a given machine, but then I need to do loadfonts(device="win") each time I start a new session. I'm not terribly well versed in what these do, but if I don't do the loadfonts step, my graph doesn't use Calibri.

I'd like the graphing function I wrote to work for others, and I'd like to check whether they've already done these steps and give them a helpful message about it if they haven't. I thought I could use fonts() and then check whether Calibri was listed in the output, but I think that only checks what fonts I've ever loaded with font_import() in the history of using this machine. I also thought maybe

 systemfonts::match_font("Calibri")

would check, but I get the same result regardless of whether I've already run loadfonts(..., so that's not it, either.

How do you check whether a font is ready to be used in a graph?

shirewoman2
  • 1,842
  • 4
  • 19
  • 31
  • 1
    I think you could use `showtext` instead to use the Calibri font on others' computers without needing the extrafont::loadfonts step. – Jon Spring Sep 24 '21 at 05:49
  • Try with `names(grDevices::windowsFonts())`. – stefan Sep 24 '21 at 16:10
  • @JonSpring: What does `showtext` do? What package is that from? I can't find it. – shirewoman2 Sep 25 '21 at 18:40
  • @stefan: That will tell me whether I've got options for serif, sans serif or mono style fonts, but it won't actually tell me the font family. – shirewoman2 Sep 25 '21 at 18:41
  • Agree with @JonSpring - showtext is how I would approach this task - e.g. `install.packages("showtext"); library(showtext); list_of_fonts <- as.data.frame(font_files()); grep(pattern = "Calibri", x = list_of_fonts$family, ignore.case = TRUE, value = TRUE)` – jared_mamrot Sep 27 '21 at 23:43
  • Excellent! Thanks! If either @jared_mamrot or JonSpring post that as an answer, I'll happily accept it. – shirewoman2 Sep 29 '21 at 00:51

1 Answers1

3

Here is one potential approach to determine whether Calibri is installed and 'useable':

install.packages("showtext")
library(showtext)
list_of_fonts <- as.data.frame(font_files())

grep(pattern = "Calibri", x = list_of_fonts$family, ignore.case = TRUE, value = TRUE)

You can implement this in a number of ways, e.g. load the Calibri font if it's available or print a message if it's not available on the system:

if (!require(showtext)) install.packages("showtext")
#> Loading required package: showtext
#> Loading required package: sysfonts
#> Loading required package: showtextdb
library(showtext)
list_of_fonts <- as.data.frame(font_files())
if(any(grepl("Calibri.ttf", list_of_fonts, ignore.case = TRUE))){
  Calibri <- list_of_fonts[list_of_fonts$file == "Calibri.ttf",]
  sysfonts::font_add(family = "Calibri",
                     regular = list.files(path = Calibri$path,
                                          pattern = "Calibri.ttf",
                                          full.names = TRUE))
  print("Calibri available")
} else{
  print("Calibri not found")
}
#> [1] "Calibri available"

library(ggplot2)
showtext_auto()
ggplot(mtcars, aes(wt, mpg)) +
  geom_point() +
  ggtitle("Example plot") +
  theme(text = element_text(family = "Calibri", size = 22))

Created on 2021-09-29 by the reprex package (v2.0.1)

N.B. This should work on windows/macOS/linux but I've only tested it on macOS. Also, @JonSpring commented first, so if he posts an answer please accept his instead of mine

jared_mamrot
  • 22,354
  • 4
  • 21
  • 46