Search code examples
rggplot2labelfacet

Order nested facet labels in facet_grid


So, I am trying to make a grid of plots that are faceted by three different variables. I can generate the grid of plots just fine, the only hitch I am having is that the order in which the labels is placed seems out of order. Here is a simple example of what I am doing:

library(ggplot2)
data(mtcars)
qplot(mpg, wt, data=mtcars) + facet_grid(cyl +am ~ vs, labeller = label_both)

which produces the following plot:

enter image description here

Now, for the most part, the plot looks great, but for the labels on the right hand side, we see that cyl is labeled "first" (i.e. close to the plot) and am is nested outside, but the way the plot is laid out, it is clear that the facets are displayed with am nested within cyl.

So, I would like to change the order that the labels are listed so that am levels are listed within cyl levels to reflect the layout. I have tried to search for things like "facet_grid order labels" or "nested facet label order ggplot2", but almost all of the results I found had to do with changing the order of the actual levels of a given facet, rather than the problem I have described. Additionally, I looked into tinkering with the labeller, but that function seems to be called after the placement of the labels has been decided.

Thanks for your help!


Solution

  • It seems that the ordering of the labels that you see is just the standard way how ggplot orders the labels. If you exchange the order of the variables in the formula, the labels also change position, but this at the same time also reorders the rows, which is probably not what you want:

    qplot(mpg, wt, data=mtcars) +
        facet_grid(am + cyl ~ vs, labeller = label_both)
    

    enter image description here

    You can indeed use the labeller to fix this, as was suggested by alistaire. The following function calls label_both() with the columns of the label data frame in reversed order:

    label_rev <- function(labels, multi_line = TRUE, sep = ": ") {
      label_both(rev(labels), multi_line = multi_line, sep = sep)
    }
    

    And it leads to the desired result:

    qplot(mpg, wt, data=mtcars) +
        facet_grid(cyl + am ~ vs, labeller = label_rev)
    

    enter image description here