32

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

Tyler Rinker
  • 108,132
  • 65
  • 322
  • 519
  • I would have guessed you could use the four arguments for top, right, bottom and left margin but you can't. Bummer. – Luciano Selzer Sep 03 '12 at 19:26
  • 1
    @lselzer, I thought so too, but I think that option is only for `plot.margin`. This feature [was asked about](https://groups.google.com/d/topic/ggplot2/tMQsVb5P69s/discussion) a year ago, with the answer to its availability being "not at present". – A5C1D2H2I1M1N2O1R2T1 Sep 03 '12 at 19:52
  • 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 Sep 06 '12 at 14:08
  • 6
    Submitted an issue requesting this: https://github.com/hadley/ggplot2/issues/678 – Brian Diggs Oct 02 '12 at 16:14

2 Answers2

44

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"))
M--
  • 25,431
  • 8
  • 61
  • 93
Dave
  • 456
  • 5
  • 2
9

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

Julius Vainora
  • 47,421
  • 9
  • 90
  • 102