You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

flextable与ggplot2兼容性问题:阿拉伯语、印地语图表异常

ggplot2加载flextable后无法渲染印地语/阿拉伯语文本的解决办法

问题详情

  • 未加载flextable时,ggplot2能正常输出包含英文、俄文、印地语、阿拉伯语的图表
  • 加载flextable并重启会话后,仅英文、俄文图表正常,印地语图表标签缺失,阿拉伯语图表完全无法渲染
  • 卸载flextable及其所有依赖包后,问题依然存在
  • 问题并非针对拉丁字母语言(俄文可正常显示),也与右至左语言无关(印地语同样异常)

测试代码(未加载flextable时正常运行)

library(dplyr) # data management
#library(flextable) # used elsewhere in application
library(ggplot2) # chart

datDf <- tibble(En = c("Orange","Purple"),
                Ru = c("оранжевый","Пурпурный"),
                Hi = c("नारंगी","जामुनी"),
                Ar = c("برتقالي","بنفسجي"), # R handles the direction change
                xMin = c(1,2),
                xMax = c(3,4)) %>%
  # keep rows in order for plot
  mutate(across(c(En,Ru,Hi,Ar), ~factor(.x, levels=rev(.x)))) 

plotFun <- function(labLang){
  # x-axis labels
  xTiks <- switch(deparse(substitute(labLang)),
                  En = c("1.0
Almost Never",
                         "2.0
Rarely",
                         "3.0
Sometimes",
                         "4.0
Often",
                         "5.0
Almost Always"),
                  Ru = c("1.0
Почти никогда",
                         "2.0
Редко",
                         "3.0
Иногда",
                         "4.0
Часто",
                         "5.0
Почти всегда"),
                  Hi = c("1.0
लगभग कभी नही",
                         "2.0
शायद ही कभी",
                         "3.0
कभी-कभी",
                         "4.0
अक्सर",
                         "5.0
लगभग हमेशा"),
                  Ar = c("1.0
تقريبًا لا على الإطلاق",
                         "2.0
نادرًا",
                         "3.0
في بعض الأحيان",
                         "4.0
غالبًا",
                         "5.0
تقريبًا دائمًا")
                  )
  plt1 <- ggplot(datDf, aes(y={{labLang}}, xmin=xMin, xmax=xMax)) +
    geom_linerange()
  plt2 <- if (deparse(substitute(labLang)) == "Ar") {
    # handle right-to-left for Arabic
    plt1 +
      scale_x_reverse(labels=xTiks, limits=c(5,1)) +
      scale_y_discrete(position="right")
  } else {
    plt1 +
      scale_x_continuous(labels=xTiks, limits=c(1,5))
  }
  return(plt2)
}

plotFun(En) # English
plotFun(Ru) # Russian
plotFun(Hi) # Hindi
plotFun(Ar) # Arabic

卸载flextable及其依赖的尝试代码

unloadNamespace("flextable")
unloadNamespace("data.table")
unloadNamespace("gdtools")
unloadNamespace("Rcpp") # unload gdtools first
unloadNamespace("fontquiver") # unload gdtools first
unloadNamespace("fontLiberation") # unload fontquiver first
unloadNamespace("fontBitstreamVera") # unload fontquiver first
unloadNamespace("officer")
unloadNamespace("openssl") # unload officer first
unloadNamespace("askpass") # unload openssl first
unloadNamespace("uuid") # unload officer first
unloadNamespace("xml2") # unload officer first
unloadNamespace("zip") # unload officer first
unloadNamespace("ragg") # unload officer first
unloadNamespace("textshaping")
unloadNamespace("systemfonts") # unload gdtools, ragg, textshaping first

解决办法

1. 给ggplot2强制指定多语言兼容字体

flextable加载后可能篡改了R的默认字体配置,导致ggplot2找不到支持印地语、阿拉伯语的字体。直接在绘图函数里指定支持多语言的字体(比如Google的Noto系列,需提前安装到系统):

修改plotFun函数,在返回plt2前添加主题设置:

plt2 <- plt2 + theme(
  axis.text = element_text(family = "Noto Sans"), # 针对印地语可单独用"Noto Sans Devanagari",阿拉伯语用"Noto Sans Arabic"
  axis.title = element_text(family = "Noto Sans")
)

2. 重置字体缓存并重启会话

flextable的依赖包(如systemfonts)会修改字体缓存,卸载包后缓存不会自动清除。执行以下操作:

# 清除字体缓存
systemfonts::clear_font_cache()

必须完全重启R会话(关闭再打开),不要加载flextable,先测试ggplot2多语言渲染是否恢复正常,再按需加载flextable。

3. 隔离flextable的运行环境

如果必须同时用flextable和ggplot2多语言渲染,用callr包在独立会话中运行flextable代码,避免影响主会话的字体配置:

library(callr)
# 在独立会话中处理flextable任务
r(function() {
  library(flextable)
  # 这里写你的flextable相关代码
})

主会话保持不加载flextable,确保ggplot2的字体配置不受干扰。

验证步骤

  1. 彻底关闭R,重新打开,不加载任何包
  2. 运行测试代码,确认所有语言图表正常显示
  3. 加载flextable后再次测试,看问题是否复现
  4. 应用上述解决办法后再次验证

内容的提问来源于stack exchange,提问作者bcarothers

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 05:43:12