GuangchuangYu / emojifont

:lollipop:Emoji and fontawesom in both base and ggplot2 graphics
https://guangchuangyu.github.io/emojifont/
67 stars 21 forks source link

Having trouble rendering colour emoji in ggplot2 #9

Open jimjam-slam opened 7 years ago

jimjam-slam commented 7 years ago

I'm trying to use the emoji associated with countries in a ggplot2 visualisation. However, the emoji are rendering as the individual country code Unicode sequence components:

steamtrain2012 = ggplot(all_data %>% filter(year == 2012)) +
  geom_pointrange(
    aes(
      x = gdppc,
      ymin = temp_min,
      y = temp,
      ymax = temp_max,
      colour = world_6region)) +
  geom_text(
    aes(
      x = gdppc,
      y = 2.3,
      label = flag_emoji,
      size = co2_cum),
    family = 'EmojiOne') +
  scale_x_log10() +
  scale_y_continuous(limits = c(-2.5, 2.5)) +
  scale_size(range = c(0, 20), guide = FALSE) +
  theme_classic(base_size = 16)

test1

However, the Unicode code points I'm providing appear to be right as far as I can tell:

> emoji('australia')
[1] "\U0001f1e6\U0001f1fa"
> emoji('us')
[1] "\U0001f1fa\U0001f1f8"
> head(all_data$flag_emoji)
[1] "\U0001f1fa\U0001f1ff" "\U0001f1e6\U0001f1f2" "\U0001f1ec\U0001f1ea"
[4] "\U0001f1f0\U0001f1ec" "\U0001f1fb\U0001f1f3" "\U0001f1f9\U0001f1ef"

I've also tried using gganimate to make a video version with the full dataset, as well as a ggplotly version. With gganimate rendering to a GIF or an MP4, I get the same result as with a static ggplot.

With plotly, the flags render correctly as emoji, but they use my system emoji font, not EmojiOne. I understand that this is probably a browser limitation and am looking at whether I can inject some Javascript to do the substitution :/ But it would be nice to get to the bottom of why it isn't working with a static or animated plot!

(Note: I'm running R 3.3.3 on macOS 10.12.6)

jimjam-slam commented 7 years ago

I've also tried rendering to SVG using grid.export, as per these instructions. In this case the correct font is used, but it still falls back to the black-and-white outline emoji.

GuangchuangYu commented 7 years ago

can you provide a simple example to reproduce the issue?

jimjam-slam commented 7 years ago

Well, here's the code I'm using after my data's been tidied. You can reproduce it with:

library(tidyverse)
library(magrittr)
library(gganimate)
library(plotly)
library(emojifont)
filter = dplyr::filter

# source data and constants
all_data = read_csv(paste0('https://raw.githubusercontent.com/rensa/steamtrain/',
  'gh-pages/data/gapminder-berkeley-tidy.csv'))
year_start = 1900
year_end = 2012
frames_per_year = 30

# build full version (works with gganimate or plotly
steamtrain = ggplot(all_data) +
  geom_pointrange(
    aes(
      x = gdppc,
      ymin = temp_min,
      y = temp,
      ymax = temp_max,
      colour = world_6region,
      text = paste(flag_emoji, name),
      frame = year)) +
  geom_text(
    aes(
      x = gdppc,
      y = 2.3,
      label = flag_emoji,
      group = world_6region,
      text = paste(flag_emoji, name),
      size = co2_cum,
      frame = year),
    family = 'EmojiOne Color') +
  geom_point(
    aes(
      x = gdppc,
      y = 2.3,
      label = flag_emoji,
      group = world_6region,
      size = co2_cum,
      frame = year),
    colour = 'black', alpha = 0.15) +
  scale_x_log10(name = 'GDP (2010 US Dollars)') +
  scale_y_continuous(name = 'Temperature anomaly (°C)', limits = c(-2.5, 2.5)) +
  scale_size(name = 'Cumulative CO2 emissions (Mt)', range = c(0, 20),
    guide = FALSE) +
  ggtitle('Historical CO2 emissions, GDP per capita and temperature rise',
    subtitle = paste('Who contributed to the greenhouse effect,',
      'and who suffers for it?')) +
  theme_classic(base_size = 16)

# build static version using just 2012
steamtrain2012 = ggplot(all_data %>% filter(year == 2012)) +
  geom_pointrange(
    aes(
      x = gdppc,
      ymin = temp_min,
      y = temp,
      ymax = temp_max,
      colour = world_6region)) +
  geom_emoji(
    aes(
      x = gdppc,
      y = 2.3,
      label = flag_emoji,
      size = co2_cum),
    family = 'EmojiOne Color') +
  scale_x_log10() +
  scale_y_continuous(limits = c(-2.5, 2.5)) +
  scale_size(range = c(0, 20), guide = FALSE) +
  theme_classic(base_size = 16)

# render static 2012 version
ggsave(filename = 'steamtrain2012.pdf', plot = steamtrain2012)

# render full plot with plotly
steamtrain_plotly = steamtrain %>%
  animation_opts(1000, easing = 'linear', redraw = FALSE) %>%
  animation_slider(
    currentvalue = list(prefix = 'Year ', font = list(color = 'black')))
htmlwidgets::saveWidget(steamtrain_plotly, file = "steamtrain_plotly.html")

# render animated version
animation::ani.options(interval = 0.5 / frames_per_year)
gganimate(steamtrain, 'steamtrain.mp4',
  ani.width = 1920, ani.height = 1080, title_frame = TRUE)
GuangchuangYu commented 7 years ago

Instead of family = 'EmojiOne Color', you need to use family = 'EmojiOne'

jimjam-slam commented 7 years ago

If I use family = 'EmojiOne', I get nothing rendering at all :/ (plotly continues to show colour emoji but in the Apple system font.)

GuangchuangYu commented 7 years ago
ggplot(all_data[1:10,]) +
  geom_text(
    aes(
      x = gdppc,
      y = co2_cum,
      label = flag_emoji),
    family = 'EmojiOne', 
    size = 8)

screenshot 2017-08-31 20 31 30

emojifont is designed to work with R graphics (including png, pdf), but not js/html.

GuangchuangYu commented 7 years ago

The figure you posted also show that it works:

.

jimjam-slam commented 7 years ago

Fair enough. But these are the emoji for the individual region symbols, not the ligature flag emoji. Is it possible that I need to format the unicode control sequences differently to get the flags?

> head(all_data$flag_emoji)
[1] "\U0001f1fa\U0001f1ff" "\U0001f1e6\U0001f1f2" "\U0001f1ec\U0001f1ea"
[4] "\U0001f1f0\U0001f1ec" "\U0001f1fb\U0001f1f3" "\U0001f1f9\U0001f1ef"
GuangchuangYu commented 7 years ago

I got your idea now. \U0001f1fa\U0001f1ff should be parsed as a flag but was parsed as two letters, \U0001f1fa (U) and \U0001f1ff (Z).

Maybe the author of showtext, @yixuan , can help.