Using unicode characters as shape

2020-06-03 08:05发布

问题:

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.

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 :)

回答1:

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()



回答2:

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)

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)

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.