2

I am trying to change the labels in a ggplot object to Greek symbols for an arbitrary number of labels. Thanks to this post, I can do this manually when I know the number of labels in advance and the number is not too large:

    # Simulate data 
   df <- data.frame(name = rep(c("alpha1","alpha2"), 50),
               value = rnorm(100))
   
   # Create a plot with greek letters for labels
   ggplot(df, aes(x = value, y = name)) + geom_density() +
     scale_y_discrete(labels = c("alpha1" = expression(alpha[1]),
                                 "alpha2" = expression(alpha[2])))
   

For our purposes, assume I need to change k default labels, where each of the k labels is the pre-fix "alpha" followed by a number 1:k. Their corresponding updated labels would substitute the greek letter for "alpha" and use a subscript. An example of this is below:

# default labels
paste0("alpha", 1:k)

# desired labels
for (i in 1:k) { expression(alpha[i]) }

I was able to hack together the below programmatic solution that appears to produce the desired result thanks to this post:

   ggplot(df, aes(x = value, y = name)) + geom_density() +
       scale_y_discrete(labels = parse(text = paste("alpha[", 1:length(unique(df)), "]")))

However, I do not understand this code and am seeking clarification about:

  1. What is parse() doing here that expression() otherwise would do?
  2. While I understand everything to the right-hand side of =, what is text doing on the left-hand side of the =?
socialscientist
  • 3,759
  • 5
  • 23
  • 58
  • 1
    Check the documentation on [parse](https://www.rdocumentation.org/packages/base/versions/3.6.2/topics/parse) out. – Adam Quek Jul 13 '22 at 07:00

1 Answers1

3

Another option to achieve your desired result would be to add a new column to your data which contains the ?plotmath expression as a string and map this new column on y. Afterwards you could use scales::label_parse() to parse the expressions:

set.seed(123)

df <- data.frame(name = rep(c("alpha1","alpha2"), 50),
                 value = rnorm(100))
df$label <- gsub("^(.*?)(\\d+)$", "\\1[\\2]", df$name)

library(ggplot2)
library(scales)

ggplot(df, aes(x = value, y = label)) + geom_density() +
  scale_y_discrete(labels = scales::label_parse())

stefan
  • 90,330
  • 6
  • 25
  • 51
  • While this is helpful, it does not directly address the questions. If you add an answer to (1) and (2) then I can accept. I'm still not sure about the difference between parse(text=foo) vs. expression(foo) here - is it just that parse returns a list of unevaluated expressions? I missed the "text" argument in parse() documentation previously so (2) is clear. – socialscientist Jul 14 '22 at 05:17