5

I would like to manually (or automatically) alter the panel layout of a faceted graph of a ggplot2 graphic in R. I have seen solutions to annotations and reordering of Facets, but not this specific question. Here is a reproducible example:

library(ggplot2)
plot <- ggplot(diamonds, aes(carat, price)) + facet_wrap(~cut) + geom_point()

If I look at the plot now, you see that the blank facet is allocated in the bottom right corner of the plot grid.

enter image description here All I want to do is make the blank plot location be in the top left corner instead, but still plot all the other plots (just move the blank plot location).

I've tried looking at ggplot_build() as such:

plot_build <- ggplot_build(plot)
plot_build$panel$layout

but I can't figure out how to actually move the blank plot location to the correct row and column. Does anyone have any ideas?

user20650
  • 24,654
  • 5
  • 56
  • 91
sjfox
  • 112
  • 2
  • 10
  • shouldn't the top right panel be moved to bottom left and the other two along the bottom shifted over one panel? the panels in the answer below are out of order no matter which way you read them – rawr May 02 '16 at 20:17
  • @rawr i also wonder what happened to the x axis in the last column. Is that a recent ggplot2 feature? – baptiste May 02 '16 at 20:23
  • 1
    @baptiste it doesn't show up in < 2.0 either without free_x scales, and if you use your answer the axis doesn't move down with the plot. but I don't remember it ever not showing up in the past. however, I used something like [this](http://stackoverflow.com/questions/13297155/add-floating-axis-labels-in-facet-wrap-plot) for the axes – rawr May 02 '16 at 20:37
  • @rawr I accepted the answer, because it showed me how to move the panels, even though it didn't move all of the panels as explicitly specified. This was just an example, and the solution lead me to get the correct output out of my actual figure. – sjfox May 02 '16 at 21:41

1 Answers1

8

You could move panels in the gtable,

library(grid)
library(ggplot2)

p <- ggplot(diamonds, aes(carat, price)) + 
      facet_wrap(~cut) + geom_point()

g <- ggplotGrob(p)

gl <- g$layout
idcol <- gl$r == (ncol(g)-2)
g$layout[idcol & gl$b < 5, c("t", "b")] <- gl[idcol & gl$b < 5, c("t", "b")] + 4
grid.newpage()
grid.draw(g)

enter image description here

baptiste
  • 75,767
  • 19
  • 198
  • 294
  • Awesome, this is exactly what I was looking for, thank you! Would you mind explaining what the layout columns stand for (or is there a website you could point me to)? – sjfox May 02 '16 at 20:13
  • 1
    unfortunately there is no documentation, it's a game of trial and error, and subject to random changes at each package update. I once started an intro doc on the [gridextra wiki though](https://github.com/baptiste/gridextra/wiki/gtable) – baptiste May 02 '16 at 20:21
  • That's unfortunate, but no worries I'll play around with it. Thank you so much @baptiste! – sjfox May 02 '16 at 20:25