使用Cairo在R中更改绘图字体

5

我发现R的默认绘图效果略显模糊。为了解决这个问题,我将Cairo设置为图形设备,现在绘图效果好多了。

不幸的是,使用Cairo却带来了另一个问题,即由于某种原因,我无法应用在绘图窗口中使用的字体(在上面的左侧图中使用了Cambria字体,而右侧图未能应用此字体)。

以下是我的代码:

library(readxl)
library(scales)
library(ggplot2)
library(dplyr)
library('Cairo')

windowsFonts(Cam = windowsFont("Cambria"))

dataset <- read_excel('CW Data.xlsx')
colnames(dataset)[4] <- "Broadband Subs (%)"

options(scipen = 1000)

# Scatter plot FDI~GDP with regression line
CairoWin()
ggplot(dataset, aes(x=`2019 GDP ($bn)`, y=`2019 FDI ($m)`)) + 
  geom_point(size=3, shape=1) +
  geom_smooth(method='lm',formula=y~x, se=FALSE, color='black') +
  scale_x_continuous(label = comma) + scale_y_continuous(label=comma) +
  theme(panel.background = element_rect(fill="peachpuff"), 
        plot.background = element_rect(fill="peachpuff")) +
  theme(panel.grid.major = element_line(colour = "gray72"), 
        panel.grid.minor = element_line(colour = "gray72")) + 
  theme(text = element_text(family = "Cam")) 

ggsave("FDI~GDP.png", device="png", type = "cairo") 

这里是我使用的Excel数据的OneDrive链接

https://1drv.ms/x/s!AvGKDeEV3LOs4gNr714Ie0KbOjhO?e=bkdPvk


2
Ryan,不要链接到OneDrive数据,因为它不稳定,可能需要登录,并且将来可能不再起作用。你能否像teunbrand在他的“回答”中建议的那样创建一个示例? - tjebo
1
以下是我从OneDrive链接中获取的信息:该项目可能不存在或不再可用 该项目可能已被删除、过期或您无权查看它。 - IRTFM
1
由于我在Linux机器上交换了x11FontswindowsFonts的调用,并在下面的非答案中使用了MCVE后,无法重现。因此,我添加了[windows]标签。 我假设Cambria应该产生类似于旧式打字机输出(细的衬线等宽字体)的字体。 - IRTFM
1个回答

2
我建议您查看 raggsystemfonts 这两个包。它们使得使用字体非常容易,并且结果比基本选项的输出要好。

首先,我建议您使用 View(systemfonts::system_fonts()) 查询所有可用字体。您可以选择此处出现的每种字体来绘制或保存图形。

由于您分享的 onedrive 链接已经失效,我使用内置数据集重新创建了您的图形。我使用了 Cambria 字体,如下所示。

plot <- ggplot(dataset, aes(x = mpg, y = hp)) +
  geom_point(size = 3, shape = 1) +
  geom_smooth(
    method = 'lm',
    formula = y ~ x,
    se = FALSE,
    color = 'black'
  ) +
  scale_x_continuous(label = comma) +
  scale_y_continuous(label = comma) +
  labs(x = "2019 GDP ($bn)", y = "2019 FDI ($m)") +
  theme(
    panel.background = element_rect(fill = "peachpuff"),
    plot.background = element_rect(fill = "peachpuff")
  ) +
  theme(
    panel.grid.major = element_line(colour = "gray72"),
    panel.grid.minor = element_line(colour = "gray72")
  ) +
  theme(text = element_text(family = "Cambria")) # relevant line

我更喜欢将图形保存在一个对象中,并显式地传递给保存函数。
ggsave(
  "FDI~GDP.png", 
  plot = plot, 
  device = ragg::agg_png, # this is the relevant part
  width = 1920, 
  height = 1080,
  units = "px"
) 

这是结果:

plot

我会说它无缺地运行了。您还可以在RStudio中使用ragg作为图形设备,使其更加一致。请看这里
如果您想将图表输出到PDF中,您可以使用showtext来注册系统字体与所有新打开的图形设备。所以你需要做的是:
library(showtext)
showtext_auto()
ggsave(
  "FDI~GDP.pdf", 
  plot = plot,
  width = 1920, 
  height = 1080,
  units = "px"
) 

{ragg}包非常适合生成光栅图形(+1),但对于PDF或SVG等矢量图形,该解决方案不起作用。 - teunbrand
没错。SVG可以使用svglite,但我无法让PDF工作。 - JBGruber
@teunbrand 我认为只要你的字体是以afm格式并通过pdfFonts注册,它们应该能正确地呈现。将TrueType字体转换为afm并注册它们是{extrafont}包所做的事情,这对我来说似乎确实解决了问题。不过我不想把这个作为答案发布,因为我认为你已经尝试过了? - Allan Cameron
谢谢你的建议,Alan!我还没有尝试过这个,因为过去曾经使用extrafont包遇到过困难。afm格式对我来说完全陌生,所以我不知道这个。但你可以随意发布答案! - teunbrand
这个问题有一个名为 showtext 的第三方新包。我更新了我的答案以展示它的工作原理。 - JBGruber

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接