使用嵌入在r中的字体将ggplot图保存为PDF

时间:2017-09-01 21:43:02

标签: r ggplot2 fonts export-to-pdf

我一直在关注我在网上找到的将ggplot图保存为PDF的建议,但我无法让它工作。我正在使用extrafont包在Calibri中生成带有文本的图表,但我的图表打印出来没有文字。我不知道我错过了什么。我在这个过程中找不到任何错误。希望其他人可以提供帮助。

以下是我使用的代码和流程:

library(extrafont)
font_import(pattern="[C/c]alibri")
loadfonts(device="win")

我此时安装了GhostScript。然后运行以下命令设置GhostScript位置。

Sys.setenv(R_GSCMD = "C:\\Program Files\\gs\\gs9.21\\bin\\gswin64c.exe")

然后我使用名为“chart”的ggplot生成了一个图表。该图表在RStudio中看起来很完美,但不是PDF格式。

ggsave("chart.pdf", plot = chart, width = 6, height = 4)

在这里,我收到警告,显示这样的内容:

  

在grid.Call中(C_textBounds,as.graphicsAnnot(x $ label),...:在PostScript字体数据库中找不到字体系列'Calibri'

显然,这些警告应该发生?然后我跑......

embed_fonts("chart.pdf", outfile="chart_embed.pdf")

不幸的是,在所有这些之后,最终的“嵌入”图表看起来与生成的原始图表没有什么不同,它们都没有任何文本。

如果有帮助,这里是生成图表的代码:

a <- ggplot(data=stats, aes(x=Date))
Chart <- a + geom_point(aes(y=NevadaTotalNonfarmAllEmployees)) + 
      xlab("Date") + 
      ylab("Nonfarm Jobs") + 
      ggtitle("Nevada Total Jobs") + 
      theme(axis.title.x = element_text(size=15, family = "Calibri"),
            axis.title.y = element_text(size=15, family = "Calibri"),
            axis.text.x = element_text(size=10, family = "Calibri"),
            axis.text.y = element_text(size=10, family = "Calibri"),
            plot.title = element_text(hjust=0.5, size=20, family = "Calibri"))

我一直在试着想出这个问题。或许它不是代码而是其他东西?无论哪种方式,谢谢你的帮助。

3 个答案:

答案 0 :(得分:6)

这里有几个问题:(1)将字体加载到R和(2)使用PDF编写库,该库可以与自定义嵌入字体一起正常工作。

首先,正如其他人所提到的,在Windows上你通常需要运行extrafont::font_import()来用R注册你的许多系统字体,但它可能需要一段时间而且可能会错过TTF和其他类型的字体。解决此问题的一种方法是使用windowsFonts(name_of_font_inside_r = windowsFont("Name of actual font"))在不加载完整数据库的情况下将字体加载到R中,如下所示:

windowsFonts(Calibri = windowsFont("Calibri"))

这使得R中只能访问一种字体。您可以使用windowsFonts()进行检查。每次运行脚本时都必须运行此行 - 字体加载不会跨会话持续存在。加载字体后,您可以正常使用它:

library(tidyverse)
df <- data_frame(x = 1:10, y = 2:11)

p <- ggplot(df, aes(x = x, y = y)) +
  geom_point() +
  labs(title = "Yay Calibri") +
  theme_light(base_family = "Calibri")
p

Calibrified

第二,R和Windows上的内置PDF编写设备都不能很好地处理字体嵌入。但是,R现在包含了Cairo图形库,它可以很好地嵌入字体。您可以在ggsave()中指定Cairo设备来使用它,这比处理GhostScript更容易:

ggsave(p, filename = "whatever.pdf", device = cairo_pdf, 
       width = 4, height = 3, units = "in")

答案 1 :(得分:1)

我发现使用pdfFonts(和/或postscriptFonts)明确注册字体更安全。

该文档包含一个示例,但也请查看我的fonts module。有了这个,注册新字体就像写

一样简单
fonts$register_font('Calibri')

在内部,这会使用Type1Font创建字体规范,确保正确设置名称,并调用pdfFonts

它还确保存在完整的字体指标集(使用extrafont::ttf_import完成)。

这种方法比使用font_import生成所有字体的字体指标要快得多,它可以让您获得更多控制权。

答案 2 :(得分:0)

我认为您错过了初始化步骤font_import()。预先警告,执行此命令可能需要更长的时间。

首先,您可以使用命令windowsFonts()查看可用的字体。我的绘图设备中的当前字体是;

$serif
[1] "TT Times New Roman"

$sans
[1] "TT Arial"

$mono
[1] "TT Courier New"

此后,您可以导入extrafont库和loadfonts(device = "win")。我还建议在R控制台中执行这些命令,而不是在RStudio中执行。我建议这样做,因为当你在RStudio中使用font_import()导入字体时,它可能不会显示y/n提示符。

下面我提供了一个可重复的最小例子;

    library(ggplot2)
    library(extrafont)
    font_import()
    # tell where ghostscript is located. This is required for saving the font in pdf
    Sys.setenv(R_GSCMD = "C:\\Program Files\\gs\\gs9.21\\bin\\gswin64c.exe") # I have installed 64-bit version of GhostScript. This is why I've used gswin64c.exe. If you have installed 32-bit version of GhostScript, use gswin32c.exe. Failure to specify the correct installed GhostScript will yield error message, "GhostScript not found"
    # create a plot object
p <- ggplot(mtcars, aes(x=wt, y=mpg)) + 
  geom_point()+
  ggtitle("Fuel Efficiency of 32 Cars")+
  xlab("Weight (x1000 lb)") + ylab("Miles per Gallon") +
  theme_bw()+
  theme(text=element_text(family="ArialMT", size=14))
# show the plot
print(p)

plot

# save the plot as pdf  
ggsave("figures//ggplot_arialmt.pdf", p, width=20, height=20, 
   device = "pdf", units = "cm")

注意

它只有ArialMT字体似乎与ggsave()一起使用。见SO post。使用任何其他字体保存为pdf,使用另一个字符顶部呈现图形。对于ggsave,这也是open issue,自2013年以来一直没有得到答复。