ggplot2 PDF输出中的Unicode字符

时间:2012-10-07 10:55:24

标签: r unicode utf-8 ggplot2

如何在使用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

在搜索此问题的解决方案时,我发现一些evidence R使用单字节编码进行多字节编码,例如UTF-8用于PDF或postscript输出。我还发现了一些建议,例如,能够获得Euro sign working,但没有一般解决方案。

3 个答案:

答案 0 :(得分:19)

正如Ben所说,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 graph with custom font family and non-ASCII characters in the title

另见this question;虽然它与标题看起来并不直接相关,但有很多关于让字体在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()

答案 1 :(得分:2)

如果您使用的是ggsave(...),则可以致电ggsave(..., device=cairo_pdf)

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

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

这是full example(不是我的作品)。

答案 2 :(得分:1)

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

TL; DR

如果您必须拥有西里尔字母,则只需回到出色的png驱动程序即可。 (然后亲吻您的抗锯齿图再见。)

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

What is old, is new again.

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

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

失败画廊

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

预备步骤:

  1. install the latest 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

Fail Gallery: vanilla config

单独使用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

Fail Gallery: using cairo_pdf() alone

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

This is as close as it gets to working with “modern” approaches.

又一次尝试了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

Fail Gallery: using cairo_pdf() with family = "MS Comic Sans"

还有更多...

使用较旧的“黑暗与暴风雨之夜”版本(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

enter image description here

并使用@drammock建议的DejaVu Sans

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

enter image description here

旧版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

enter image description here