Hebrew and digits don't render ("Failed to get emoji face")
I found a problem when mixing Hebrew text with numbers - it causes the text to not appear. This does not affect other text in the figure.
Here are some oddities:
- The problem "disappears" when running the code through
reprex::reprex()(on the same machine). - saving the image with
ggsave()as a.pngalso has the missing text (as below). - saving the image with
ggsave()as a.pdfhas the text, but all of the Hebrew letters (regardless of mixing with numerals) are replaced with.s, which I suspect is a "standard" encoding problem.
Here is the code to reproduce the bug:
library(ggplot2)
#> Warning: package 'ggplot2' was built under R version 4.3.3
df <- data.frame(
x = 1:3,
y = 0,
label = c("זה טקסט",
"this is text with number 1",
"זה טקסט עם מספר 2")
)
ggplot(df, aes(x, y)) +
geom_label(aes(label = label))
#> Failed to get emoji face: ���, 0
#> Failed to get emoji face: ���, 0
#> Failed to get emoji face: , 0
#> Failed to get emoji face: , 0
#> Failed to get emoji face: , 0
Session info
sessioninfo::session_info()
#> ─ Session info ───────────────────────────────────────────────────────────────
#> setting value
#> version R version 4.3.2 (2023-10-31 ucrt)
#> os Windows 11 x64 (build 22631)
#> system x86_64, mingw32
#> ui RTerm
#> language (EN)
#> collate English_Israel.utf8
#> ctype English_Israel.utf8
#> tz Asia/Jerusalem
#> date 2024-07-25
#> pandoc 3.1.1 @ C:/Program Files/RStudio/resources/app/bin/quarto/bin/tools/ (via rmarkdown)
#>
#> ─ Packages ───────────────────────────────────────────────────────────────────
#> package * version date (UTC) lib source
#> cli 3.6.2 2023-12-11 [1] CRAN (R 4.3.2)
#> colorspace 2.1-0 2023-01-23 [1] CRAN (R 4.3.1)
#> curl 5.2.1 2024-03-01 [1] CRAN (R 4.3.3)
#> digest 0.6.35 2024-03-11 [1] CRAN (R 4.3.3)
#> dplyr 1.1.4 2023-11-17 [1] CRAN (R 4.3.2)
#> evaluate 0.23 2023-11-01 [1] CRAN (R 4.3.2)
#> fansi 1.0.6 2023-12-08 [1] CRAN (R 4.3.2)
#> farver 2.1.2 2024-05-13 [1] CRAN (R 4.3.2)
#> fastmap 1.2.0 2024-05-15 [1] CRAN (R 4.3.3)
#> fs 1.6.4 2024-04-25 [1] CRAN (R 4.3.3)
#> generics 0.1.3 2022-07-05 [1] CRAN (R 4.3.1)
#> ggplot2 * 3.5.1 2024-04-23 [1] CRAN (R 4.3.3)
#> glue 1.7.0 2024-01-09 [1] CRAN (R 4.3.2)
#> gtable 0.3.5 2024-04-22 [1] CRAN (R 4.3.3)
#> highr 0.10 2022-12-22 [1] CRAN (R 4.3.1)
#> htmltools 0.5.8.1 2024-04-04 [1] CRAN (R 4.3.3)
#> knitr 1.46 2024-04-06 [1] CRAN (R 4.3.3)
#> labeling 0.4.3 2023-08-29 [1] CRAN (R 4.3.1)
#> lifecycle 1.0.4 2023-11-07 [1] CRAN (R 4.3.2)
#> magrittr 2.0.3 2022-03-30 [1] CRAN (R 4.3.1)
#> munsell 0.5.1 2024-04-01 [1] CRAN (R 4.3.3)
#> pillar 1.9.0 2023-03-22 [1] CRAN (R 4.3.1)
#> pkgconfig 2.0.3 2019-09-22 [1] CRAN (R 4.3.1)
#> purrr 1.0.2 2023-08-10 [1] CRAN (R 4.3.1)
#> R.cache 0.16.0 2022-07-21 [1] CRAN (R 4.3.1)
#> R.methodsS3 1.8.2 2022-06-13 [1] CRAN (R 4.3.0)
#> R.oo 1.26.0 2024-01-24 [1] CRAN (R 4.3.2)
#> R.utils 2.12.3 2023-11-18 [1] CRAN (R 4.3.2)
#> R6 2.5.1 2021-08-19 [1] CRAN (R 4.3.1)
#> reprex 2.1.0 2024-01-11 [1] CRAN (R 4.3.2)
#> rlang 1.1.3 2024-01-10 [1] CRAN (R 4.3.2)
#> rmarkdown 2.27 2024-05-17 [1] CRAN (R 4.3.3)
#> rstudioapi 0.16.0 2024-03-24 [1] CRAN (R 4.3.3)
#> scales 1.3.0 2023-11-28 [1] CRAN (R 4.3.2)
#> sessioninfo 1.2.2 2021-12-06 [1] CRAN (R 4.3.1)
#> styler 1.10.3 2024-04-07 [1] CRAN (R 4.3.3)
#> tibble 3.2.1 2023-03-20 [1] CRAN (R 4.3.1)
#> tidyselect 1.2.1 2024-03-11 [1] CRAN (R 4.3.3)
#> utf8 1.2.4 2023-10-22 [1] CRAN (R 4.3.1)
#> vctrs 0.6.5 2023-12-01 [1] CRAN (R 4.3.2)
#> withr 3.0.0 2024-01-16 [1] CRAN (R 4.3.2)
#> xfun 0.44 2024-05-15 [1] CRAN (R 4.3.3)
#> xml2 1.3.6 2023-12-04 [1] CRAN (R 4.3.2)
#> yaml 2.3.8 2023-12-11 [1] CRAN (R 4.3.2)
#>
#> [1] C:/Users/user/AppData/Local/R/win-library/4.3
#> [2] C:/Program Files/R/R-4.3.2/library
#>
#> ──────────────────────────────────────────────────────────────────────────────
Thanks for the report! This is an issue with graphics devices, which is beyond the control of ggplot2.
library(grid)
grid.newpage()
grid.text(
x = c(0.25, 0.5, 0.75),
y = 0.5,
label = c("זה טקסט",
"this is text with number 1",
"זה טקסט עם מספר 2")
)

#> Failed to get emoji face: pmcc, 0
#> Failed to get emoji face: , -922569248
Created on 2024-07-25 with reprex v2.1.1
Thanks @teunbrand. Weird that this has 0 hits on Google.
If we take another device png(type = "cairo") here, we do render all 3 texts.
While I'm no expert in RtL languages, I think the glyph order is different than in the other device.
library(grid)
grid.newpage()
grid.text(
x = c(0.25, 0.5, 0.75),
y = 0.5,
label = c("זה טקסט",
"this is text with number 1",
"זה טקסט עם מספר 2")
)

Created on 2024-07-25 with reprex v2.1.1
Another thing that you could try is to explicitly use a font that you know contains all the glyphs that you need. Font used in example below is available here: https://fonts.google.com/noto/specimen/Noto+Sans+Hebrew. This sort-of looks correct to my untrained eye, but again, I'm no RtL language expert.
knitr::opts_chunk$set(dev = "ragg_png")
library(grid)
grid.newpage()
grid.text(
x = c(0.25, 0.5, 0.75),
y = 0.5,
label = c("זה טקסט",
"this is text with number 1",
"זה טקסט עם מספר 2"),
gp = gpar(family = "Noto Sans Hebrew")
)

Created on 2024-07-25 with reprex v2.1.1
Thanks!
How do integrate this solution with ggplot? adding sysfonts::font_add_google(name = "Noto Sans Hebrew") and then geom_text(family = "Noto Sans Hebrew") while saving to a ragg::agg_png doesn't seem to do anything?
Honestly, I don't know: it seems to fail on my end too and results are inconsistent. Maybe @thomasp85 has a better idea than I do what is going on here.
Using straightforward print to device, the 2 is missing in 3rd text.
#+ setup, include=FALSE
knitr::opts_chunk$set(dev = "ragg_png")
#+ main
library(ggplot2)
df <- data.frame(
x = 1:3,
y = 0,
label = c("זה טקסט",
"this is text with number 1",
"זה טקסט עם מספר 2")
)
ggplot(df, aes(x, y)) +
geom_label(
aes(label = label),
family = "Noto Sans Hebrew", hjust = 'inward'
)

#> Failed to get emoji face: , 0
#> Failed to get emoji face: , 0
#> Failed to get emoji face: , 0
#> Failed to get emoji face: , 0
Created on 2024-07-25 with reprex v2.1.1
Using ggsave() also has a missing 2 but also misjudges the text size based on the textbox placement:
library(ggplot2)
df <- data.frame(
x = 1:3,
y = 0,
label = c("זה טקסט",
"this is text with number 1",
"זה טקסט עם מספר 2")
)
p <- ggplot(df, aes(x, y)) +
geom_label(
aes(label = label),
family = "Noto Sans Hebrew", hjust = 'inward'
)
ggsave("temp.png", p, device = ragg::agg_png)
#> Saving 7 x 5 in image
#> Failed to get emoji face: , 10
#> Failed to get emoji face: , 0
#> Failed to get emoji face: , 65024
knitr::include_graphics("temp.png")
Created on 2024-07-25 with reprex v2.1.1
This is weird - I now see that at least 4 months ago this did work (comparing a plot that use to render properly). Hoping @thomasp85 has any ideas....
Let's just re-open this because ggsave() has behaviour I don't know how to explain
In the dev version of ggplot2, the ggsave() and print to device give the same results, which would mean that we're only left with the issue that devices cannot render some labels properly. However, this is not really something that ggplot2 has control over, so I'm going to close this again.
Sorry to keep bringing this up, but I just tried running the code (both ggplot and raw grid code) in RGui (instead of RStudio) and it does work. Does this help localize where the Failed to get emoji face is coming from?
I presume it'd then circumvent RStudio's shadow device and if that is the case, it'd point to the shadow device as having a role. If we entertain the idea that the shadow device is at fault, that is something that RStudio might be able to fix.
Thanks @teunbrand!
This was due to having selected "AGG" in RStudio under Options > General > Graphics > Backend. All other backends (windows, Cairo, Cairo PNG) render the Hebrew+number (though Cairo PNG invert the Hebrew).
Surfacing this up, although this seems to have been solved/worked around in RStudio, the issue exists in Positron. I simply don't know where to look for the equivalent option from RStudio in Positron (if there is such an option).
I think Positron uses ragg when available by default. Do you have ragg installed?
Installed as in the R ragg library? yes, it is installed.
Using the 'vanilla' ggsave would recreate the issue described above.
Using a different device would render the text inverted e.g.:
png(type = "cairo", filename = "test.png")
some_ggplot
dev.off()
And when numbers and Hebrew text are not combined (e.g., just Hebrew text, no numbers), all is fine with ggsave, though the plots pane in Positron has the text inverted.
Issue solved - with some digging into + running on different platforms.
This is related to a bug in textshaping, see issue #6497 that I reported a while ago.
It's just that the different error messages confused me (Running on Linux yields a different error than windows).
The "linux version of events" leads to Error: Unable to merge embeddings of different levels and the "windows version of events" is vague in its error message Failed to get emoji face.
EDIT: After reading a bit more (https://github.com/r-lib/textshaping/issues/49), these might be two different unrelated issues, but both of them are fixed in the textshaping dev version anyhow...
Resolution
So basically what I did is to install systemfonts (from CRAN) and then the dev version of textshaping
install.packages("systemfonts")
remotes::install_github("r-lib/textshaping")