ggplot2 and gridExtra: completely remove strip in facet_grid - not just invisible

Claire Armstrong picture Claire Armstrong · Jun 17, 2013 · Viewed 8.4k times · Source

I have two graphs that I'm placing one above the other, in the following way:

library(ggplot2)
library(gridExtra)
p1 <- ggplot(mtcars, aes(mpg, wt)) + geom_point()
p2 <- ggplot(mtcars, aes(mpg, wt)) + geom_point()
p2 <- p2 + facet_grid(cyl ~ .)
grid.arrange(p1, p2, ncol=1)

For this I need the x axes of the top and bottom graphs to line up, however because of the strip to the left, the faceted graph is narrower than the top graph. I can make the strip invisible using:

theme(strip.text.y = element_blank())
theme(strip.background = element_blank())

However this does not get rid of the space that the strip takes up. So I either need a way to get rid of the strip entirely, or have a way to split my faceted graph into separate graphs, yet somehow sharing the same y-axis label across them. In my graph I have two faceted panels that are not very tall, and there isn't enough space for them to each have a decent-sized y-axis.

Any suggestions?

Answer

Simon O&#39;Hanlon picture Simon O'Hanlon · Jun 17, 2013

My solution would be to find the width of the strip and then set the margins of both plots to be zero, but shrink the one without the strip to be slightly smaller (the width of the strip) so they appear to be the same size. By trial and error it seems the strip is about 0.5 lines wide (but I guess you could figure this out programatically). Therefore just make sure the right plot margin in the plot without the strip text is 0.5 lines greater than the one with the invisible strip:

#  Add a line of width 0.5 on the left but set all other margins to zero
p1 <- p1 + theme( plot.margin = unit( c(0,0.5,0,0) , units = "lines" ) )
#  Set all margins to zero, the strip will take up a phantom amount of invisible space
p2 <- p2 + theme(strip.text.y = element_blank() , 
  strip.background = element_blank(),
  plot.margin = unit( c(0,0,0,0) , units = "lines" ) )

grid.arrange(p1, p2, ncol=1)

Obviously you can adjust the margins as you wish (e.g. add 1 to the first position in each numeric vector in plot.margin to get a border of one line along the top of each plot), as long as you keep 0.5 lines more margin in the right border of the second plot they will look the same.

enter image description here