ggplot中Lato字体在RStudio正常但R Markdown编织时失效(Windows)
Windows下R Markdown编织时Lato字体失效问题的解决
问题背景
在Windows系统中,通过windowsFonts(Lato = windowsFont("Lato"))加载Lato字体后:
- 基础R绘图、RStudio中直接生成jpg/png/pdf格式图形时,字体显示正常
- 编织R Markdown文档时,出现警告:
Warning in grid.Call.graphics(C_text, as.graphicsAnnot(x$label), x$x, x$y, : font family 'Lato' not found, will use 'sans' instead
字体无法正常渲染。Mac系统无此问题,排查发现RStudio中dev.list()返回RStudioGD,而R Markdown编织时仅返回png,问题与绘图设备差异有关。
默认字体与Lato字体可通过字母"i"上方的点区分:Lato字体的点为圆形,默认字体为方形(RStudio中运行代码的正常效果):
编织R Markdown后的异常效果:
基础R绘图中字体显示正常:
原因分析
windowsFonts()仅对Windows原生窗口类绘图设备(如RStudioGD、windows())生效,而R Markdown编织时默认使用png()设备,该设备无法识别通过windowsFonts()注册的字体,需将字体注册到R的图形设备环境中。
解决方法
方法1:适配Windows的extrafont方案
在R Markdown代码块中添加以下代码,将Lato字体注册到png设备可用的字体库:
library(extrafont) # 仅注册Lato字体,避免全量扫描耗时 font_import(pattern = "Lato", prompt = FALSE) # 加载字体到Windows设备(包含png) loadfonts(device = "win")
之后在ggplot中指定base_family="Lato"即可正常渲染。
方法2:跨系统兼容的showtext方案
若需Windows/Mac系统统一生效,推荐使用showtext包:
library(showtext) # 加载Lato字体并命名为"Lato" font_add_google("Lato", "Lato") # 自动对所有绘图设备启用showtext showtext_auto()
此方法无需处理设备差异,在RStudio和R Markdown编织中均可正常生效。
修正后的可复现代码
--- title: "Untitled" output: html_document date: '2022-07-18' editor_options: chunk_output_type: console ---
knitr::opts_chunk$set(echo = TRUE) library(tidyverse) library(patchwork) library(extrafont) # 或library(showtext) # 方法1:extrafont注册字体(二选一) font_import(pattern = "Lato", prompt = FALSE) loadfonts(device = "win") # 方法2:showtext加载字体(二选一) # font_add_google("Lato", "Lato") # showtext_auto() # Windows机器加载字体(可保留,不冲突) windowsFonts(`Lato` = windowsFont("Lato"))
default_example <- mtcars %>% slice(1:10) %>% rownames_to_column("mfg") %>% ggplot(aes(x=mpg, y=reorder(mfg, mpg), fill=as.factor(cyl)))+ geom_col()+ ggtitle("无自定义字体")+ ylab("制造商")+ theme(legend.position = "none", plot.title=element_text(size=14)) font_example <- mtcars %>% slice(1:10) %>% rownames_to_column("mfg") %>% ggplot(aes(x=mpg, y=reorder(mfg, mpg), fill=as.factor(cyl)))+ geom_col()+ ggtitle("使用Lato字体")+ ylab("制造商")+ theme_minimal(base_family="Lato")+ theme(legend.position = "none", plot.title=element_text(size=14)) default_example + font_example
内容的提问来源于stack exchange,提问作者acircleda
相关产品推荐
相关产品推荐

