Отображать смайлы Unicode в цвете в ggplot2 geom_text
У меня есть текст в Юникоде, который включает смайлики. Я хотел бы отобразить их в графике ggplot2 с помощью geom_text или geom_label таким образом, чтобы включить цвет эмодзи. Я смотрел на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]
Затем я практически без изменений позаимствовал несколько функций с этой страницы Эмиля Хвитфельдта. Эмиль столкнулся со мной с аналогичной проблемой, но без проблемы с тем, что исходный смайлик был просто текстом.
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"