32

如何在使用 ggplot2 创建的 PDF 图中将 Unicode 字符用于标签、标题和类似内容?

考虑以下示例:

library(ggplot2)
qplot(Sepal.Length, Petal.Length, data=iris, main="Aʙᴄᴅᴇғɢʜɪᴊᴋʟᴍɴᴏᴘǫʀsᴛᴜᴠᴡxʏᴢ")
ggsave("t.pdf")

该图的标题使用 Unicode 字符(小型大写字母),在输出中显示为.... 该问题仅出现在 pdf 绘图中;如果我用 替换最后一行ggsave("t.png"),则输出如预期。

我究竟做错了什么?我拥有的 R 脚本采用 UTF-8 编码。一些系统信息:

R version 2.14.1 (2011-12-22)
Platform: x86_64-pc-linux-gnu (64-bit)

locale:
 [1] LC_CTYPE=en_US.UTF-8       LC_NUMERIC=C              
 [3] LC_TIME=en_US.UTF-8        LC_COLLATE=en_US.UTF-8    
 [5] LC_MONETARY=en_US.UTF-8    LC_MESSAGES=en_US.UTF-8   
 [7] LC_PAPER=C                 LC_NAME=C                 
 [9] LC_ADDRESS=C               LC_TELEPHONE=C            
[11] LC_MEASUREMENT=en_US.UTF-8 LC_IDENTIFICATION=C       

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base

在寻找这个问题的解决方案时,我发现一些证据表明 R 使用单字节编码进行多字节编码,例如用于 PDF 或 postscript 输出的 UTF-8。我还找到了一些建议,例如,能够使欧元符号正常工作,但没有通用解决方案。

4

3 回答 3

24

正如本建议的那样,cairo_pdf()是你的朋友。它还允许您通过family参数在 PDF 中嵌入非 postscript 字体(即 TTF/OTF)(如果您碰巧没有包含要使用的字形的任何 postscript 字体,则至关重要)。例如:

library(ggplot2)
cairo_pdf("example.pdf", family="DejaVu Sans")
qplot(Sepal.Length, Petal.Length, data=iris, main="Aʙᴄᴅᴇғɢʜɪᴊᴋʟᴍɴᴏᴘǫʀsᴛᴜᴠᴡxʏᴢ")
dev.off()

...给出如下所示的 PDF: ggplot2 图形,标题中有自定义字体系列和非 ASCII 字符

另见这个问题;虽然它看起来与标题没有直接关系,但其中有很多关于让字体在 R 中做你想做的事情。

编辑评论中的每个请求,这是特定于 Windows 的代码:

library(ggplot2)
windowsFonts(myCustomWindowsFontName=windowsFont("DejaVu Sans"))
cairo_pdf("example.pdf", family="myCustomWindowsFontName")
qplot(Sepal.Length, Petal.Length, data=iris, main="Aʙᴄᴅᴇғɢʜɪᴊᴋʟᴍɴᴏᴘǫʀsᴛᴜᴠᴡxʏᴢ")
dev.off()

要使用基本图形命令,首先使用命令cairo_pdf()定义字体系列就足够了windowsFonts(),如上所示。当然,请确保您使用系统上实际拥有的字体,并且该字体实际上具有您需要的所有字形。

下面评论中关于 DLL 文件的说明是我必须做的才能让Cairo()CairoPDF()命令在library(Cairo)Windows 上工作。然后:

library(ggplot2)
library(Cairo)
windowsFonts(myCustomWindowsFontName=windowsFont("DejaVu Sans"))
CairoPDF("example.pdf")
par(family="myCustomWindowsFontName")
qplot(Sepal.Length, Petal.Length, data=iris, main="Aʙᴄᴅᴇғɢʜɪᴊᴋʟᴍɴᴏᴘǫʀsᴛᴜᴠᴡxʏᴢ")
dev.off()
于 2012-10-08T03:53:06.130 回答
7

截至 2020 年和 R 版本 4.0.3,在 Mac OS X 上不再是你的朋友cairo_pdf()至少就西里尔文而言 - 请参阅下面的失败库。

TL;博士

如果您必须使用西里尔文,请回到好的 olepng驱动程序。(和你的抗锯齿图告别。)

R -e 'png(filename = "ftw.png"); library(ggplot2); qplot(Sepal.Length, Petal.Length, data=iris, main="Aʙᴄᴅᴇғɢʜɪᴊᴋʟᴍɴᴏᴘǫʀsᴛᴜᴠᴡxʏᴢ"); dev.off()'
open ftw.png

旧的,又是新的。

或者,如果您将Rmarkdown与 knitr 一起使用:

R -e 'rmarkdown::render("foo.Rmd", "pdf_document", output_file="foo.pdf", runtime = "static", output_options = list(dev = "png"))'

失败画廊

Cairo 的“现代”方法在 v4.0.3 中失败,如下所示。请注意,这不是(或不仅仅是)字体嵌入或渲染问题,因为从生成的 PDF 中选择和粘贴文本也会产生乱码输出。

准备步骤:

  1. 安装最新的 R(4.0.3 或更高版本,全部capabilities()显示TRUE
  2. R -e 'install.packages(c("Cairo", "ggplot2"), repos="https://cloud.r-project.org")'

香草配置

R -e 'library(ggplot2); qplot(Sepal.Length, Petal.Length, data=iris, main="Aʙᴄᴅᴇғɢʜɪᴊᴋʟᴍɴᴏᴘǫʀsᴛᴜᴠᴡxʏᴢ"); ggsave("fail1.pdf")'
open fail1.pdf

失败图库:原版配置

cairo_pdf()单独使用

R -e 'cairo_pdf("fail2.pdf"); library(ggplot2); qplot(Sepal.Length, Petal.Length, data=iris, main="Aʙᴄᴅᴇғɢʜɪᴊᴋʟᴍɴᴏᴘǫʀsᴛᴜᴠᴡxʏᴢ"); dev.off()'
open fail2.pdf

失败图库:单独使用 cairo_pdf()

使用cairo_pdf()自定义(可能符合 Unicode)字体

R -e 'cairo_pdf("fail3.pdf", family = "Arial Unicode MS"); library(ggplot2); qplot(Sepal.Length, Petal.Length, data=iris, main="Aʙᴄᴅᴇғɢʜɪᴊᴋʟᴍɴᴏᴘǫʀsᴛᴜᴠᴡxʏᴢ"); dev.off()'
open fail3.pdf

这与使用“现代”方法非常接近。

Comic Sans 的另一次尝试:

R -e 'cairo_pdf("fail3bis.pdf", family = "Comic Sans MS"); library(ggplot2); qplot(Sepal.Length, Petal.Length, data=iris, main="Aʙᴄᴅᴇғɢʜɪᴊᴋʟᴍɴᴏᴘǫʀsᴛᴜᴠᴡxʏᴢ"); dev.off()'
open fail3bis.pdf

失败图库:将 cairo_pdf() 与家人一起使用 =

还有几...

使用较旧的“黑暗和暴风雨之夜”版本(3.6.2):

/Library/Frameworks/R.framework/Versions/3.6/Resources/bin/R -e 'cairo_pdf("fail4.pdf", family = "Arial Unicode MS"); library(ggplot2); qplot(Sepal.Length, Petal.Length, data=iris, main="Aʙᴄᴅᴇғɢʜɪᴊᴋʟᴍɴᴏᴘǫʀsᴛᴜᴠᴡxʏᴢ"); dev.off()'
open fail4.pdf

在此处输入图像描述

DejaVu Sans正如@drammock 所建议的那样:

R -e 'cairo_pdf("fail5.pdf", family = "DejaVu Sans"); library(ggplot2); qplot(Sepal.Length, Petal.Length, data=iris, main="Aʙᴄᴅᴇғɢʜɪᴊᴋʟᴍɴᴏᴘǫʀsᴛᴜᴠᴡxʏᴢ"); dev.off()'
open fail5.pdf

在此处输入图像描述

旧 R 上的 DejaVu Sans:

/Library/Frameworks/R.framework/Versions/3.6/Resources/bin/R -e 'cairo_pdf("fail5bis.pdf", family = "DejaVu Sans"); library(ggplot2); qplot(Sepal.Length, Petal.Length, data=iris, main="Aʙᴄᴅᴇғɢʜɪᴊᴋʟᴍɴᴏᴘǫʀsᴛᴜᴠᴡxʏᴢ"); dev.off()'
open fail5bis.pdf

在此处输入图像描述

于 2020-10-21T20:36:56.097 回答
1

如果你正在使用ggsave(...),你可以打电话ggsave(..., device=cairo_pdf)

您需要先安装并加载 Cairo 绑定。

install.packages("Cairo")
library(Cairo)

这是一个完整的例子(不是我的工作)。

于 2020-03-02T12:57:02.830 回答