在 ggplot2 geom_text 中以颜色呈现 unicode 表情符号
Posted
技术标签:
【中文标题】在 ggplot2 geom_text 中以颜色呈现 unicode 表情符号【英文标题】:Render unicode emoji in colour in ggplot2 geom_text 【发布时间】:2020-09-13 23:49:20 【问题描述】:我有包含表情符号的 unicode 文本。我想以包含表情符号颜色的方式将它们呈现在带有 geom_text 或 geom_label 的 ggplot2 图形中。我看过emojifont
、emo
和ggtext
,这些似乎都不允许这样做。问题当然是geom_text
中文本的颜色受颜色审美的支配。有什么方法可以通过 geom_text 或其他解决方法在我的文本中呈现颜色?
可重现的例子:
library(ggplot2)
pets <- "I like ???? ???? ???? ????"
cat(pets)
ggplot() +
theme_void() +
annotate("text", x = 1, y = 1, label = pets, size = 15)
cat(pets)
在 RStudio 的屏幕上工作,但最后一行绘制的图形如下所示:
或者,使用ggtext::geom_richtext()
我会得到类似的黑白结果和以下错误消息:
> library(ggtext)
> ggplot() +
+ theme_void() +
+ annotate("richtext", x = 1, y = 1, label = pets, size = 15)
Warning messages:
1: In text_info(label, fontkey, fontfamily, fontface, fontsize, cache) :
unable to translate '<U+0001F436>RStudioGD142.6791338582677' to native encoding
2: In text_info(label, fontkey, fontfamily, fontface, fontsize, cache) :
unable to translate '<U+0001F431>RStudioGD142.6791338582677' to native encoding
3: In text_info(label, fontkey, fontfamily, fontface, fontsize, cache) :
unable to translate '<U+0001F41F>RStudioGD142.6791338582677' to native encoding
4: In text_info(label, fontkey, fontfamily, fontface, fontsize, cache) :
unable to translate '<U+0001F422>RStudioGD142.6791338582677' to native encoding
5: In do.call(gList, grobs) :
unable to translate 'I like <U+0001F436> <U+0001F431> <U+0001F41F> <U+0001F422>' to native encoding
【问题讨论】:
【参考方案1】:好的,这是我自己的问题的答案。
整体做法:我们将每个表情符号转换为表情符号图像的超链接,并使用ggtext
来呈现新版本的文本和图像组合。
首先我们需要一个包含所有表情符号的向量,这样我们就可以识别它们:
library(tidyverse)
library(ggtext)
library(rvest)
# test vector
pets <- "I like ? ? ? ?"
# the definitive web page with emoji:
unicode <- read_html("https://unicode.org/emoji/charts/full-emoji-list.html")
ut <- unicode %>%
html_node("table") %>%
html_table()
# vector of all emoji - purely for recognition purposes
all_emoji <- ut[,3]
然后我几乎没有更改地从this page by Emil Hvitfeldt 借用几个函数。 Emil 对我也有类似的挑战,但没有原始表情符号只是文本的问题。
emoji_to_link <- function(x)
paste0("https://emojipedia.org/emoji/",x) %>%
xml2::read_html() %>%
rvest::html_nodes("tr td a") %>%
.[1] %>%
rvest::html_attr("href") %>%
paste0("https://emojipedia.org/", .) %>%
xml2::read_html() %>%
rvest::html_node('div[class="vendor-image"] img') %>%
rvest::html_attr("src")
link_to_img <- function(x, size = 24)
paste0("<img src='", x, "' width='", size, "'/>")
这些链接采用表情符号并将其转换为指向由 Apple Color Emoji 字体呈现的表情符号图像的超链接。到目前为止一切顺利,但我首先需要从我的混合测试中提取表情符号。为此,我又写了两个函数
将单个标记(其中标记可能是单个表情符号)转换为表情符号或将其作为未更改的文本返回;和 对文本字符串进行标记,将任何表情符号标记转换为图像,然后将它们重新粘贴在一起。这是这两个函数:
token_to_rt <- function(x)
if(x %in% all_emoji)
y <- link_to_img(emoji_to_link(x))
else
y <- x
return(y)
string_to_rt <- function(x)
tokens <- str_split(x, " ", simplify = FALSE)[[1]]
y <- lapply(tokens, token_to_rt)
z <- do.call(paste, y)
return(z)
现在我们拥有所需的一切。首先我将我的pets
向量转换为pets2
,然后我可以使用ggplot2
和ggtext
在屏幕上以绚丽的色彩渲染它
pets2 <- string_to_rt(pets)
ggplot() +
theme_void() +
annotate("richtext", x = 1, y = 1, label = pets2, size = 15)
我们来了:
为了完整起见,下面是关键对象 pets
、pets2
和 all_emoji
在 R 控制台中打印时的外观:
> pets
[1] "I like \U0001f436 \U0001f431 \U0001f41f \U0001f422"
> pets2
[1] "I like <img src='https://emojipedia-us.s3.dualstack.us-west-1.amazonaws.com/thumbs/120/apple/237/dog-face_1f436.png' width='24'/> <img src='https://emojipedia-us.s3.dualstack.us-west-1.amazonaws.com/thumbs/120/apple/237/cat-face_1f431.png' width='24'/> <img src='https://emojipedia-us.s3.dualstack.us-west-1.amazonaws.com/thumbs/120/apple/237/fish_1f41f.png' width='24'/> <img src='https://emojipedia-us.s3.dualstack.us-west-1.amazonaws.com/thumbs/120/apple/237/turtle_1f422.png' width='24'/>"
> all_emoji[1:10]
[1] "face-smiling" "Browser" "\U0001f600" "\U0001f603" "\U0001f604" "\U0001f601"
[7] "\U0001f606" "\U0001f605" "\U0001f923" "\U0001f602"
【讨论】:
细心的读者会注意到,此工作流程取决于表情符号两侧的空格。我想需要一些额外的工作来加强它以用于真实数据。以上是关于在 ggplot2 geom_text 中以颜色呈现 unicode 表情符号的主要内容,如果未能解决你的问题,请参考以下文章
如何在 R 中的 ggplot2 中更改 geom_text 中的字体颜色?
在堆积条形图中反转 geom_text() (ggplot2)
ggplot2:如何在 geom_text 标签中将字符变量(例如 x <- “.35”)解析为字符,而不是数字
有没有办法将 HSD.test 的结果从 agricolae 直接导入到 ggplot2 中的 geom_text() 中?