ggplot2 PDF输出中的Unicode字符

ste*_*fan 24 unicode r utf-8 ggplot2

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

请考虑以下示例:

library(ggplot2)
qplot(Sepal.Length, Petal.Length, data=iris, main="A?????????????????s????x??")
ggsave("t.pdf")
Run Code Online (Sandbox Code Playgroud)

图表的标题使用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
Run Code Online (Sandbox Code Playgroud)

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

dra*_*ock 22

正如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()
Run Code Online (Sandbox Code Playgroud)

...给出一个如下所示的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()
Run Code Online (Sandbox Code Playgroud)

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

以下评论中有关DLL文件的说明是我必须要做的,以便在Windows上使用Cairo()CairoPDF()命令library(Cairo).然后:

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()
Run Code Online (Sandbox Code Playgroud)


Dom*_*omQ 9

截至 2020 年和 R 版本 4.0.3,在 Mac OS X 上不再cairo_pdf()您的朋友,至少就西里尔字母而言 \xe2\x80\x94\xc2\xa0请参阅下面的失败图库。

\n

长话短说

\n

如果您必须使用西里尔字母,请返回良好的 olepng驱动程序。(和你的抗锯齿图表吻别吧。)

\n
R -e \'png(filename = "ftw.png"); library(ggplot2); qplot(Sepal.Length, Petal.Length, data=iris, main="A\xca\x99\xe1\xb4\x84\xe1\xb4\x85\xe1\xb4\x87\xd2\x93\xc9\xa2\xca\x9c\xc9\xaa\xe1\xb4\x8a\xe1\xb4\x8b\xca\x9f\xe1\xb4\x8d\xc9\xb4\xe1\xb4\x8f\xe1\xb4\x98\xc7\xab\xca\x80s\xe1\xb4\x9b\xe1\xb4\x9c\xe1\xb4\xa0\xe1\xb4\xa1x\xca\x8f\xe1\xb4\xa2"); dev.off()\'\nopen ftw.png\n
Run Code Online (Sandbox Code Playgroud)\n

旧的又是新的。

\n

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

\n
R -e \'rmarkdown::render("foo.Rmd", "pdf_document", output_file="foo.pdf", runtime = "static", output_options = list(dev = "png"))\'\n
Run Code Online (Sandbox Code Playgroud)\n

失败画廊

\n

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

\n

准备步骤:

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

普通配置

\n
R -e \'library(ggplot2); qplot(Sepal.Length, Petal.Length, data=iris, main="A\xca\x99\xe1\xb4\x84\xe1\xb4\x85\xe1\xb4\x87\xd2\x93\xc9\xa2\xca\x9c\xc9\xaa\xe1\xb4\x8a\xe1\xb4\x8b\xca\x9f\xe1\xb4\x8d\xc9\xb4\xe1\xb4\x8f\xe1\xb4\x98\xc7\xab\xca\x80s\xe1\xb4\x9b\xe1\xb4\x9c\xe1\xb4\xa0\xe1\xb4\xa1x\xca\x8f\xe1\xb4\xa2"); ggsave("fail1.pdf")\'\nopen fail1.pdf\n
Run Code Online (Sandbox Code Playgroud)\n

失败画廊:普通配置

\n

cairo_pdf()单独使用

\n
R -e \'cairo_pdf("fail2.pdf"); library(ggplot2); qplot(Sepal.Length, Petal.Length, data=iris, main="A\xca\x99\xe1\xb4\x84\xe1\xb4\x85\xe1\xb4\x87\xd2\x93\xc9\xa2\xca\x9c\xc9\xaa\xe1\xb4\x8a\xe1\xb4\x8b\xca\x9f\xe1\xb4\x8d\xc9\xb4\xe1\xb4\x8f\xe1\xb4\x98\xc7\xab\xca\x80s\xe1\xb4\x9b\xe1\xb4\x9c\xe1\xb4\xa0\xe1\xb4\xa1x\xca\x8f\xe1\xb4\xa2"); dev.off()\'\nopen fail2.pdf\n
Run Code Online (Sandbox Code Playgroud)\n

失败画廊:单独使用 cairo_pdf()

\n

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

\n
R -e \'cairo_pdf("fail3.pdf", family = "Arial Unicode MS"); library(ggplot2); qplot(Sepal.Length, Petal.Length, data=iris, main="A\xca\x99\xe1\xb4\x84\xe1\xb4\x85\xe1\xb4\x87\xd2\x93\xc9\xa2\xca\x9c\xc9\xaa\xe1\xb4\x8a\xe1\xb4\x8b\xca\x9f\xe1\xb4\x8d\xc9\xb4\xe1\xb4\x8f\xe1\xb4\x98\xc7\xab\xca\x80s\xe1\xb4\x9b\xe1\xb4\x9c\xe1\xb4\xa0\xe1\xb4\xa1x\xca\x8f\xe1\xb4\xa2"); dev.off()\'\nopen fail3.pdf\n
Run Code Online (Sandbox Code Playgroud)\n

这与使用 \xe2\x80\x9cmodern\xe2\x80\x9d 方法非常接近。

\n

另一种使用 Comic Sans 的尝试是为了更好地衡量:

\n
R -e \'cairo_pdf("fail3bis.pdf", family = "Comic Sans MS"); library(ggplot2); qplot(Sepal.Length, Petal.Length, data=iris, main="A\xca\x99\xe1\xb4\x84\xe1\xb4\x85\xe1\xb4\x87\xd2\x93\xc9\xa2\xca\x9c\xc9\xaa\xe1\xb4\x8a\xe1\xb4\x8b\xca\x9f\xe1\xb4\x8d\xc9\xb4\xe1\xb4\x8f\xe1\xb4\x98\xc7\xab\xca\x80s\xe1\xb4\x9b\xe1\xb4\x9c\xe1\xb4\xa0\xe1\xb4\xa1x\xca\x8f\xe1\xb4\xa2"); dev.off()\'\nopen fail3bis.pdf\n
Run Code Online (Sandbox Code Playgroud)\n

失败画廊:使用 cairo_pdf() 和 family =“MS Comic Sans”

\n

还有几个...

\n

对于较旧的“黑暗暴风雨之夜”版本(3.6.2):

\n
/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\xca\x99\xe1\xb4\x84\xe1\xb4\x85\xe1\xb4\x87\xd2\x93\xc9\xa2\xca\x9c\xc9\xaa\xe1\xb4\x8a\xe1\xb4\x8b\xca\x9f\xe1\xb4\x8d\xc9\xb4\xe1\xb4\x8f\xe1\xb4\x98\xc7\xab\xca\x80s\xe1\xb4\x9b\xe1\xb4\x9c\xe1\xb4\xa0\xe1\xb4\xa1x\xca\x8f\xe1\xb4\xa2"); dev.off()\'\nopen fail4.pdf\n
Run Code Online (Sandbox Code Playgroud)\n

在此输入图像描述

\n

DejaVu Sans按照@drammock的建议:

\n
R -e \'cairo_pdf("fail5.pdf", family = "DejaVu Sans"); library(ggplot2); qplot(Sepal.Length, Petal.Length, data=iris, main="A\xca\x99\xe1\xb4\x84\xe1\xb4\x85\xe1\xb4\x87\xd2\x93\xc9\xa2\xca\x9c\xc9\xaa\xe1\xb4\x8a\xe1\xb4\x8b\xca\x9f\xe1\xb4\x8d\xc9\xb4\xe1\xb4\x8f\xe1\xb4\x98\xc7\xab\xca\x80s\xe1\xb4\x9b\xe1\xb4\x9c\xe1\xb4\xa0\xe1\xb4\xa1x\xca\x8f\xe1\xb4\xa2"); dev.off()\'\nopen fail5.pdf\n
Run Code Online (Sandbox Code Playgroud)\n

在此输入图像描述

\n

老版 R 上的 DejaVu Sans:

\n
/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\xca\x99\xe1\xb4\x84\xe1\xb4\x85\xe1\xb4\x87\xd2\x93\xc9\xa2\xca\x9c\xc9\xaa\xe1\xb4\x8a\xe1\xb4\x8b\xca\x9f\xe1\xb4\x8d\xc9\xb4\xe1\xb4\x8f\xe1\xb4\x98\xc7\xab\xca\x80s\xe1\xb4\x9b\xe1\xb4\x9c\xe1\xb4\xa0\xe1\xb4\xa1x\xca\x8f\xe1\xb4\xa2"); dev.off()\'\nopen fail5bis.pdf\n
Run Code Online (Sandbox Code Playgroud)\n

在此输入图像描述

\n\n


归档时间:

查看次数:

9628 次

最近记录:

13 年,4 月 前