Search code examples
rggplot2cairo

unicode symbol(s) not showing in ggplot geom_point shapes (and pdf)


I'm trying to use unicode symbols as geom_point shapes in ggplot. It mostly works as expected, but one symbol (▶, "\u25b6") doesn't show in the RStudio plot and in a pdf none of the symbols show up. Here's my example (the data show user input during listening to music):

library(tidyverse)
library(ggplot2)
library(Cairo)

event_levels <- c("open", "play", "q", "pause", "ff", "exit")
# 1st try: add the symbols directly
event_shapes1 <- c("⏏️", "▶", "❓", "⏸️", "⏩", "⏹️")
# 2nd try: add unicode
event_shapes2 <- c("\u23cf", "\u25b6", "\u2753", "\u23f8", "\u23e9", "\u23f9")
# 3rd try: add unicode with ucap letters
event_shapes3 <- c("\U23CF", "\U25B6", "\U2753", "\U23F8", "\U23E9", "\U23F9")
event_colours <- c("black", "green", "red", "orange", "blue", "black")

data <- tibble(event = factor(c("open", "play", "q", "play", "q", "play", "pause", "play", "ff", "exit"), levels = event_levels),
               time = seq(0, 100, length.out = length(event)),
               pos = c(0, 0, 50, 50, 100, 100, 150, 150, 200, 300))

p <- ggplot(data) +
  geom_line(mapping = aes(x = time, y = pos), alpha = 0.5) +
  geom_point(mapping = aes(x = time, y = pos, color = event, shape = event), size = 6) +
  scale_shape_manual(values = event_shapes2) + 
  # event_shapes1 doesn't work, no difference between event_shapes2 and event_shapes3
  scale_color_manual(values = event_colours)

ggsave("test.pdf", plot = p, device=cairo_pdf)

I might be doing something wrong or it might be a system specific fault (Win 10). I tried using library(extrafont) and par(family = "Consolas") and symbolfamily="Consolas" in the ggsave-line (and many other font families), but no success.

I also tried to print the symbols with geom_text and added the symbols to the tibble like this:

data <- data %>%
  mutate(event_shape = case_when(
    event == "open" ~ "⏏️",
    event == "play"~ "▶",
    event == "q" ~ "❓",
    event == "pause" ~ "⏸️",
    event == "ff" ~ "⏩",
    event == "exit" ~ "⏹️",
  ), .after = event)

p <- ggplot(data) +
  geom_line(mapping = aes(x = time, y = pos), alpha = 0.5) +
  geom_text(mapping = aes(x = time, y = pos, label = event_shape), size = 6)

But still no success. What can I do? I don't want to download the symbols every time, maybe I can save the symbols as png or svg locally and then add them to the graph? Or maybe something less complicated?


Solution

  • The emojifont package fixes this.

    Here's an example:

    library(emojifont)
    library(ggplot2)
    library(Cairo)
    
    df <- data.frame(
      x=1,
      y=1,
      text="\u25b6"
    )
    
    p <- ggplot(df, aes(x=x,y=y, label=text)) +
      geom_text()
    ggsave('test.pdf', p)