使用 cairo 在轴标题中保存带有表达式和 unicode 的 ggplot

bee*_*oot 6 r cairo ggplot2

我想保存以下情节:

library(ggplot2)

myplot <- ggplot(iris) +
  geom_point(aes(x = Sepal.Width, y = Sepal.Length)) +
  ylab(expression(~delta^13*C~"[\211]"))

ggsave(myplot, 
       filename = "myplot.png", 
       type = "cairo")
Run Code Online (Sandbox Code Playgroud)

但我收到以下错误:

Error in grid.Call.graphics(C_text, as.graphicsAnnot(x$label), x$x, x$y,  : 
  Metric information not available for this family/device
Run Code Online (Sandbox Code Playgroud)

问题一定是表达式和​​ unicode 的组合,因为这两者可以工作:

myplot <- ggplot(iris) +
  geom_point(aes(x = Sepal.Width, y = Sepal.Length)) +
  ylab("[\211]")

myplot <- ggplot(iris) +
  geom_point(aes(x = Sepal.Width, y = Sepal.Length)) +
  ylab(expression(~delta^13*C))
Run Code Online (Sandbox Code Playgroud)

我怎么解决这个问题?

编辑:我想打印“千分之一”符号。显然它的unicode是U2030,我错误地认为“\211”是一个unicode,但一定是别的东西。

编辑2:与此同时,我发现这个问题也有类似的问题。在那里,一个建议是用 保存情节encoding = "MacRoman",不幸的是这对我不起作用:

Error in png_dev(..., res = dpi, units = "in") : 
  unused argument (encoding = "MacRoman")
Run Code Online (Sandbox Code Playgroud)

编辑3:

> capabilities()["cairo"]
cairo 
 TRUE 
> sessionInfo()
R version 4.0.1 (2020-06-06)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows 7 x64 (build 7601) Service Pack 1

Matrix products: default

locale:
[1] LC_COLLATE=German_Germany.1252  LC_CTYPE=German_Germany.1252    LC_MONETARY=German_Germany.1252 LC_NUMERIC=C                   
[5] LC_TIME=German_Germany.1252    

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

other attached packages:
[1] patchwork_1.1.1 ggplot2_3.3.5   dplyr_1.0.7  
Run Code Online (Sandbox Code Playgroud)

sta*_*007 3

您尝试实际使用哪个 unicode 符号。我猜这只是你指定 unicode 符号的语法是错误的。

试试这个代码:

myplot <- ggplot(iris) +
  geom_point(aes(x = Sepal.Width, y = Sepal.Length)) +
  ylab(expression(~delta^13*C~"\U0211"))

ggsave(myplot, 
       filename = "myplot.png", 
       type = "cairo")
Run Code Online (Sandbox Code Playgroud)

这对我来说非常有效。

给出一个如下所示的情节: 在此输入图像描述

你用"\U0211"。因此"\U,为了指定您需要 unicode,然后是代码。

在这里查找 unicode 符号: https ://en.wikipedia.org/wiki/List_of_Unicode_characters

这是您必须输入以获得正确符号的第一列。例如,对于 U+020F 你写"\U020F"

更新

这是一个包含有关您的 unicode 符号的新信息的示例

myplot <- ggplot(iris) +
  geom_point(aes(x = Sepal.Width, y = Sepal.Length)) +
  ylab(expression(~delta^13*C~"\U2030"))

 ggsave(myplot, 
           filename = "myplot.png", 
           type = "cairo")
Run Code Online (Sandbox Code Playgroud)

给了我这个情节:

在此输入图像描述

您介意尝试上面的确切代码吗?还尝试在不保存的情况下运行 - 因为保存图实际上不应该成为问题。

所以也尝试只是跑

library("ggplot2")
ggplot(iris) +
      geom_point(aes(x = Sepal.Width, y = Sepal.Length)) +
      ylab(expression(~delta^13*C~"\U2030"))
Run Code Online (Sandbox Code Playgroud)

在那里,查看 y 轴标签是否正确显示。

如果仍然不起作用:

也可能是,您使用的字体不包含您尝试使用的 unicode 字符。

然后将以下内容添加到您的绘图代码中:

ggplot(iris) +
  geom_point(aes(x = Sepal.Width, y = Sepal.Length)) +
  ylab(expression(~delta^13*C~"\U2030")) +
  theme(text=element_text(family="Arial Unicode MS"))
Run Code Online (Sandbox Code Playgroud)

“Arial Unicode MS”实际上可以是任何可用的字体,并包含您想要的形式的 unicode 字符。

也许这些提示已经解决了问题 - 如果不只是写另一条评论,也许您还需要一些进一步的步骤。

进一步的步骤:

由于它仍然不起作用,并且您提到它似乎特定于保存,type = cairo请尝试以下操作:

cairo首先提供一些更多信息并使用此命令进行检查:

capabilities()["cairo"]
Run Code Online (Sandbox Code Playgroud)

结果应该是真的。

然后向我们发布一些有关您的系统的信息

sessionInfo()
Run Code Online (Sandbox Code Playgroud)

由于这些字体和绘图通常取决于您的操作系统。

然后我们 100% 确定我们有可用的字体/unicode 符号:

library(ggplot2)
install.packages("extrafont")
library("extrafont")
font_import()
loadfonts()
fonts()
Run Code Online (Sandbox Code Playgroud)

对 fonts() 的调用现在应该输出可用的字体。

也许您可以另外发布这些信息,以便我们可以为您提供进一步的步骤。

之后你可以再试一次,单独使用 extrafonts() 有时已经解决了问题:

library("ggplot2")
library("extrafont")
font_import()
loadfonts()

myplot <- ggplot(iris) +
  geom_point(aes(x = Sepal.Width, y = Sepal.Length)) +
  ylab(expression(~delta^13*C~"\U2030")) +
  theme(text=element_text(family="Arial Unicode MS"))
  
ggsave(myplot, 
       filename = "myplot.png", 
       type = "cairo")
Run Code Online (Sandbox Code Playgroud)

正如我所说,capabilities()["cairo"]必须返回true并且必须是某种返回的family="Arial Unicode MS"字体fonts()

准备好 extrafont 后也值得尝试不同的 grDevice

library("extrafont")
font_import()
loadfonts()

myplot <- ggplot(iris) +
  geom_point(aes(x = Sepal.Width, y = Sepal.Length)) +
  ylab(expression(~delta^13*C~"\U2030")) +
  theme(text=element_text(family="Arial Unicode MS"))
  
ggsave(myplot, 
       filename = "myplot.png", 
       type = "cairo-png")
Run Code Online (Sandbox Code Playgroud)

您还可以尝试更多...这是一篇关于在不同操作系统上保存图形的非常有趣的文章。有趣的是,根据您的操作系统和图形设备,导出的图形看起来略有不同。

只需在您的评论中阅读您想要使用开罗来提高质量即可。尝试一下它是否适用ragg于开罗 - 质量可能会更好。

ragg 提供了一组高质量和高性能的光栅设备,能够直接在 R 中生成 png、tiff 或 ppm 文件或原始颜色值矩阵。

ragg 是我们为提高 R 各个级别的图形性能和质量而做出的更广泛努力的一部分

library(ragg)

myplot <- ggplot(iris) +
  geom_point(aes(x = Sepal.Width, y = Sepal.Length)) +
  ylab(expression(~delta^13*C~"\U2030")) +
  theme(text=element_text(family="Arial Unicode MS"))

ggsave(
       filename = "myplot3.png",
       myplot,
       device = ragg::agg_png( 
         width = 3000,
         height = 3000, 
         units = "px",
         res = 500)
)
Run Code Online (Sandbox Code Playgroud)

由于您现在仍然遇到一些问题expression,因此您也可以将其与 结合起来ggtext。那么就没有必要了expression

myplot <- ggplot(iris) +
  geom_point(aes(x = Sepal.Width, y = Sepal.Length)) +
  ylab("\U03B4<sup>13</sup>C\U2030") +
  theme(
    axis.title.y = element_markdown(size = 11, lineheight = 1.2)
  )

ggsave(
       filename = "myplot4.png",
       myplot,
       device = ragg::agg_png( 
         width = 3000,
         height = 3000, 
         units = "px",
         res = 500)
)
Run Code Online (Sandbox Code Playgroud)

使用该包ggtext基本上使您可以使用轴标题执行所有类型的操作(粗体、多种颜色、不同尺寸……全部在一个标签中)。另请参阅ggtext手册。