Today's guest post comes from Winston Chang, a software developer at RStudio — ed.
When it comes to making figures in R, you can use any font you like, as long as it's Helvetica, Times, or Courier. Using other fonts that are installed on your computer can seem an impossible task, especially if you want to save the output to PDF.
Fortunately, the extrafont package makes this process much easier. With it, you can create beautiful, professional-looking results like this:
When using fonts in PDF files, there are two challenges: First you must tell R that the font is available to use. Next, you must embed the font into the PDF file to make it render properly on another computer or printer that doesn't already have the font.
Here's an example of what a PDF using Garamond might look like when it's not embedded, and printed or viewed on a device that lacks the font. It will substitute some other font in the place of Garamond:
Using extrafont in three easy steps
The first step is to install extrafont, and then import the fonts from your system into the extrafont database:
Installation
install.packages("extrafont")
library(extrafont)
font_import()
You may see some warnings, but you should be able to ignore them. After the fonts are imported, you can view the available fonts by running fonts()
or fonttable()
:
fonts()
## [1] "Andale Mono" "AppleMyungjo"
## [3] "Arial Black" "Arial"
## [5] "Arial Narrow" "Arial Rounded MT Bold"
## [7] "Arial Unicode MS" "Bangla Sangam MN"
## [9] "Brush Script MT" "Comic Sans MS"
## [11] "Courier New" "Georgia"
## [13] "Gujarati Sangam MN" "Impact"
## ...
# This will show more detailed information about fonts
fonttable()
Creating PDF files with fonts
Once you've imported the fonts from your system to the extrafont database, they must be registered with R as being available for the PDF output device. This must be run once in each R session where you want to use the fonts:
library(extrafont)
loadfonts()
# If you want to output to .ps files instead of .pdf, use:
# loadfonts(device="postscript")
After the fonts are registered with R's PDF device, you can create figures with them. Here's an example using base graphics:
pdf("plot_garamond.pdf", family="Garamond", width=4, height=4.5)
plot(mtcars$mpg, mtcars$wt,
main = "Fuel Efficiency of 32 Cars",
xlab = "Weight (x1000 lb)",
ylab = "Miles per Gallon")
dev.off()
Again, you may see some warnings, but they shouldn't cause any problems.
And with ggplot2:
library(ggplot2)
p <- ggplot(mtcars, aes(x=wt, y=mpg)) + geom_point() +
ggtitle("Fuel Efficiency of 32 Cars") +
xlab("Weight (x1000 lb)") + ylab("Miles per Gallon") +
theme_bw() +
theme(text=element_text(family="Garamond", size=14))
ggsave("ggplot_garamond.pdf", p, width=3.5, height=3.5)
Embedding fonts
Extrafont uses GhostScript, a free PostScript interpreter, to embed the fonts. You'll need to make sure it's installed on your computer (note that GhostScript is not an R package). If you're using Windows, you'll also need to tell R where the Ghostscript executable is:
# For Windows - in each session
# Adjust the path to match your installation of Ghostscript
Sys.setenv(R_GSCMD = "C:/Program Files/gs/gs9.05/bin/gswin32c.exe")
To embed the fonts, use embed_fonts()
:
# If you don't specify 'outfile', it will overwrite the original file
embed_fonts("plot_garamond.pdf", outfile="plot_garamond_embed.pdf")
embed_fonts("ggplot_garamond.pdf", outfile="ggplot_garamond_embed.pdf")
If you have many PDF figures that are being put into a single PDF document, it can be more space-efficient to embed the fonts in the final document, instead of in each figure. That way, there will be a single copy of the font in the document instead of one for each figure.
Using Computer Modern (with math symbols)
If you are creating a document with TeX, there's a good chance that your document uses the default font, Computer Modern. Some R users use TikZ (with the tikzDevice package) to create figures that use Computer Modern, to match the appearance of the document text.
With extrafont, you can use Computer Modern in a PDF figure without using TikZ. This is done by installing the font package called fontcm
. (Extrafont supports special font packages that contain a PostScript type 1 font stored in a particular way.)
font_install("fontcm")
It will ask you to download the fontcm package from CRAN, and then it will import the font into the extrafont database. Once that's done, run loadfonts()
to register the fonts with R's PDF device. If you run fonts()
, they will be listed as “CM Roman”, “CM Sans”, and “CM Typewriter”.
Now you can create PDF figures with these fonts:
# Base graphics
pdf("plot_cm.pdf", family="CM Roman", width=5.5, height=5)
curve(dnorm, from=-3, to=3, main="Normal Distribution")
text(x=0, y=0.1, cex=1.5, expression(italic(y == frac(1, sqrt(2 * pi)) *
e ^ {-frac(x^2, 2)} )))
dev.off()
embed_fonts("plot_cm.pdf", outfile="plot_cm_embed.pdf")
And with ggplot2:
# ggplot2
exp_text <- "italic(y == frac(1, sqrt(2 * pi)) * e ^ {-frac(x^2, 2)} )"
p <- ggplot(data.frame(x=c(-3,3)), aes(x=x)) + ggtitle("Normal Distribution") +
stat_function(fun=dnorm, geom="line") +
theme_bw() +
theme(text=element_text(family="CM Roman")) +
annotate("text", x=0, y=0.1, label=exp_text, parse=TRUE, family="CM Roman")
ggsave("ggplot_cm.pdf", p, width=4, height=3.5)
embed_fonts("ggplot_cm.pdf", outfile="ggplot_cm_embed.pdf")
Note that font packages installed this way can only be used for PDF and PostScript figures generated with R. They aren't available for on-screen output, nor are they available for use for other programs.
Output to bitmap files (PNG, TIFF)
If you output graphics using Linux or Mac, you are probably using the Cairo device or Quartz output devices. With these output devices, system fonts are generally available without having to jump through any of these hoops.
On Windows, however, the default output device, “windows”, requires registering fonts to work with it. Usually this is a bit of a chore, but extrafont makes it easy. After the fonts have been imported:
loadfonts(device = "win")
This registers the fonts with R's windows output device. Then you can make bitmap figures with system fonts on screen, or saved to a file.
Experimental support for OTF and TTC files
The released version of extrafont can only import TTF (TrueType) fonts. It doesn't work with with OTF (OpenType) and TTC (TrueType font collection) files, which are increasingly common. There is an in-development version supports these file formats. It can be installed from GitHub, using the devtools package. This requires that you have a C compiler installed on your system, and the proper R development environment set up:
library(devtools)
install_github("Rttf2pt1", "wch")
install_github("extrafont", "wch")
Once it's installed, import the fonts as before:
library(extrafont)
font_import()
Support for these file types is experimental. If you find any issues, please report them on the issues page for extrafont:
https://github.com/wch/extrafont/issues
Learning more
For more information, see:
- extrafont project page
- fontcm project page
- A writeup by Paul Murrell about using symbol fonts with R. (The fontcm package should take care of the issues.)
The current version of extrafont is 0.11. Previous version had problems with character spacing when you use hyphens and minus signs, but it should be fixed in the latest version.
Winston Chang graduated in 2012 from Northwestern University with a PhD in Psychology. He is now a software developer for RStudio, working primarily on developing the ggplot2 package for data visualization. He created and maintains the "Cookbook for R" website, and is the author of the forthcoming book "R Graphics Cookbook", to be published by O'Reilly Media.
Thanks for this absolutely great post! I've been craving for such a functionality :) Keep up the great work!
Posted by: Sebastian | September 21, 2012 at 02:20
Hi Winston, this looks super interesting, and thanks for posting. However, when I try to install extrafont in Rstudio, I get the following error: package ‘extrafont’ is not available (for R version 2.14.1) Do you know how to proceed? Best, Sebastian
Posted by: Sebastian Nielsen | September 25, 2012 at 08:02
Hi Sebastian - I uploaded it to CRAN pretty recently, and they build it only for the latest version of R, which is now 2.15.1. The best thing to do is upgrade your copy of R. Normally, an alternative solution would be to install extrafont from a source package, but I believe it uses some features (of the system2() function) that were introduced in R 2.15, and it probably won't work correctly on R 2.14.
Posted by: Winston Chang | September 25, 2012 at 08:03
Winston - I'm a relative newbie to R but when I try to run your ggplot2 code in the first example I get errors saying that the functions "ggtitle" and "theme" could not be found. Which package are they contained in ??? I came up pretty much blank on google ... thanks in advance.
Posted by: Craig B | September 25, 2012 at 08:04
Craig - this requires the latest version of ggplot2, 0.9.2.1. You can get it by running update.packages().
Posted by: Winston Chang | September 25, 2012 at 08:05
I just noticed that for the experimental OTF and TTC support, I forgot to specify the branch. To install it, these are the commands to run: library(devtools) install_github("Rttf2pt1", "wch", "freetype2") install_github("extrafont", "wch", "freetype")
Posted by: Winston Chang | September 25, 2012 at 08:06
Craig, those are in the ggplot2 package.
Posted by: erock | September 25, 2012 at 08:06
I tried to install and use the Georgia font in Ubuntu and R 2.15.1 but got a message: Warning in load fonts() : More than one version of regular/bold/italic font for Georgia. Skipping setup for this font. Finally the font has not been installed. Is there any workaround for the problem?
Posted by: Vladimir S. | October 04, 2012 at 21:28
Winston, this is quite nice. Do you know how I could use extrafonts as an alternative to the Cairo setup I just described in http://wp.me/p1X1Iq-8O ?
Posted by: Greg Tucker-Kellogg | October 15, 2012 at 04:21
Interesting diagrams i have never tried to work out the R charts as seen above, but this article has teached me something about car fuel. thanks
Posted by: Mary Nightwood | November 01, 2012 at 11:36
Thanks a lot for this! It was really helpful!
Posted by: Caner Gocmen | April 16, 2013 at 08:32
Hi winston, thanks for that article.
Have you had any luck with dfonts?
Posted by: Alex | July 12, 2013 at 10:19
Hi Winston,
So I've installed an external font as described, however, wordcloud seems to complain about not finding it.
Please see my post here: http://stackoverflow.com/questions/18108512/r-wordcloud-external-ttf-vfont-not-recognized
TIA!
Posted by: Paul | August 07, 2013 at 09:28
Hi Winston,
Thanks for developing this! However, I'm having a problem with getting the correct font in the legend of my plot using legend(). Any ideas?
Posted by: Kevin | August 28, 2013 at 09:55