knitr генерирует ошибки в документе, но генерирует цифры правильно независимо - PullRequest
4 голосов
/ 09 марта 2019

Я вяжу файл R Markdown в macOS и использую knitr::opts_chunk$set(dev = c("png", "cairo_pdf")) для сохранения вывода графиков в формате PNG и PDF одновременно. Я также использую библиотеку Cairo PDF, так как она может корректно встраивать шрифты по умолчанию (см. здесь )

Когда я вяжу и создаю график, в котором используется собственный шрифт, knitr правильно сохраняет файлы PNG и PDF с помощью Cairo:

figure output

Однако в фактическом связанном документе R Markdown R жалуется на отсутствующие шрифты и выдает десятки предупреждений. Это странно, так как работает за кадром просто отлично.

Вот 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")
```

Сами рисунки сохранены правильно, но вывод HTML полон этих предупреждений:

## 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

Сейчас мое решение состоит в том, чтобы добавить warning=FALSE к параметрам чанка для warningful-plot и всем другим чанкам, которые генерируют графики с пользовательскими шрифтами. Я хотел бы знать, почему эти дополнительные предупреждения происходят, и есть ли способ избежать получения предупреждений.

1 Ответ

4 голосов
/ 09 марта 2019

Отвечая на мой собственный вопрос здесь ...

Согласно паре проблем на GitHub (на knitr и hrbrthemes ), это происходит потому, что knitr незримо использует нулевой PDFустройство (pdf(NULL)) в фоновом режиме при собственно вязании.Однако графическое устройство pdf() по умолчанию в R не может обрабатывать пользовательские шрифты, отсюда и предупреждения.Даже если ни одна из видимых графических изображений никогда не проходит через базовое устройство pdf(), они все равно проходят через него незаметно.

При вязании с использованием dev = 'png', knitr будет использовать невидимое устройство png(), и нетпредупреждения будут выброшены.Кажется, что использование устройства cairo_pdf в то же время нарушает это и вынуждает knitr возвращаться к невидимому, нестандартному pdf() устройству без шрифтов.

Мы можем это исправить, заставив knitr использоватьвместо этого - невидимое устройство png(), на основе этого комментария здесь :

# 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")))

Это заклинание options(device = ...) делает предупреждения исчезнуть.

...