Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Having trouble rendering colour emoji in ggplot2 #9

Open
jimjam-slam opened this issue Aug 29, 2017 · 9 comments
Open

Having trouble rendering colour emoji in ggplot2 #9

jimjam-slam opened this issue Aug 29, 2017 · 9 comments

Comments

@jimjam-slam
Copy link

jimjam-slam commented Aug 29, 2017

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
Copy link
Author

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
Copy link
Owner

can you provide a simple example to reproduce the issue?

@jimjam-slam
Copy link
Author

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
Copy link
Owner

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

@jimjam-slam
Copy link
Author

jimjam-slam commented Aug 31, 2017

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

@GuangchuangYu
Copy link
Owner

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
Copy link
Owner

The figure you posted also show that it works:

.

@jimjam-slam
Copy link
Author

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
Copy link
Owner

GuangchuangYu commented Aug 31, 2017

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants