9.7 High-quality graphics

The rmarkdown package has set reasonable default graphical devices for different output formats. For example, HTML output formats use the png() device, so knitr will generate PNG plot files, and PDF output formats use the pdf() device, etc. If you are not satisfied by the quality of the default graphical devices, you can change them via the chunk option dev. All possible devices supported by knitr are: "bmp", "postscript", "pdf", "png", "svg", "jpeg", "pictex", "tiff", "win.metafile", "cairo_pdf", "cairo_ps", "quartz_pdf", "quartz_png", "quartz_jpeg", "quartz_tiff", "quartz_gif", "quartz_psd", "quartz_bmp", "CairoJPEG", "CairoPNG", "CairoPS", "CairoPDF", "CairoSVG", "CairoTIFF", "Cairo_pdf", "Cairo_png", "Cairo_ps", "Cairo_svg", "svglite", and "tikz".

Usually a graphical device name is also a function name. If you want to know more about a device, you can read the R help page. For example, you can type ?svg in the R console to know the details about the svg device, which is included in base R. Note that the quartz_* devices are based on the quartz() function, and they are only available on macOS. The CairoXXX devices are from the add-on R package Cairo, the Cairo_xxx devices are from the cairoDevice package, the svglite device is from the svglite package, and tikz is a device in the tikzDevice package. If you want to use devices from an add-on package, you have to install the package first.

Usually vector graphics have higher quality than raster graphics, and you can scale vector graphics without loss of quality. For HTML output, you may consider using dev = "svg" or dev = "svglite" for SVG plots. Note that SVG is a vector graphics format, and the default png device produces a raster graphics format.

For PDF output, if you are really picky about the typeface in your plots, you may use dev = "tikz", because it offers native support for LaTeX, which means all elements in a plot, including text and symbols, are rendered in high quality through LaTeX. Figure 9.2 shows an example of writing LaTeX math expressions in an R plot rendered with the chunk option dev = "tikz".

par(mar = c(4, 4, 2, .1))
curve(dnorm, -3, 3, xlab = '$x$', ylab = '$\\phi(x)$',
      main = 'The density function of $N(0, 1)$')
text(-1, .2, cex = 3, col = 'blue',
  '$\\phi(x)=\\frac{1}{\\sqrt{2\\pi}}e^{\\frac{-x^2}{2}}$')
A plot rendered via the tikz device.

FIGURE 9.2: A plot rendered via the tikz device.

Note that base R actually supports math expressions, but they are not rendered via LaTeX (see ?plotmath for details). There are several advanced options to tune the typesetting details of the tikz device. You may see ?tikzDevice::tikz for the possibilities. For example, if your plot contains multibyte characters, you may want to set the option:

options(tikzDefaultEngine = "xetex")

That is because xetex is usually better than the default engine pdftex in processing multibyte characters in LaTeX documents.

There are two major disadvantages of the tikz device. First, it requires a LaTeX installation, but this may not be too bad (see Section 1.1). Second, it is often significantly slower to render the plots, because this device generates a LaTeX file and has to compile it to PDF. If you feel the code chunk is time-consuming, you may enable caching by the chunk option cache = TRUE.

For Figure 9.2, we also used the chunk option fig.process = pdf2png, where the function pdf2png is defined in Section 9.6 to convert the PDF plot to PNG when the output format is not LaTeX. Without the conversion, you may not be able to view the PDF plot in the online version of this book in the web browser.