r - Conflict between flextable, ggplot2, and Arabic & Hindi - Stack Overflow

admin2025-05-01  0

I'm having trouble getting ggplot2 to work with Arabic and Hindi when flextable is loaded.

Here's a first run that also includes English and Russian to demonstrate that everything works without flextable loaded:

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\nAlmost Never",
                         "2.0\nRarely",
                         "3.0\nSometimes",
                         "4.0\nOften",
                         "5.0\nAlmost Always"),
                  Ru = c("1.0\nПочти никогда",
                         "2.0\nРедко",
                         "3.0\nИногда",
                         "4.0\nЧасто",
                         "5.0\nПочти всегда"),
                  Hi = c("1.0\nलगभग कभी नही",
                         "2.0\nशायद ही कभी",
                         "3.0\nकभी-कभी",
                         "4.0\nअक्सर",
                         "5.0\nलगभग हमेशा"),
                  Ar = c("1.0\nتقريبًا لا على الإطلاق",
                         "2.0\nنادرًا",
                         "3.0\nفي بعض الأحيان",
                         "4.0\nغالبًا",
                         "5.0\nتقريبًا دائمًا")
                  )
  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

Plot outputs run as expected:

Here's the tricky part. If I remove the # from library(flextable) and re-run everything in the same session, it all still works. If I then restart the session and re-run everything, the English and Russian plots are still fine, but the Hindi plot is missing the labels, and the Arabic plot won't render at all:

The problem persists even if I unload flextable and all of its dependencies before running the plot function:

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

As far as I can tell, unloading all of those didn't remove anything that comes with dplyr, ggplot2, and whatever is there by default.

The problem isn't with things only working with the Latin alphabet because it still works with Russian, and the problem isn't with right-to-left languages because Hindi doesn't work either.

I'm having trouble getting ggplot2 to work with Arabic and Hindi when flextable is loaded.

Here's a first run that also includes English and Russian to demonstrate that everything works without flextable loaded:

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\nAlmost Never",
                         "2.0\nRarely",
                         "3.0\nSometimes",
                         "4.0\nOften",
                         "5.0\nAlmost Always"),
                  Ru = c("1.0\nПочти никогда",
                         "2.0\nРедко",
                         "3.0\nИногда",
                         "4.0\nЧасто",
                         "5.0\nПочти всегда"),
                  Hi = c("1.0\nलगभग कभी नही",
                         "2.0\nशायद ही कभी",
                         "3.0\nकभी-कभी",
                         "4.0\nअक्सर",
                         "5.0\nलगभग हमेशा"),
                  Ar = c("1.0\nتقريبًا لا على الإطلاق",
                         "2.0\nنادرًا",
                         "3.0\nفي بعض الأحيان",
                         "4.0\nغالبًا",
                         "5.0\nتقريبًا دائمًا")
                  )
  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

Plot outputs run as expected:

Here's the tricky part. If I remove the # from library(flextable) and re-run everything in the same session, it all still works. If I then restart the session and re-run everything, the English and Russian plots are still fine, but the Hindi plot is missing the labels, and the Arabic plot won't render at all:

The problem persists even if I unload flextable and all of its dependencies before running the plot function:

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

As far as I can tell, unloading all of those didn't remove anything that comes with dplyr, ggplot2, and whatever is there by default.

The problem isn't with things only working with the Latin alphabet because it still works with Russian, and the problem isn't with right-to-left languages because Hindi doesn't work either.

Share Improve this question edited Apr 11 at 20:14 TylerH 21.1k79 gold badges79 silver badges114 bronze badges asked Jan 2 at 19:45 bcarothersbcarothers 92410 silver badges23 bronze badges 5
  • Is "Orange" the color or the fruit? In Russian, orange color is "оранжевый", but the fruit is "апельсин". – yuk Commented Jan 3 at 0:24
  • @yuk - I just meant the color, so I revised according to your suggestion. Thanks! (Google translate fail! These aren't my real categories...) – bcarothers Commented Jan 3 at 0:31
  • Sorry that I cannot answer the actual question. You can try to place this as an issue on the flextable github. – yuk Commented Jan 3 at 0:34
  • 1 I've tried to load the packages under Imports section in the flextable DESCRIPTION file, one by one. It looks the problem is from the officer package. – yuk Commented Jan 3 at 0:50
  • 1 Also ragg package. – yuk Commented Jan 3 at 0:54
Add a comment  | 

1 Answer 1

Reset to default 1

Thanks to @yuk's comments, I was able to narrow the problem down to the textshaping package (a dependent of ragg, which is a dependent of officer, which is a dependent of flextable). Upon a closer reading of this thread (How to unload a package without restarting R), I realized that unloadNamespace wasn't doing everything I needed. Instead, plugging in pkgload::unload("textshaping") before the plot functions solved the issue. Including library(textshaping) after I've rendered the charts puts it back in place just fine for when I need it later.

转载请注明原文地址:http://anycun.com/QandA/1746099792a91662.html