Setting the Graphics Device in a RMarkdown Document


In our recent post about saving R graphics, it became obvious that achieving consistent graphics across platforms or even saving the “correct” graph on a particular OS was challenging. Getting consistent fonts across platforms often failed, and for the default PNG device under Windows, anti-aliasing was also an issue. The conclusion of the post was to use

  • grDevices::cairo_pdf() for saving PDF graphics or
  • grDevices::png(..., type = "cairo_png") for PNGs or alternatively
  • the new ragg package.

In many workflows, function calls to graphic devices are not explicit. Instead, the call is made by another package, such as knitr.

When kniting an Rmarkdown document, the default graphics device when creating PDF documents is grDevices::pdf() and for HTML documents it’s grDevices::png(). As we
demostrated, these are the worst possible choices!

PDFs and PNGs

If you want to save your graphs as PDFs, then simply set

knitr::opts_chunk$set(dev = "cairo_pdf")

at the top of Rmarkdown file. The PNG variant is slightly different as we need to specify the device dev and also pass the type argument to the device

knitr::opts_chunk$set(dev = "png", dev.args = list(type = "cairo-png"))

These options, i.e. dev = "cairo_pdf", can also be set at individual chunks.

The ragg Package

Setting the agg_png() function from the ragg package as the graphics device is somewhat more tricky as it doesn’t come pre-defined within knitr. The knitr docs states that

if none of the 20 built-in devices is appropriate, we can still provide yet another name as long as it is a legal function name which can record plots (it must be of the form function(filename, width, height))

The arguments of agg_png() are

#> $filename
#> [1] "Rplot%03d.png"
#> $width
#> [1] 480
#> $height
#> [1] 480

This suggests we can simply set ragg::agg_png() as the knitr dev, as it’s of the correct form. However, careful reading of the knitr source code highlights that the dpi argument isn’t passed to new devices and that the units should be inches. So after a “little” experimentation, we have

ragg_png = function(..., res = 192) {
  ragg::agg_png(..., res = res, units = "in")
knitr::opts_chunk$set(dev = "ragg_png", fig.ext = "png")

Remember the dpi argument isn’t passed to ragg_png(), so if you want to change the resolution per chunk, then you will need to use

dev.args = list(ragg_png = list(res = 192))

As ragg is being developed by RStudio, I’m guessing that at some point in the near future, ragg will become native to knitr.

Jumping Rivers are full service, RStudio certified partners. Part of our role is to offer support in RStudio Pro products. If you use any RStudio Pro products, feel free to contact us (). We may be able to offer free support.

1 thought on “Setting the Graphics Device in a RMarkdown Document”

Comments are closed.