Although R has vast graphical functionality I've lamented the lack of support for additional fonts. You can spend an incredible amount of time fine-tuning a ggplot2
graphic, fiddling with the length of the tick marks, getting the legend just right but then the Helvetica text detracts from the beauty of what you've created.
My understanding is that support for 'non-standard' fonts is extremely difficult given the large number of computing setups, graphics devices etc. Nevertheless we often need to prepare Postscript and PDF plots for scientific papers and reports and the standard fonts often don’t cut it. Luckily there is support for additional fonts particularly if you’re creating PDFs or postscript files. I'm going to show an example using the package extrafont
. There is also a relatively new package called showtext
that I got to work for me, but I didn't find that it offered any functionality beyond extrafont
(and it crashed my R session twice) so I won't cover that package.
1. Import fonts (and some quick data setup)
For the extrafont
package you'll need to make sure that you have GhostScript on your system in order to embed the fonts (you will also need to tell R where it's located – see below). In addition, you will need to import the fonts you need. Luckily the package comes with a function that does this for you without much fuss – it takes a couple of minutes, depending on how many fonts you have. Here is an example of the code to import and then review the fonts:
library(extrafont)
font_import() # import all your fonts
fonts() #get a list of fonts
fonttable()
fonttable()[40:45,] # very useful table listing the family name, font name etc
## package afmfile fontfile FullName
## 1 NA AGENCYB.afm.gz C:\\Windows\\Fonts\\AGENCYB.TTF Agency FB Bold
## 2 NA AGENCYR.afm.gz C:\\Windows\\Fonts\\AGENCYR.TTF Agency FB
## 3 NA ahronbd.afm.gz C:\\Windows\\Fonts\\ahronbd.ttf Aharoni Bold
## 4 NA ALGER.afm.gz C:\\Windows\\Fonts\\ALGER.TTF Algerian
## 5 NA Aller_Rg.afm.gz C:\\Windows\\Fonts\\Aller_Rg.ttf Aller
## 6 NA Aller.afm.gz C:\\Windows\\Fonts\\Aller.ttf Aller Bold
## FamilyName FontName Bold Italic Symbol afmsymfile
## 1 Agency FB AgencyFB-Bold TRUE FALSE FALSE NA
## 2 Agency FB AgencyFB-Reg FALSE FALSE FALSE NA
## 3 Aharoni Aharoni-Bold TRUE FALSE FALSE NA
## 4 Algerian Algerian FALSE FALSE FALSE NA
## 5 Aller Aller FALSE FALSE FALSE NA
## 6 Aller Aller-Bold TRUE FALSE FALSE NA
Now we're ready to use the fonts in an actual plot. Based on my review of Winston Chang's GitHub repository for the package all computer systems can use extrafont
to embed fonts in PDF/PS files but extra fonts are only available in bitmap output on Windows machines.
# a little setup, I'm using data from the amazing NMMAPS air pollution study
# background here http://bit.ly/1pqboBG
library(ggplot2)
nmmaps<-read.csv("chicago-nmmaps.csv", as.is=T)
nmmaps$date<-as.Date(nmmaps$date)
nmmaps<-nmmaps[nmmaps$date>as.Date("1996-01-01"),]
2. Use your new fonts – Bauhaus 93 TrueType font anyone?
Below I'm saving directly to an image and the non-default font shows up both on a screen device and in the saved PNG file. But on a Mac you may be limited to saving to PDF (see next setp)
.
# default font
ggplot(nmmaps, aes(x = date, y = temp)) + geom_point(color="red")+
ggtitle("This is a default font")+
theme(plot.title = element_text(size=30, face="bold", vjust=1))
# new font (note the family argument)
ggplot(nmmaps, aes(x = date, y = temp)) + geom_point(color="red")+
ggtitle("This is a non-default font")+
theme(plot.title = element_text(size=30,
vjust=1, family="Bauhaus 93"))
3. Create a PDF (and don't forget to embed your fonts)
You can use ggplot2
's great ggsave
function to save the plot to PDF.
# note that this step will get warnings that you can ignore
ggsave("newfont.pdf")
If you open the PDF now, though, you will be sorely disappointed! The new font will not appear in the PDF because we have not embedded the font in the PDF yet. In order to do this you have two last steps. Tell R where GhostScript is located and then embed the fonts.
Sys.setenv(R_GSCMD = "C:/Program Files (x86)/gs/gs9.02/bin/gswin32.exe")
embed_fonts("newfont.pdf")
And you're ready to send that PDF directly to your journal of choice.
4. Last comment
I found that most of the fonts worked perfectly both on my image devices as well as PDF but in a few cases something went wrong with the PDF. For example, I played around with the Algerian TrueType font and got output like this:
when it should look like this:
Some digging would be required to track down the issue and, fortunately, Algerian TrueType is not high on my list of fonts to use.
Hi Zev,
Firstly I would like to thank you for this post.
I try to use your method to apply a different font to a graph in ggplot2 but have some problem with ghostscript.
Here’s my script :
#Data analysis Q1.
>library(ggplot2)
>library(extrafont)
>font_import()
>y
>loadfonts()
>fonts()
>fonttable()
>ggplot(data=Q[[1]][Q[[1]]$reg_org==”TOTAL”,],aes(geo,ident_vict))+
geom_boxplot()+
labs(x=”Country”,y=”Number of identified victims”)+
ggtitle(“Number of identified victims by country for 2014-2016”)+
theme(axis.title = element_text(family = “Garamond”, color=”black”, size=12))+
theme(title = element_text(family=”Garamond”,color=”#666666″,size=14))+
theme(axis.text.x = element_text(family=”Garamond”))
>ggsave(“newfont.pdf”)
>Sys.setenv(R_GSCMD = “C:/Program Files/gs/gs922w64.exe”)
>embed_fonts(“newfont.pdf”)
And here’s what I receive as warnings error comments after enter the last command (embed_fonts(“newfont.pdf”)) :
>Error in system(paste(gsexe, “-help”), intern = TRUE, invisible = TRUE) :
‘CreateProcess’ failed to run ‘C:\PROGRA~1\gs\gs922w64.exe -help’
In addition: There were 20 warnings (use warnings() to see them)
Previously, after the ggplot2 command I receive this message of warnings :
>In grid.Call(C_textBounds, as.graphicsAnnot(x$label), … :
famille de police introuvable dans la base de données des polices Windows
(translation of the second line: Font family is unfound inside the Windows Font data base.
Thank you in advance for your help,
Regards,
Paul
I’ve just soluce this problem.
Thanks again for this very interisting post.
Paul