Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

creating subscripts inside scale_x_discrete

Tags:

r

ggplot2

df <- data.frame(a=c(1,2,3,4,5,6), 
                 b=c("x1","x2","y1","y2","w1","w2"), 
                 c=runif(6), 
                 d=c(1,1,2,2,3,3))
p <- ggplot(aes(x=b, y=c), data=df) + 
  geom_bar(stat="identity") + 
  facet_grid(~d, scales="free_x") 

I'd like to use expression (or any other function) in order to create subscripts for each label. I tried this:

new_labels <- c(expression("x[1]"),expression("x[2]"),expression("y[1]"),expression("y[2]"),expression("w[1]"),expression("w[2]"))
p + scale_x_discrete(labels=new_labels) 

and this

new_labels2 <- c("x[1]","x[2]","y[1]","y[2]","w[1]","w[2]")
p + scale_x_discrete(labels=function(new_labels2) expression(new_labels2))

but none of these solutions gave me the intended result.

Also how can I change the bar colors to be the same in all facets?

I thought p + scale_fill_manual(values=c("green","red")) would work, but it has no effect.

like image 971
HappyPy Avatar asked Dec 20 '25 19:12

HappyPy


1 Answers

You can provide a function to the labels argument of scale_x_discrete to generate the expressions as strings and then parse the strings to have them interpreted as expressions. In the example below I've also added fill=grepl("1", b) which will map column b to the fill aesthetic based on whether there's a 1 or not in the value of b. This mapping is necessary to generate fill colours that can then be set with scale_fill_manual.

p = ggplot(aes(x=b, y=c, fill=grepl("1", b)), data=df) + 
  geom_bar(stat="identity") + 
  facet_grid(~d, scales="free_x") +
  guides(fill=FALSE) +
  scale_x_discrete(labels=function(l) parse(text=gsub("(.)([0-9])", "\\1[\\2]", l)))

p

enter image description here

For illustration, below is what the gsub function is doing to generate the strings before they're parsed as expressions (basically just doing programmatically what you hard-coded in your question):

p <- ggplot(aes(x=b, y=c, fill=grepl("1", b)), data=df) + 
  geom_bar(stat="identity") + 
  facet_grid(~d, scales="free_x") +
  guides(fill=FALSE) +
  scale_x_discrete(labels=function(l) gsub("(.)([0-9])", "\\1[\\2]", l))

p

enter image description here

The gsub function uses regular expressions to do the substitutions. If you're not familiar with regular expressions, another, perhaps less opaque way to code this would be:

function(l) paste0(substr(l,1,1), "[", substr(l,2,2), "]")

If you want to set your own fill colours, you could do:

p + scale_fill_manual(values=c("green","red")) 

In reference to the question in your comment: You can create a dummy grouping variable as follows:

library(tidyverse)

p <- df %>% 
  group_by(b.grp = substr(b, 1, 1)) %>% 
  mutate(grp.val = 1:n()) %>% 
  ggplot(aes(x=b, y=c, fill=factor(grp.val))) + 
    geom_bar(stat="identity") + 
    facet_grid(~d, scales="free_x") +
    guides(fill=FALSE) +
    scale_x_discrete(labels=function(l) parse(text=gsub("(.)(.)", "\\1[\\2]", l)))
like image 86
eipi10 Avatar answered Dec 23 '25 07:12

eipi10



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!