Reputation: 38709
I'm knitting an R Markdown file on macOS and I'm using knitr::opts_chunk$set(dev = c("png", "cairo_pdf"))
to save the output of plots as PNG and PDF files simultaneously. I'm also using the Cairo PDF library since it can embed fonts correctly by default (see here)
When I knit and create a plot that uses a custom font, knitr correctly saves both the PNG and PDF files using Cairo:
However, in the actual knitted R Markdown document, R complains about missing fonts and provides dozens of warnings. This is odd, since it is working just fine behind the scenes.
Here's a MWE:
---
title: "So many warnings?"
---
```{r setup, include=FALSE}
knitr::opts_chunk$set(fig.path = "fig/", # Save images to a subdirectory
echo = FALSE, # Hide code for now
dpi = 300, # High resolution PNGs
# Save all figures as Cairo PDFs and PNGs
dev = c("png", "cairo_pdf"),
dev.args = list(png = list(type = "cairo")))
```
```{r load-libraries}
library(ggplot2)
```
```{r warningless-plot}
# This will save two files in the fig/ folder, both saved using Cairo:
# - fig/warningless-plot-1.png
# - fig/warningless-plot-1.pdf
ggplot(mtcars, aes(x = wt, y = mpg)) +
geom_point()
```
```{r warningful-plot}
# This will save two files in the fig/ folder, both saved *correctly* using Cairo:
# - fig/warningful-plot-1.png
# - fig/warningful-plot-1.pdf
# However, rmarkdown or knitr or something in the pipeline gets mad and throws
# a ton of warnings.
ggplot(mtcars, aes(x = wt, y = mpg)) +
geom_point() +
theme_grey(base_family = "Comic Sans MS")
```
The figures themselves are saved correctly, but the HTML output is full of these warnings:
## Warning in grid.Call(C_textBounds, as.graphicsAnnot(x$label), x$x, x$y, :
## font family 'Comic Sans MS' not found in PostScript font database
## Warning in grid.Call(C_textBounds, as.graphicsAnnot(x$label), x$x, x$y, :
## font family 'Comic Sans MS' not found in PostScript font database
Right now my solution is to add warning=FALSE
to the chunk options for warningful-plot
and all other chunks that generate plots with custom fonts. I'd like to know why these extra warnings are happening, though, and if there's a way to avoid getting warnings in the first place.
Upvotes: 5
Views: 593
Reputation: 38709
Answering my own question here…
According to a couple issues on GitHub (at knitr and hrbrthemes), this happens because knitr invisibly uses a null PDF device (pdf(NULL)
) in the background when actually knitting. The default pdf()
graphics device in R can't handle custom fonts, though, hence the warnings. Even though none of the visible graphics ever go through the base pdf()
device, they still go through it invisibly I guess.
When knitting using dev = 'png'
, knitr will use an invisible png()
device and no warnings will be thrown. It seems that using a cairo_pdf
device at the same time breaks this and forces knitr to go back to an invisible, custom-font-less pdf()
device.
We can fix this by forcing knitr to use an invisible png()
device instead, based on this comment here:
# Use invisible NULL png() device
options(device = function(file, width, height) {
png(tempfile(), width = width, height = height)
})
# knit options, including `dev = c("png", "cairo_pdf")`
knitr::opts_chunk$set(fig.path = "fig/", # Save images to a subdirectory
echo = FALSE, # Hide code for now
dpi = 300, # High resolution PNGs
# Save all figures as Cairo PDFs and PNGs
dev = c("png", "cairo_pdf"),
dev.args = list(png = list(type = "cairo")))
That options(device = ...)
incantation makes the warnings go away.
Upvotes: 5