R PDF 格式保存报错

记录一个R图像存储的问题,在通过R-studio生成图像时,以pdf格式存储会出现如下错误提示:
Error in grid.Call.graphics(C_text, as.graphicsAnnot(x$label), x$x, x$y, : invalid font type
同时的warning更加描述直接:

Warning messages: 
1: In grid.Call(C_textBounds, as.graphicsAnnot(x$label), ... : font family 'Arial' not found in PostScript font database   
2: In grid.Call(C_textBounds, as.graphicsAnnot(x$label), ... : font family 'Arial' not found in PostScript font database
...

无论是ggplot2还是原生graphics都遇到过类似的情况。
特征是直接在页面绘制,包括以png/tiff/jpg等格式存储都是没问题的,就是在pdf存储时包括。
最荒谬的是,有的时候没有问题,偶尔出现一次,非常恶心。

问题来源

核心就是warning里面提示的,(部分)特殊字体/字符不支持的问题,或者说不兼容(其实逻辑很奇怪,PDF/R/系统,分别各自都支持该字体,组合在一起,就会有bug,底层逻辑我还没太搞明白)。
但是其实本质上无论是R还是系统本身,肯定是支持相关字体的,不然是什么方式都可视化不出来,尤其是像我这里的arial,是广泛使用的无衬字体。

问题解决

任意选其中一个就可以解决,具体情况具体尝试

1. 修改字体

直接修改pdf基本都支持的字体就行了,推荐使用万金油字体Helvetica(也是sans),无衬字体,期刊都接受。
graphics系别的图像(包括常见的ComplexHeatmap, UpsetR等)通过par()来修改字体就行了

par(family = "Helvetica")
pdf();plot;dev.off()
par(family="") # 取消字体指定 恢复系统默认字体

ggplot2系列会更加简单,因为它有theme参数可以直接指定想要的字体

p + theme(text = element_text(family = "Helvetica"))   # 单图即时生效

theme_bw(base_family = "Helvetica") # 全局临时生效

2. 修改输出模式

不采用pdf输出,从本质上解决问题,当然,许多时候我们就是必须要矢量图结构的图片,所以还是得pdf格式。
所有的chatbot都推荐通过cairo_pdf(),不过我个人测试是没有解决问题。包括ggsave()的方式也是一样的,不改变问题。
大家可以自己测试一下,能不能解决。

3. 注册并使用自定义字体

我个人经验就是上面那些方法有时候没有,尤其是par()修改字体,就是一个笑话,ggplot2::theme()倒是好用。
不兼容的核心就是R没有这些字体,那我加进去就行了。
首先查看系统可用字体,一般这里就可以发现,里面没有想要的字体。

# 基础方法
names(pdfFonts())    # PDF 设备可用字体
names(postscriptFonts())  # PS 设备可用字体

然后我们手动把系统库里面的字体,手动注册到R兼容的环境就行了,推荐用 extrafont(最常用)

install.packages("extrafont")
library(extrafont)

# 第一次使用需要导入系统字体(只需运行一次,较慢)
font_import()

# 加载字体
loadfonts()

# 验证 Arial 是否进来了
"Arial" %in% fonts()

# 现在就可以用了
names(pdfFonts())  # 应该能看到 Arial 了

现在PDF就可以成功保存了。

但是这个办法仍然不是最终解决这个问题,仍然有问题
产出的pdf图中的字体看起来像 Serif(衬线体),有点像 Times New Roman 或 Computer Modern,而 我RStudio 预览窗口默认用的是无衬线字体(类 Helvetica/Arial),后者才是我想要的。
Claude给的推测原因 -- PDF 设备和屏幕设备用的字体系统不同:
设备默认字体RStudio 预览(屏幕)Helvetica / Arial(无衬线)pdf() 设备Helvetica 理论上也是,但实际回退到 Type1 字体,看起来像衬线体cairo_pdf() 设备跟随系统字体
你图里那个字体很可能是 PDF 设备找不到 Helvetica 时自动回退到了 Times 或类似的 Type1 字体
不过问题不大了,反正我只需要图像是矢量的,字体格式我可以Adobe改。

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容