Search code examples
rggplot2font-face

Two font faces in ggplot labels


I am trying to create a bar plot with two font faces for the y labels (don't confuse: it's called x due to coord_flip()). However, I have not found any solution for this on the internet.

Is it even possible?

I've got this so far.

library(ggplot2)

labs <- paste(rep("1st", 40), rep("2nd", 40), rep("3rd", 40))
labs <- strsplit(labs, " ")

v1 <- ggplot(data.frame(x = 1:40, y = 1:40), aes(x,y)) + 
  geom_bar(stat = "identity", fill = "grey50") + 
  coord_flip() + 
  scale_x_discrete(labels = paste(sapply(labs, "[[", 1), 
                                  .(bold(.(sapply(labs, "[[", 2)))),
                                  sapply(labs, "[[", 3)), 
                   breaks = 1:40)
v1

I want to be the 2nd in all ylabs as bold face. Yet, I get this: enter image description here

The tick labels should look like this ([=====] indicate the bars in the plot):

1st 2nd 3rd [================================]

1st 2nd 3rd [=============================]

1st 2nd 3rd [==========================]

...


Solution

  • minimal example

    You have to define an expression.

    library(ggplot2)
    
    all.data <- data.frame(group=c('a','b'),count=c(5,8))
    
    ggplot(data=all.data, aes(group, count)) + 
      geom_bar(stat = "identity") + 
      scale_x_discrete(label=c( expression(paste("xxx",bold("foo"))), expression(paste("yyy",bold("bar")))  ))
    

    enter image description here

    example using variables

    A post here on stackoverflow got me on the right track: Use expression with a variable r

    labs <- paste(rep("1st", 40), rep("2nd", 40), rep("3rd", 40))
    labs <- strsplit(labs, " ")
    
    # create a vector of expressions
    # everything in .() is evaluated and ~ forms an expression
    plot.labs <- bquote( .(labs[[1]][1]) ~ bold(.(labs[[1]][2])) ~ .(labs[[1]][3]))
    
    # produce a list of expressions
    plot.labs.apply <- lapply(labs, function(x) {plot.labs <- bquote( .(x[1]) ~ bold(.(x[2])) ~ .(x[3]))})
    
    # was it done correctly?
    class(plot.labs.apply[[2]])
    
    # i used a smaller data frame to not overload the plot
    ggplot(data.frame(x = c('a','b'), y = c(40,25)), aes(x,y)) + 
        geom_bar(stat = "identity", fill = "grey50") + 
        coord_flip() + 
        scale_x_discrete(label = c(plot.labs.apply) )
    

    enter image description here