【问题标题】:Force ggsave to vectorize point geoms in .wmf-files强制 ggsave 对 .wmf 文件中的点几何图形进行矢量化
【发布时间】:2020-02-24 17:14:54
【问题描述】:

使用 R 生成的图如果不能正确导出,则不能用于发布。我在 Windows 机器上工作,并使用 MS Word 2016 进行所有写作目的。所以,我希望将我的图导出为 .wmf 文件(我想 .emf 也可以)。

我用ggplot2 生成所有图表,所以 ggsave (device = "wmf") 似乎是一个不错的选择,我想。但是,我对生成的文件有一个主要问题:点几何似乎被打印为光栅而不是矢量格式。以下是生成简单散点图的示例:

library (ggplot2)    

plot_data <- data.frame (a = runif (1:20), 
                         b = seq (1:20))

x11 (width =  3, height = 3)

ggplot (data = plot_data, mapping = aes (x = a, y = b)) +
    geom_point () +
    labs (x = "my x-label", y = "my y-label") +
    theme (panel.background = element_blank(),
           panel.border = element_rect (fill = NA, size = 0.7),
           axis.ticks = element_line (color = "black", lineend = "round"),
           axis.ticks.length = unit (2, "mm"),
           axis.text = element_text (color = "black"),
           plot.margin = unit(rep (0, 4), "cm")
           )

我使用以下代码保存绘图:

ggsave(filename = "my_file.wmf", device = "wmf")

当我在 MS Word 或 Libre Office 中打开绘图时,我发现这些点根本没有以良好的质量呈现。在 Libre Office Draw 中,一个点看起来像这样(放大了很多):

在 MS Word 中,情节如下所示:

用这些“点”:

但是,标签和轴都可以。微软字:

Libre Office 抽奖:

我认为标签、刻度注释和轴(甚至点周围的圆圈)都以矢量格式存储,而点几何图形似乎存储为栅格。我担心,由此产生的地块不可用。所以,我想找到一个选项来强制ggsave () 向量化点几何而不是打印光栅。我非常希望有人能提供帮助 - 我迫切需要一种简单的方法来从 R 导出绘图以供发表,以说服我的实验室更多地依赖 R。

【问题讨论】:

  • 可能相关:github.com/ropensci/pdftools/issues/25grDevices::pdf.options(useDingbats=FALSE) 可能会有所帮助
  • 另一种可能不太令人满意的解决方法是更改​​点形状。正如您在放大图中看到的那样,geom_point 会同时绘制点和笔划 (shape 19)。笔划看起来没问题,所以你可以使用shape = 1。我认为更好的选择是如上所述更改 Dingbats 选项。我可能也不推荐 Windows 专有文件格式。我个人总是保存为pdf,然后使用 Adob​​e illustrator 将其导出到任何图像文件。这样,当我的论文不应该被接受并且我需要重新格式化为其他图像格式时,我也能保持灵活性。
  • 我会尝试 Dingbats 选项。我知道 Windows 专有文件格式并不理想。但是,我的目标是说服我的同事使用 R 进行绘图。为了做到这一点,我最好只使用 R 和 MS 词来展示一个工作流程。
  • Dingbats 是一个 .pdf - 选项,我想。保存 .wmf 文件时,我得到:Error in grDevices::win.metafile(...) : unused argument (useDingbats = FALSE)
  • 对我来说,使用 PDF 有另一个限制:我使用字体“ChantillyLH”,可以通过extrafont 包中的font_importloadfonts (device = "win") 注册。但是,loadfonts (device = "pdf") 给出了 ChantillyLH [More than one version of regular/bold/italic found for ChantillyLH. Skipping setup for this font.] 的错误。我无法解决这个问题;我真的尝试了几种方式。 ChantillyLH 似乎不是“标准”字体格式 - 具有“普通”、“斜体”、“粗体”和“粗体”样式的字体格式。不幸的是......

标签: r ggplot2 plot export wmf


【解决方案1】:

您可以使用附加 CRAN 包 devEMF 在 R 中直接创建完全矢量化的 EMF(或 EMF+)文件。这避免了任何需要导出到 SVG 并随后转换为 EMF 的需要。我不确定为什么 ggsave(..., device="wmf") 调用(它使用窗口 API 生成文件)在这里使用光栅绘图符号,但 devEMF 中的函数肯定使用矢量(我说这既是 devEMF 的开发人员,也由使用 LibreOffice 放大)。

安装 devEMF 后,您可以运行原始问题中的示例代码,然后:

library(devEMF)
ggsave(filename = "my_file.emf", device = emf)

注意:上面代码中使用的emf(不带引号)是devEMF定义的函数的名称(类似于原始问题中使用的x11)。 "emf"(带引号)将被 ggsave 解释为对使用 windows API 的请求。您希望前者不带引号,而不是后者带引号。

或者,可以替换原来对x11的调用,直接生成emf文件而不需要ggsave

library (ggplot2)
library (devEMF)

plot_data <- data.frame (a = runif (1:20), 
                         b = seq (1:20))

emf (file = "my_file.emf", width =  3, height = 3)

ggplot (data = plot_data, mapping = aes (x = a, y = b)) +
    geom_point () +
    labs (x = "my x-label", y = "my y-label") +
    theme (panel.background = element_blank(),
           panel.border = element_rect (fill = NA, size = 0.7),
           axis.ticks = element_line (color = "black", lineend = "round"),
           axis.ticks.length = unit (2, "mm"),
           axis.text = element_text (color = "black"),
           plot.margin = unit(rep (0, 4), "cm")
           )

dev.off() #must close device to close file!

根据我的经验,MS Office 对 EMF 和 EMF+ 的支持与 WMF 一样完整,因此生成 EMF 是此用例的合理解决方案。如果遇到兼容性问题,请查看 emf 函数的 emfPlus* 参数(请参阅 help("emf", package="devEMF"))。

【讨论】:

  • 感谢您提供这个非常简洁的解决方案。但是,出于我的目的,我有一个无法通过这种方式解决的问题。我需要嵌入字体,但“EMF/EMF+ 不允许嵌入字体。因此,您必须小心,您在创建 emf 文件时使用的系统(即运行 R)和在用于导入/查看结果文件的系统上。坚持使用标准的 Adob​​e PostScript 字体系列可能是个好主意。”保存为 .svg 然后转换为 .emf 是迄今为止我发现的唯一解决方法...
  • 哦,有趣——CairoSVG 似乎将字体字形转换为曲线。我可以假设在 devEMF 中实现类似的程序;如果我最终这样做了,我会在这里发帖。
  • 完美。我不知道这是多少工作。但是,我想更多的人会遇到和我一样的问题。因此,我想,非常感谢 devEMF 的更新。无论如何,如果您有时间,我期待您的解决方案。
  • devEMF 4.0 版(现在在 CRAN 上)有一个选项“emfPlusFontToPath”,可以将字体转换为曲线(路径)。从技术上讲,这不是字体嵌入(下游程序无法访问字体字形以进行进一步的文本编辑),但它确保了生成的 EMF+ 文件是可移植的。请注意,此选项目前仅适用于 Linux 和 Windows(不是 Apple)。
  • 哇,我认为这是一个重大改进。谢谢!
【解决方案2】:

我没有找到使 WMF 设备正常运行的方法,但您可以保存为 SVG,然后使用 R 通过 Inkscape(您需要单独下载的免费软件)自动从 SVG 转换为 EMF,如下所示:

inkscape_path <-'C:/Program Files/Inkscape/inkscape.exe'
if(!file.exists(inkscape_path)) {
  warning("Could not find inkscape, will not convert to .emf")
} else {
   input_file <- "plot.svg"
   output_file <- "plot.emf"
   system(paste0('"', inkscape_path,'"', ' --file "', input_file, '" --export-emf "', output_file, '"'))
}

(Inkscape 不支持从命令行导出到 WMF,但为了导入 int Office,WMF 和 EMF 应该可以互换)

编辑:很遗憾,您无法从命令行访问某些导出设置(尤其是“将文本转换为路径”选项)。但是,命令行将使用您上次用于导出 WMF 的设置,因此您可以使用所需的设置手动保存一次,然后自动进行进一步的转换。 (这是一个已知限制:https://bugs.launchpad.net/inkscape/+bug/1747696

【讨论】:

  • 直到我得到最新版本的 ms office,它被告知能够读取 .svg 文件,这可能是迄今为止最好的解决方案。我目前的解决方法是在inkscape中手动打开.svg文件并将它们保存为.emf,因此一些用于自动化的R操作似乎是这种方法的一个非常受欢迎的增强......
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-05-11
  • 1970-01-01
  • 1970-01-01
  • 2022-08-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多