Отображать смайлы 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"  
Другие вопросы по тегам