【问题标题】:How to use Cairo PNGs in R Markdown如何在 R Markdown 中使用 Cairo PNG
【发布时间】:2019-03-05 18:27:23
【问题描述】:

使用 Cairo 保存 R 图形有很多优点 (see here, for example)。例如,在保存 PDF 时,cairo_pdf 设备会正确嵌入自定义字体。

cairo_pdf 图形设备的使用很容易,基于 ggplot 的图形与 ggsave():

library(ggplot2)

ugly_plot <- ggplot(mtcars, aes(x = wt, y = mpg)) +
  geom_point() +
  labs(title = "Some data about cars") +
  theme_gray(base_family = "Papyrus")
ugly_plot

ggsave(ugly_plot, filename = "ugly_plot.pdf", 
       width = 4, height = 2.5, device = cairo_pdf)

在 R Markdown 中通过 knitr 使用 cairo_pdf 设备也很容易——将 dev: cairo_pdf 添加到 YAML 前端:

---
title: "Cairo stuff"
output:
  pdf_document:
    dev: cairo_pdf
---

```{r make-ugly-plot, fig.width=4, fig.height=2.5}
library(ggplot2)

ugly_plot <- ggplot(mtcars, aes(x = wt, y = mpg)) +
  geom_point() +
  labs(title = "Some data about cars") +
  theme_gray(base_family = "Papyrus")
ugly_plot
```

使用基于开罗的 PNG 也有优势,因为 Cairo correctly deals with DPI。如果将正常保存的高 DPI 的 PNG 放入 Word 或 PowerPoint 文件中,则图形的尺寸会被夸大且不准确。如果将具有相同高 DPI 的基于开罗的 PNG 放入 Word 中,则尺寸正确:

使用ggsave() 很容易将 ggplot 输出保存为高分辨率 Cairo PNG,但语法与保存为 Cairo PDF 略有不同。我们不指定设备,而是指定类型:

ggsave(ugly_plot, filename = "ugly_plot.png", 
       width = 4, height = 2.5, dpi = 300, type = "cairo")

将该文件放在 Word 或 PowerPoint 中效果很好,并且所有内容的大小都在高分辨率下正确。

当编织成 HTML 或 Word 时,这种对尺寸的误解会延续到 R Markdown 中。在编织时让 knitr 使用 type = "cairo" 会很棒,但是在 R Markdown 中复制这个 dpi = 300, type = "cairo" 会更加困难。 Cairo 库包括像Cairo::CairoPNG() 这样的设备,但ggsave(..., type = "cairo") 不使用这个设备。它使用 R 的标准 PNG 设备,但开启了对 Cairo 的支持。

dpi=300 添加到块选项中很容易使图形高分辨率,但我无法让knitr 使用启用type = cairo 的内置PNG 设备。我尝试天真地将type: cairo 添加到 YAML 元数据中,但毫无疑问它不起作用。 knitr 生成的 PNG 不使用 Cairo,并且比预期的要大得多(并且在 HTML 和 Word 文档中是巨大的)。

---
title: "Cairo stuff"
output:
  html_document: 
    self_contained: no  # to see resulting figure as a file
    dev: png
    type: cairo  # this doesn't do anything
---

```{r make-ugly-plot, fig.width=5, fig.height=3.5, dpi=300}
library(ggplot2)

ugly_plot <- ggplot(mtcars, aes(x = wt, y = mpg)) +
  geom_point() +
  labs(title = "Some data about cars") +
  theme_gray(base_family = "Papyrus")
ugly_plot
```

总之,我正在寻找一种方法来使用您从 knitr 中的 ggsave(..., filename = "blah.png", dpi = 300, type = "cairo") 获得的相同输出。有没有办法做到这一点?

---
title: "Something"
output:
  pdf_document:
    dev: cairo_pdf  # yay Cairo output
  html_document:  # What needs to go here?
    dev: png
    type: cairo
---

【问题讨论】:

  • 这可能是由于与 dev.args 而不仅仅是 dev ,如下面我的回答??

标签: r ggplot2 r-markdown knitr cairo


【解决方案1】:

使用 knitr 选项,而不是 YAML 标头。

您可以使用knitr选项更改特定设备的类型(易会推荐):

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

或者,您可以根据输出有条件地执行此操作:

if (!knitr::is_latex_output()) {
  knitr::opts_chunk$set(dpi = 300, dev.args = list(type = "cairo"))
})

我现在已经在几个文档中使用了它。 注意:我只将它用于从 R 命令行执行 rmarkdown::render(...) 的文档。

【讨论】:

  • 啊!好决定!我不知道dev.args 列表的事情!
  • 是的,它真的很有用。我不知道这是否/如何转换为 yaml 标头中的选项
  • 我推荐使用dev.args = list(png = list(type = "cairo")),即仅将type = "cairo"应用于png设备,而不影响其他图形设备。
  • 是的,你可以:)
  • 我不记得最近在 knitr 中有任何与图形设备相关的更改。请注意type = "cairo" 实际上是png() 如果capabilities('cairo') == TRUE 的默认值,所以我真的很惊讶这个选项有帮助...
【解决方案2】:

作为@rmflight's answer 在每个文件顶部使用一段代码的替代方案,这可以在shell 包装器或Makefile 中实现,后者使用rmarkdown::render() 的可选参数编​​织Rmarkdown 文件:

R -e 'rmarkdown::render("foo.Rmd", "pdf_document", output_file="foo.pdf", runtime = "static", output_options = list(dpi = 300, dev.args = list(type = "cairo")))'

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-16
    • 2018-05-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多