12

I'd like to use unicode characters as the shape of plots in ggplot, but for unknown reason they're not rendering. I did find a similar query here, but I can't make the example there work either.

Any clues as to why?

Note that I don't want to use the unicode character as a "palette", I want each item plotted by geom_point() to be the same shape (color will indicate the relevant variable).

Running

Sys.setenv(LANG = "en_US.UTF-8")

and restarting R does not help. Wrapping the unicode in sprintf() also does not help.

This is an example bit of code that illustrates the problem:

library(tidyverse)
library(ggplot2)
library(Unicode)

p1 = ggplot(mtcars, aes(wt, mpg)) +
  geom_point(shape="\u25D2", colour="red", size=3) +
  geom_point(shape="\u25D3", colour="blue", size=3) + 
  theme_bw()

plot(p1)

And here's what that renders result.

enter image description here

I use macOS Sierra (10.13.6), R version 3.5.1 & Rstudio 1.0.143.

Grateful for any help! I've been scouting several forums looking for a solution and posted to #Rstats, so far nothing has worked. It may be that the solution is hidden in some thread somewhere, but if so I have failed to detect it and I suspect others have also missed it. So, here I am making my first ever post to stack overflow :)

Ronak Shah
  • 377,200
  • 20
  • 156
  • 213
Laserhedvig
  • 381
  • 2
  • 13
  • 2
    For me, Ubuntu 18.04, R 3.5.1, your example works as it is. If you just enter `"\u25D2"` in the console and press return, do you get the expected output? – Stibu Oct 20 '18 at 10:50
  • Nope, I don't :/ I'm starting to think it's got something to do with the font/typeface setting. However, I've never changed from the default and I can't figure out how to change the font/family for shape (i.e. not text) on macs... any clues? – Laserhedvig Oct 22 '18 at 02:39
  • 1
    Right, after some discussion it seems that the problem lies in the font. Apparently, the base default fonts don't contain support for these specific glyphs. Now, how to change the font for the shape argument of geom_point()? NB: not the text, so theme() shouldn't help. – Laserhedvig Oct 23 '18 at 03:13
  • 1
    See [this solution](https://stackoverflow.com/a/53129919/9724126) (which is also my first-ever post to Stack Overflow :) ). – skalyan91 Nov 03 '18 at 09:15
  • To expand on Laserhedvig's comment, for most unicode characters, your code works just fine. That particular symbol does not render because the base font does not include it. – Dan Slone Oct 23 '19 at 18:05

2 Answers2

7

Might it work to use geom_text instead? It allows control of the font, so you can select one with the glyph you need.

library(tidyverse)
ggplot(mtcars, aes(wt, mpg)) +
  geom_text(label = "\u25D2", aes(color = as.character(gear)),  
            size=10, family = "Arial Unicode MS") +
  geom_text(label = "\u25D3", colour="blue", 
            size=10, family = "Arial Unicode MS") + 
  scale_color_discrete(name = "gear") +
  theme_bw()

enter image description here

Jon Spring
  • 55,165
  • 4
  • 35
  • 53
  • 2
    I needed to use "Lucida Sans Unicode" to get this to work as my system does not have "Arial Unicode MS" installed. – Dan Slone Oct 23 '19 at 18:00
3

It's possible to change the font family using par. The problem is that this will affect base R graphics but not ggplot2 graphics, as they use two different graphics devices (grDevices vs. grid). For instance, we can try to plot your example using base R functions, but at first we see the same issue:

plot(mtcars$wt, mtcars$mpg, pch="\u25D2", col = "red", cex = 2)
points(mtcars$wt, mtcars$mpg, pch="\u25D3", col = "blue", cex = 2)

base R plot, unicode characters aren't rendered

We can get what we want if we call par first (the font should support the symbols):

par(family = "Arial Unicode MS")
plot(mtcars$wt, mtcars$mpg, pch="\u25D2", col = "red", cex = 2)
points(mtcars$wt, mtcars$mpg, pch="\u25D3", col = "blue", cex = 2)

base R plot, unicode is rendered

Changing the font family parameter that specifically affects the points in a ggplot geom_point appears to be a bit more complicated. As far as I can tell, it would involve turning the ggplot object into a grob, editing the parameters, and then drawing it. It probably makes more sense to either use Jon Spring's geom_text solution, or use base R.