ggplot shape = Unicode (e.g. arrows like "\u2198" or LaTeX \searrow)?
Asked Answered
D

2

6

I'd like to use Unicode shapes in ggplot2 geom_point() (specifically, arrows like ↘, Unicode "\u2198", or LaTeX \searrow), as in shape = "\u2198", that are not in the default font. In this unanswered post, @Laserhedvig commented "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()?"

This solution for Unicode in axes.text uses theme(axis.text.x = element_text(family = "FreeSerif")), and this solution uses theme(text=element_text(size=16, family="Comic Sans MS")) for all text, but how can I do this for shape?

  1. Is there a general solution to use Unicode for shape? (must I somehow use cairo and/or a font family argument?)
  2. If not, is there some other set of arrow shapes? (My search for arrow shapes and glyphs, including in the scale_shape documentation came up empty.)

In my case, I need a ggplot2 layer showing qualitative predictions for the direction of change at points in time across discrete categories.

An example:

library(dplyr)
library(ggplot2)

d <- tibble(year = c(1, 1, 2, 2),
       policy = rep( c('policy 1', 'policy 2'), 2),
       prediction = c(NA, 'increase', 'decrease', NA),
       predictionUnicode = c(NA, '\u2197', '\u2198', NA))

ggplot(d) + 
  geom_point(aes(x = year, y = policy, color = prediction), shape = "\u2198")

shape = "\u2198" (i.e. "↘") does not work

Edit: Thanks to djangodude's comment about ggplot's font usage, I found the family argument of geom_text, which allows different fonts. Thus, Unicode "shapes" can be plotted as characters with geom_text. However, the legend for geom_text is fixed to "a". And themes only control non-data display, so the base_family argument will not work for shape.

ggplot(d) + 
  geom_tile( aes(x = year, y = policy), color = "black", fill = "white") +   
  # geom_point does not allow new fonts?
  geom_point(aes(x = year, y = policy, 
                 color = prediction), shape = "\u2198") + 
  # geom_text does allow new fonts, but the legend text is fixed to "a"
  geom_text(aes(x = year, y= policy, 
                color = prediction,
                label = predictionUnicode), 
            family = "Calibri") + 
  scale_x_continuous(breaks = c(1,2)) +
  theme_gray(base_family = "Calibri") 

geom_text plots unicode, but not in the legend

It seems the shape argument is really the correct way to do this, right?

I tried setting Sys.setenv(LANG = "en_US.UTF-8") and Sys.setenv(LANG = "Unicode") to no effect, but perhaps some global language setting would affect shape?

Thank you so much for any help!

Note: These solutions for Unicode skull and crossbones and half-filled points do not have legends and will not work without the right font:

To get the right font:

  1. Look for an installed font that contains the Unicode character you seek. I found these instructions helpful.

  2. Import installed fonts into R

library(extrafont)
font_import()
fonts()
sessionInfo()
R version 3.5.2 (2018-12-20)
Platform: x86_64-apple-darwin15.6.0 (64-bit)
Running under: macOS Mojave 10.14.3
Dorladorlisa answered 25/2, 2019 at 16:43 Comment(0)
S
0

Use shape="\u2198" instead of \u8600. When specifying a character with \u notation, the value needs to be hexadecimal. 8600 is the decimal value for Unicode character LOWER RIGHT ARROW; the hex value is 2198.

Siderolite answered 25/2, 2019 at 20:12 Comment(4)
Thank you; I edited the question to reference "\u2198", but this also does not render with ggplot for me.Dorladorlisa
Ah, indeed, then the issue is probably the font being used to render the labels. Whatever font you're using most likely does not contain U+2198 (it's not in many fonts). I will have to leave a more complete answer up to users more familiar with ggplot2's font usage. cookbook-r.com/Graphs/Fonts has some examples showing the use of setting the font family, which might help, although first you'll need to identify an installed font that contains the characters.Siderolite
Thanks again; that clarifies that my Unicode issue is with ggplot2's font usage. I edited the example to include theme_gray(base_family = "") but no luck.Dorladorlisa
I banged around on this a bit more and ultimately came to the same conclusion as cookbook-r.com/Graphs/Fonts, specifically, "Font support in R is generally not very good". You might be able to get somewhere by installing the extrafont package (github.com/wch/extrafont) but the main issue seems to be setting the font that is used for geom_point. I tried a number of different ways, including theme_set and so on, but couldn't get it working. Sorry :-(Siderolite
W
0

"\u2192" worked for me by just random chance testing some other values in hope of finding a right pointing arrow.

Wallywalnut answered 22/1 at 3:23 Comment(2)
This does not provide an answer to the question. Once you have sufficient reputation you will be able to comment on any post; instead, provide answers that don't require clarification from the asker. - From ReviewTritium
Yes, interesting. \u2192 works for shape values and in the legend, but '\u2197', and '\u2198' do notDorladorlisa

© 2022 - 2024 — McMap. All rights reserved.