Search code examples
rggplot2axis-labels

Add multiple level x-label in ggplot2


How would I place a x-label on multiple lines in ggplot 2. I am aware that I would use mtext as illustrated below to do this in base plot, but what would be an equivalent way to create a similar x-axes label in ggplot2?

enter image description here

Minimum working example:

# List containing the expressions for the x-axes
xaxeslist = list(bquote("Low" %<-% "Complexity" %->% "High"), 
               bquote("High" %<-% "Bias" %->% "Low"),
               bquote("Low" %<-% "Variance" %->% "High"))

# In base R one would use mtext to plot the desired x-label values
# mtext(do.call(expression, xaxeslist), side = 1, line = 2:4)


# Dummy values for working example
xval = seq(0, 100, by = 0.001)
yval = seq(0, 100, by = 0.001)
data <- data.frame("x"=xval,"y"=yval)

# Plot the desired output
b<-ggplot(data) +
  aes(x = x, y = y) +
  geom_line(size = 1L) +
  labs(
    x = do.call(expression, xaxeslist),
    y = "Y-value",
    title = "Title"
  ) +
  theme(axis.ticks.x = element_blank(),
        axis.text.x = element_blank(),
        axis.ticks.y = element_blank(),
        axis.text.y = element_blank())

print(b)

enter image description here

I would like to manipulate the x-label so that it falls onto multiple lines as the figure above, i.e. so that xaxeslist becomes the xlabel.


Solution

  • atop function is an answer, it enables you to have a two lines expression in your xlab of ggplot without difficulities :

    ggplot(data) +
        aes(x = x, y = y) +
        labs(x = expression(atop("Low" %<-% "Complexity" %->% "High",
                                 "High" %<-% "Bias" %->% "Low"))
             )
    

    first

    However, it is not easy to obtain a three lines expression with such a strategy, one solution is :

    ggplot(data) +
        aes(x = x, y = y) +
        labs(x = expression(atop(atop(textstyle("Low" %<-% "Complexity" %->% "High"),
                                     textstyle("High" %<-% "Bias" %->% "Low")),
                                "Low" %<-% "Variance" %->% "High")),
            y = "Y-value",
            title = "Title"
        )
    

    second

    Although not without faults because of a too large space between the second and the third line !