Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
643 views
in Technique[技术] by (71.8m points)

r - Greek letters, symbols, and line breaks inside a ggplot legend label

I am trying to

  1. have line breaks (automatic or forced)
  2. justify the text (left or both left and right)
  3. have greek letters and percentage signs

inside a gglot legend label.

I have experimented with several methods, but I don't seem to be able to combine all the tricks I read about.

I can get linebreaks by inserting into the labels, but that doesn't seem to work with greek letters, not inside legend labels. Or I could have linebreaks and greek letters in a base plot by combining mtext() and bquote() to insert a piece of text into the plot, (EDIT) but as pointed out by Gregor in the comments section, this doesn't work with ggplot. Below I combine a list with paste0() to pass text to the legend labels: the problem is I can't find the way to insert Greek letters, e.g. gamma.

Grateful for suggestions.

Here is a MWE with one of my attempts (Edit: improved MWE):

label1.line1 <- "Not much to say about this one"
label2.line1 <- "blabla blabla, blabla blabla, blee blee blee (bling, bling, bling),"
label2.line2 <- paste0("(", "1900-2014: g = 1.50%, gamma = 2.75%, and r = 2.30%",")")
label3.line1 <- "blabla blabla, blabla blabla, blee blee blee (bling, bling, bling),"
label3.line2 <- paste0("(", "1900-2014: g = 2.50%, gamma = 1.75%, and r = 2.30%",")")
labels_fixed <- list(
    label1.line1, 
    paste0(label2.line1, "
", label2.line2),
    paste0(label3.line1, "
", label3.line2)
)
library(ggplot2)
library(scales)
library(grid)  # provides unit() function used to tweak spacing inside legend

ggplot(data = mtcars, aes(x = mpg, y = wt, group = factor(cyl), colour = factor(cyl), shape = factor(cyl))) + 
geom_line() + geom_point(size = 3) + theme_bw() + 
scale_shape_manual(name = "Details", values = c(17, 21, 15), 
    labels = labels_fixed) + 
scale_colour_manual(name = "Details", values = c("darkred", "darkgreen", "darkblue"), 
    labels = labels_fixed) + 
theme(legend.key = element_blank(), 
      legend.position = c(.65, .8), 
      legend.background = element_rect(colour = "black"), 
      legend.key.size = unit(2, "lines"), 
      legend.text = element_text(size = 15)) 

A minor problem is that the legend text is much smaller with multiple lines so the legend line spacing will need to be tweaked: I was able to tweak legend.key.size and legend.text to achieve a better result than the default, which is too cramped.

I also tried another suggestion involving cat(strwrap("long label here"), sep = " "), but I couldn't get that to work. I also tried atop but that makes each line much too small and the nesting required to achieve the desired stacking is tedious.

Is there any way to get Greek letters?

enter image description here

Here are some useful suggestions I couldn't make to work, e.g. the combination of mtext() and bquote() is mentioned in 1 and 2:

  1. Expression and new line in plot labels
  2. Line break in expression()?
  3. Wrap horizontal legend across multiple rows
  4. using expression(paste( to insert math notation into a ggplot legend
  5. ggplot2 two-line label with expression
  6. How to annotate() ggplot with latex
  7. Greek letters in ggplot annotate
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Baptiste's suggestion was spot on: unicode go a long way. Replace every instance of gamma above with u03B3 and it will display as Greek. Amazing!

Printing can be done with the cairo device (ref):

library(Cairo)
cairo_pdf(file = "ggplot-greek.pdf", width = 8, height = 5)
## ggplot object created here
dev.off()

Also works: ggsave("greek.pdf", device = cairo_pdf)

Here is a selection of unicode symbols I have found useful:

"U016B" = ū
"U016A" = ū
"U00FB" = ?
"U00DB" = ?
"U0233" = ?
"U0232" = ?
"U0177" = ?
"U0176" = ?
"U0113" = ē
"U0112" = ē
"u00EA" = ê
"U00CA" = ê
"U003BCU2080" = μ?
"U003BCU2081" = μ?
"RU00B2" = R2
"u221E" = ∞
"u2248" = ≈
"U2260" = ≠ 
"u03C3/u221An" = σ/√n

Sadly, not all special characters have a unicode equivalent. For instance, there is a unicode for y-hat but not for x-hat. It is possible to combine the letter x with a unicode bar, as in "xu0305" = x? or "pu0302" = p?, but that doesn't seem to print very well.

I have also had difficulty printing greek unicode as axis labels, so in these cases I resorted to annotate() with the option coord_cartesian(clip = "off") to ensure that the labels printed below the axes do not get clipped ("on" is the default clipping behaviour).

Sometimes you can directly use the character, for instance:

myplot + labs(title  = "±")

When unicode fails, you can try expression(), e.g. x?:

title = expression(paste("z = (", bar(x), "-u03BC)/(u03C3/u221An)", sep = ""))  
library(ggplot2)
ggplot() + labs(title = title) + theme_bw() 

title

For convenience, I copy some commonly used greek letters' unicodes below. Many more unicodes may be found, e.g. http://en.wikipedia.org/wiki/List_of_Unicode_characters

u0391  Α   Greek Capital Letter Alpha
u0392  Β   Greek Capital Letter Beta
u0393  Γ   Greek Capital Letter Gamma
u0394  Δ   Greek Capital Letter Delta
u0395  Ε   Greek Capital Letter Epsilon
u0396  Ζ   Greek Capital Letter Zeta
u0397  Η   Greek Capital Letter Eta
u0398  Θ   Greek Capital Letter Theta
u0399  Ι   Greek Capital Letter Iota
u039A  Κ   Greek Capital Letter Kappa
u039B  Λ   Greek Capital Letter Lambda
u039C  Μ   Greek Capital Letter Mu
u039D  Ν   Greek Capital Letter Nu
u039E  Ξ   Greek Capital Letter Xi
u039F  Ο   Greek Capital Letter Omicron
u03A0  Π   Greek Capital Letter Pi
u03A1  Ρ   Greek Capital Letter Rho
u03A3  Σ   Greek Capital Letter Sigma
u03A4  Τ   Greek Capital Letter Tau
u03A5  Υ   Greek Capital Letter Upsilon
u03A6  Φ   Greek Capital Letter Phi
u03A7  Χ   Greek Capital Letter Chi
u03A8  Ψ   Greek Capital Letter Psi
u03A9  Ω   Greek Capital Letter Omega
u03B1  α   Greek Small Letter alpha
u03B2  β   Greek Small Letter beta
u03B3  γ   Greek Small Letter gamma
u03B4  δ   Greek Small Letter delta
u03B5  ε   Greek Small Letter epsilon
u03B6  ζ   Greek Small Letter zeta
u03B7  η   Greek Small Letter eta
u03B8  θ   Greek Small Letter theta
u03B9  ι   Greek Small Letter iota
u03BA  κ   Greek Small Letter kappa
u03BB  λ   Greek Small Letter lambda
u03BC  μ   Greek Small Letter mu
u03BD  ν   Greek Small Letter nu
u03BE  ξ   Greek Small Letter xi
u03BF  ο   Greek Small Letter omicron
u03C0  π   Greek Small Letter pi
u03C1  ρ   Greek Small Letter rho
u03C2  ?   Greek Small Letter final sigma
u03C3  σ   Greek Small Letter sigma
u03C4  τ   Greek Small Letter tau
u03C5  υ   Greek Small Letter upsilon
u03C6  φ   Greek Small Letter phi
u03C7  χ   Greek Small Letter chi
u03C8  ψ   Greek Small Letter psi
u03C9  ω   Greek Small Letter omega

Information about which fonts to use with unicode: https://en.wikipedia.org/wiki/List_of_typefaces#Unicode_fonts

Some currency symbols:

# http://www.fileformat.info/info/unicode/category/Sc/list.htm
Character   Name    Browser     Image
u0024  DOLLAR SIGN     $
u00A2  CENT SIGN   ¢
u00A3  POUND SIGN  £
u00A4  CURRENCY SIGN   ¤
u00A5  YEN SIGN    ¥
u058F  ARMENIAN DRAM SIGN
u060B  AFGHANI SIGN    ?
u09F2  BENGALI RUPEE MARK  ?
u09F3  BENGALI RUPEE SIGN  ?
u09FB  BENGALI GANDA MARK
u0AF1  GUJARATI RUPEE SIGN     ?
u0BF9  TAMIL RUPEE SIGN    ?
u0E3F  THAI CURRENCY SYMBOL BAHT   ?
u17DB  KHMER CURRENCY SYMBOL RIEL  ?
u20A0  EURO-CURRENCY SIGN  ?
u20A1  COLON SIGN  ?
u20A2  CRUZEIRO SIGN   ?
u20A3  FRENCH FRANC SIGN   ?
u20A4  LIRA SIGN   ?
u20A5  MILL SIGN   ?
u20A6  NAIRA SIGN  ?
u20A7  PESETA SIGN     ?
u20A8  RUPEE SIGN  ?
u20A9  WON SIGN    ?
u20AA  NEW SHEQEL SIGN     ?
u20AB  DONG SIGN   ?
u20AC  EURO SIGN   €
u20AD  KIP SIGN    ?
u20AE  TUGRIK SIGN     ?
u20AF  DRACHMA SIGN    ?
u20B0  GERMAN PENNY SIGN   ?
u20B1  PESO SIGN   ?
u20B2  GUARANI SIGN    ?
u20B3  AUSTRAL SIGN    ?
u20B4  HRYVNIA SIGN    ?
u20B5  CEDI SIGN   ?
u20B6  LIVRE TOURNOIS SIGN     ?
u20B7  SPESMILO SIGN   ?
u20B8  TENGE SIGN  ?
u20B9  INDIAN RUPEE SIGN   ?
u20BA  TURKISH LIRA SIGN   ?
u20BB  NORDIC MARK SIGN    ?
u20BC  MANAT SIGN  ?
u20BD  RUBLE SIGN  ?
uA838  NORTH INDIC RUPEE MARK
uFDFC  RIAL SIGN   ?
uFE69  SMALL DOLLAR SIGN   ﹩
uFF04  FULLWIDTH DOLLAR SIGN   $
uFFE0  FULLWIDTH CENT SIGN     ¢
uFFE1  FULLWIDTH POUND SIGN    £
uFFE5  FULLWIDTH YEN SIGN  ¥
uFFE6  FULLWIDTH WON SIGN  

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...