ggsave在交互模式下可以使用systemfonts包中的字体,但在RScript下不支持
我想把系统中的自定义字体(使用 systemfonts 库)应用到用 ggplot2 绘制的图上,并且希望在不触及R 控制台的情况下编辑程序。然而,ggsave 会在非交互式运行时导致程序失败。将程序稍作修改,改用 png 或 agg_png(输出相同)来替代 ggsave,似乎解决了问题,但我想知道为什么 ggsave 无法与 systemfonts 在RScript中配合使用,以及是否有什么办法可以解决。
下面是一个示例程序:
library(tidyverse)
library(ragg)
library(systemfonts)
options(warn = 1)
mydata = tribble(
~type, ~quantity,
"Widgets", 1024,
"Gizmos", 826,
"Doodads", 1701
)
mydata |> ggplot() +
geom_bar(
stat = "identity",
aes(x = type, y = quantity)
) +
labs(title = "Quantity of widgets, gizmos, and doodads") +
theme(plot.title = element_text(size = 15, family = "Basteleur"))
ggsave("graph.png", width = 10, height = 7, units = "in")
如果我把整个程序复制并粘贴到一个新的R 会话中,它按预期运行,并生成一个 graph.png 文件,其外观如下:

如果我尝试用 RScript 运行这个程序,甚至 R --no-save < program.r,我得到如下警告和错误。
Warning in grid.Call(C_stringMetric, as.graphicsAnnot(x$label)) :
font family 'Basteleur' not found in PostScript font database
Warning in grid.Call(C_stringMetric, as.graphicsAnnot(x$label)) :
font family 'Basteleur' not found in PostScript font database
Warning in grid.Call(C_stringMetric, as.graphicsAnnot(x$label)) :
font family 'Basteleur' not found in PostScript font database
Warning in grid.Call(C_stringMetric, as.graphicsAnnot(x$label)) :
font family 'Basteleur' not found in PostScript font database
Warning in grid.Call(C_stringMetric, as.graphicsAnnot(x$label)) :
font family 'Basteleur' not found in PostScript font database
Warning in grid.Call(C_stringMetric, as.graphicsAnnot(x$label)) :
font family 'Basteleur' not found in PostScript font database
Warning in grid.Call(C_stringMetric, as.graphicsAnnot(x$label)) :
font family 'Basteleur' not found in PostScript font database
Warning in grid.Call(C_stringMetric, as.graphicsAnnot(x$label)) :
font family 'Basteleur' not found in PostScript font database
Warning in grid.Call(C_stringMetric, as.graphicsAnnot(x$label)) :
font family 'Basteleur' not found in PostScript font database
Warning in grid.Call(C_stringMetric, as.graphicsAnnot(x$label)) :
font family 'Basteleur' not found in PostScript font database
Warning in grid.Call(C_stringMetric, as.graphicsAnnot(x$label)) :
font family 'Basteleur' not found in PostScript font database
Warning in grid.Call(C_stringMetric, as.graphicsAnnot(x$label)) :
font family 'Basteleur' not found in PostScript font database
Warning in grid.Call(C_stringMetric, as.graphicsAnnot(x$label)) :
font family 'Basteleur' not found in PostScript font database
Warning in grid.Call(C_stringMetric, as.graphicsAnnot(x$label)) :
font family 'Basteleur' not found in PostScript font database
Warning in grid.Call(C_textBounds, as.graphicsAnnot(x$label), x$x, x$y, :
font family 'Basteleur' not found in PostScript font database
Warning in grid.Call(C_textBounds, as.graphicsAnnot(x$label), x$x, x$y, :
font family 'Basteleur' not found in PostScript font database
Warning in grid.Call.graphics(C_text, as.graphicsAnnot(x$label), x$x, x$y, :
font family 'Basteleur' not found in PostScript font database
Warning in grid.Call.graphics(C_text, as.graphicsAnnot(x$label), x$x, x$y, :
font family 'Basteleur' not found in PostScript font database
Warning in grid.Call.graphics(C_text, as.graphicsAnnot(x$label), x$x, x$y, :
font family 'Basteleur' not found in PostScript font database
Warning in grid.Call.graphics(C_text, as.graphicsAnnot(x$label), x$x, x$y, :
font family 'Basteleur' not found in PostScript font database
Warning in grid.Call.graphics(C_text, as.graphicsAnnot(x$label), x$x, x$y, :
font family 'Basteleur' not found in PostScript font database
Error in grid.Call.graphics(C_text, as.graphicsAnnot(x$label), x$x, x$y, :
invalid font type
Calls: <Anonymous> ... drawDetails -> drawDetails.text -> grid.Call.graphics
Execution halted
有没有办法在RScript中使用 systemfonts?你是不是一定要使用 extrafonts?
解决方案
执行在 ggsave() 之前就被停止。
没有赋值,
mydata |> ggplot() ...
会触发打印/提前渲染,批处理模式下的默认图形设备恰好是 pdf,而它又不支持 systemfonts。
要验证,请尝试在不设置字体的情况下使其在RStudio外部工作/使用 RScript,你应该会得到两个输出文件:Rplots.pdf 来自 ggplot() 的调用,以及 graph.png 来自 ggsave()。
切换到目标设备本应可行,但在批处理模式中我宁愿将 ggplot 对象存储起来并将其传递给 ggsave():
p <- mydata |> ggplot() +
geom_bar(
stat = "identity",
aes(x = type, y = quantity)
) +
labs(title = "Quantity of widgets, gizmos, and doodads") +
theme(plot.title = element_text(size = 15, family = "Basteleur"))
ggsave("graph.png", p, width = 10, height = 7, units = "in")
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。