30
votes

ggplot2 has the ability to change the margins between a faceted plot using the argument panel.margin in opts. This seems to change both horizontal and vertical spacing. Is there a way to change the spacing of either horizontal or vertical without changing the other?

An example with outcome and desired outcome:

mtcars[, c("cyl", "am", "gear")] <- lapply(mtcars[, c("cyl", "am", "gear")], as.factor)

p <- ggplot(mtcars, aes(mpg, wt, group = cyl)) + 
    geom_line(aes(color=cyl)) +
    geom_point(aes(shape=cyl)) + 
    facet_grid(gear ~ am) +
    theme_bw()        

p + opts(panel.margin = unit(1, "lines")) 

So it currently looks like:enter image description here

How can we make it look more like:enter image description here

2
I would have guessed you could use the four arguments for top, right, bottom and left margin but you can't. Bummer.Luciano Selzer
@lselzer, I thought so too, but I think that option is only for plot.margin. This feature was asked about a year ago, with the answer to its availability being "not at present".A5C1D2H2I1M1N2O1R2T1
Since the ggplot2 0.9.2 now replaces opts with theme and you can move some things independent of another (ie panel.grid.major.y etc) I figured this may work to use: theme(panel.margin.x = unit(1, "lines")) but it does not.Tyler Rinker
Submitted an issue requesting this: github.com/hadley/ggplot2/issues/678Brian Diggs

2 Answers

39
votes

As of July 9th, 2015, the panel.margin.x and panel.margin.y seem to have been implemented

p <- p + theme(panel.margin.x=unit(0.5, "lines") , panel.margin.y=unit(1,"lines"))

As of December 15, 2016, 'panel.spacing' and 'panel.spacing.x' is implemented in r 3.3.2 and ggplot2 2.2.0

p <- p + theme(panel.spacing.x=unit(0.5, "lines"),panel.spacing.y=unit(1, "lines"))
9
votes

A manual solution until this feature becomes available:

library(grid)
height <- 0.5 # Vertical spacing
aux <- 1e-5 # Auxiliary number to identify 'height' among other heights
width <- 0.1 # Desirable horizontal spacing

p <- p + theme(panel.margin = unit(height + aux, "lines"))

gtable <- ggplot_gtable(ggplot_build(p))
gtable$widths[sapply(gtable$widths, '[[', 1) == height + aux][[1]][[1]] <- width
grid.draw(gtable)

enter image description here