rggplot2fontsextrafont

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


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?


Solution

  • 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")