Installing fonts so that R postscript() device can recognise them
Asked Answered
G

1

6

Based on the advice in this post I am trying to get the serif font (or 'family' of fonts) installed into R so that I can save ggplots as .eps files. Though the suggestion provided worked I would like to try to resolve the issue for future use.

Here's code to generate the issue.

library(bayesplot)
df <- data.frame(xVar = rnorm(1e4,0,1), yVar = rnorm(1e4,2,1), zVar = rnorm(1e4,4,1))
t <- bayesplot::mcmc_trace(df) 
t

enter image description here

Now when I go to save the figure...

ggplot2::ggsave(filename = "tPlot.eps", 
                plot = t, 
                device = "eps", 
                dpi = 1200, 
                width = 15,
                height = 10, 
                units = "cm")

...it throws the error

Error in grid.Call(C_stringMetric, as.graphicsAnnot(x$label)) : 
  family 'serif' not included in postscript() device

In the previous post the answerer suggested I download the extrafont package.

I ran

View(fonttable())

But the serif font did not appear to be installed.

Then I tried

font_addpackage(pkg = "serif")

But I got the error

Error in font_addpackage(pkg = "serif") : 
  Unknown font package type: not type1 or ttf.

Does anyone know how to install the serif font so R can recognise/use it?

Garzon answered 13/8, 2019 at 20:37 Comment(9)
Serif is not a font, it's a type of feature fonts may have or not.Irrigate
@Rui Barradas you are right but the error message I copied into the post seems to indicate that R sees it a 'family', whatever that means. Do you have any tips on how to install it?Garzon
I don't interpret the error message the same way you do. I think it means that "serif" is not recognized as a font type. But there are 458 serif fonts in package extrafont, try fnt <- fonts();i <- grep("serif", fnt, ignore.case = TRUE);fnt[i] to have a vector of their names.Irrigate
thank you @Rui Barradas. I used your code and got [1] "Microsoft Sans Serif" "MS Reference Sans Serif" which I gather are not serif fonts. Times New Roman is a serif font though, and when I do View(fonttable()) Times New Roman is there, but I still get that error message. Also View(fonttable()) only returns 81 font names. I am very confused about the difference between loading, embedding, and installing fonts. How do I install the 458 fonts you mention so that R can recognise them?Garzon
Have you read the package documentation?Irrigate
Just the helps for each command. Didn't get anywhere. This helps. Thank you again @Rui Barradas.Garzon
Have you run font_import()? It's needed to install the fonts. After running it your ggsave code is not giving me errors.Irrigate
Yes it did @Rui Barradas! It didn't yeaterday, Very strange, Oh well. Thank you. Put it in an answer, any answer, and I'll accept it.Garzon
Glad to help, that's what SO is about :). See if the answer is what you wanted.Irrigate
I
5

With package extrafont the fonts must be installed before being made available to users. This is done with function font_import.

library(extrafont)

font_import()    # This takes several minutes

Now we can see what are the fonts installed and available. From the documentation, help("fonts").

Description

Show the fonts that are registered in the font table (and available for embedding)

fonts_installed <- fonts()

serif1 <- grepl("serif", fonts_installed, ignore.case = TRUE)
sans1 <- grepl("sans", fonts_installed, ignore.case = TRUE)

fonts_installed[serif1 & !sans1]

sum(serif1 & !sans1)
#[1] 458

There are 458 fonts available.
Another way to see the font table is with function fonttable but the fonts returned are not necessarily available for embedding. From help("fonttable").

Description

Returns the full font table

Note that the function returns a dataframe, hence the call to str below (output omitted).

df_font <- fonttable()
str(df_font)

serif2 <- grepl("serif", df_font$FontName, ignore.case = TRUE)
sans2 <- grepl("sans", df_font$FontName, ignore.case = TRUE)

df_font$FontName[serif2 & !sans2]

Finally see if the graphing functions work on a postscript device.

library(bayesplot)

df <- data.frame(xVar = rnorm(1e4,0,1), yVar = rnorm(1e4,2,1), zVar = rnorm(1e4,4,1))
p <- bayesplot::mcmc_trace(df)
p

ggplot2::ggsave(filename = "tPlot.eps", 
                plot = p, 
                device = "eps", 
                dpi = 1200, 
                width = 15,
                height = 10, 
                units = "cm")
Irrigate answered 15/8, 2019 at 10:35 Comment(2)
When I run this it successfully registers the fonts, yet when I see those that are available for embedding I only get two options. Any idea why this is?Prismatic
@Prismatic No, I cannot say I do. Maybe ask another question with a link to this question and the code you have run?Irrigate

© 2022 - 2024 — McMap. All rights reserved.