I love good typography, even more so as Microsoft Word and PowerPoint have debased our standards. When I see a really fine piece of technical typesetting, it’s almost always done using TeX and friends. Beautiful LaTeX documents are easy to recognize. Beautiful R graphics are also easy to recognize. When literate programming systems like Sweave, Org mode, or knitr weave R graphics and LaTeX typesetting together, the beauty of both LaTeX and R is obvious, but documents can still look all wrong because of font clash.
Documents typeset purely in LaTeX can have a visual consistency that is hard to match. Take Kevin Lynagh‘s beautifully typeset undergraduate thesis. Kevin obviously cares about typography, so much that he ended up making many of his plots in using the LaTeX pgfplots package, based on the equally incredible PGF/TikZ. These are terrific packages, and ones that I use myself. But these are not replacements for R. To get R graphics output into LaTeX without any font clash, I need to either use something like the tikzDevice package, which has been dropped from CRAN and seems to have stalled, or generate PDFs and PNGs that complement my font choices in LaTeX. [edit: Kevin's thesis source is available here.]
As wonderful as R is for plotting, changing the fonts in plots can be a bit cryptic. The base graphics package has methods, but
ggplot2 are built on top of the
grid package, which is another beast entirely. The extrafonts package described by Winston Chang is a terrific option for individual plots, but at least for me it didn’t seem quite clear how to change an entire literate document in a single line.
An alternative is the Cairo package which provides the ability to change fonts in any supported device. Cairo also provides its own drop in replacement commands to the standard commands
pdf(), etc., which can be dropped in for a literate programing session. I’d be interested to know what limitations others have found in these replacements.
Most of the time I use the LaTeX mathdesign package with Charter BT fonts. But I’m fickle, and sometimes use urw-garamond. When preparing Beamer presentations at NUS I tend to use Verdana, because that’s the university’s standard. Since I’m almost always using Org, with R blocks evaluated in the Babel literate programming framework, I want a solution in which all the graphics generated by R will match the LaTeX main text font as closely as possible. When I move an R code block from a beamer presentation to a manuscript draft, I don’t want to have to do anything special. It should just work.
The solution using Cairo appears to be pretty simple. In the beginning of an Org mode document in which the LaTeX will be typeset in Garamond, I can put the following
#+begin_src R :exports none :results silent :session library(Cairo) mainfont <- "Garamond" CairoFonts(regular = paste(mainfont,"style=Regular",sep=":"), bold = paste(mainfont,"style=Bold",sep=":"), italic = paste(mainfont,"style=Italic",sep=":"), bolditalic = paste(mainfont,"style=Bold Italic,BoldItalic",sep=":")) pdf <- CairoPDF png <- CairoPNG #+end_src
With that in place, my fonts in exported PDF or PNG graphics from R will all use Garamond, largely in keeping with the LaTeX font. Strictly speaking, the urw-garamond in the LaTeX
mathdesign package is not the same as the system font on MacOSX that R will be using, but it’s pretty close. Note this has to be done in each R session if an Org-mode file is running multiple sessions.
So for example, a code block like
#+begin_src R :exports results :results graphics :session :file histogram.png x <- rnorm(100) hist(x,main="This is a histogram using Garamond") #+end_src
will result in a histogram like
The Cairo package is all well documented stuff, though I have to admit I found the other ways of handling graphics fonts confusing. But within the limits of the four choices available in Cairo, one can mix and match system fonts. If your locale supports UTF-8, you can do some crazy things. For example, you can redefine the italic family to a font that supports Chinese characters, and create something completely nonsensical, such as a ggplot histogram with text in a mix of xkcd and Chinese, e.g.
#+begin_src R :exports results :results graphics output :session :file chinese.png Sys.setlocale("LC_CTYPE","en_US.UTF-8") library(Cairo) mainfont <- "xkcd" CairoFonts(regular = paste(mainfont,"style=Regular",sep=":"), bold = paste(mainfont,"style=Bold",sep=":"), italic = paste("SimSun","style=Regular",sep=":"), bolditalic = paste(mainfont,"style=Bold Italic,BoldItalic",sep=":")) pdf <- CairoPDF png <- CairoPNG qplot(x) + theme_bw() + ggtitle(expression(paste(italic("这是一个用"),"xkcd",italic("的直方图")))) #+end_src
Alas, the XKCD font is not Unicode, so there are no Chinese xkcd characters.
In this case, what works for Org mode should work equally well for Sweave and knitr