2

I am attempting to arrange multiple ggplot2 plots into one output/grid. I'd like the plots (without considering the labels) to be the same size. I have found a way to do this, but now I'd like to adjust the space between the plots.

For example: example plots with default spacing

In this plot, I'd like to reduce the amount of space between the two plots. I've tried adjusting margins, removing ticks, etc. This has removed some of the space.

example plots with reduced space between plots

Is there a way to have more control of the spacing adjustment between plots in situations such as these?

library(MASS)
data(iris)
library(ggplot2)
library(grid)
library(gridExtra)

p1 <- ggplot(iris,aes(Species,Sepal.Width))+geom_violin(fill="light gray")+geom_boxplot(width=.1) +coord_flip() +
  theme(axis.title.y = element_blank()) + ylab("Sepal Width")

p2 <- ggplot(iris,aes(Species,Petal.Width))+geom_violin(fill="light gray")+geom_boxplot(width=.1) + coord_flip() +
  theme(axis.title.y = element_blank(), axis.text.y=element_blank()) + ylab("Petal Width")


p11 <- p1 + theme(plot.margin = unit(c(-0.5,-0.5,-0.5,-0.5),"mm"))
p22 <- p2 + theme(plot.margin = unit(c(-0.5,-0.5,-0.5,-0.5),"mm"),  axis.ticks.y=element_blank())


# https://stackoverflow.com/questions/24709307/keep-all-plot-components-same-size-in-ggplot2-between-two-plots
# make plots the same size, even with different labels
gl <- lapply(list(p11,p22), ggplotGrob)
widths <- do.call(unit.pmax, lapply(gl, "[[", "widths"))
heights <- do.call(unit.pmax, lapply(gl, "[[", "heights"))
lg <- lapply(gl, function(g) {g$widths <- widths; g$heights <- heights; g})

# https://stackoverflow.com/questions/1249548/side-by-side-plots-with-ggplot2-in-r?lq=1
grid.arrange(lg[[1]],lg[[2]], ncol=2) #in gridExtra
Community
  • 1
  • 1
nofunsally
  • 2,051
  • 6
  • 35
  • 53

1 Answers1

2

You have set the 'widths' to be the maximums of the two plots. This means that the widths for the y-axis of the 'Petal Widths' plot will be the same as the widths of the y-axis of the 'Sepal Widths' plot.

One way to adjust the spacing is, first, to combine the two grobs into one layout, deleting the y-axis and left margin of the second plot:

# Your code, but using p1 and p2, not the plots with adjusted margins
gl <- lapply(list(p1, p2), ggplotGrob)
widths <- do.call(unit.pmax, lapply(gl, "[[", "widths"))
heights <- do.call(unit.pmax, lapply(gl, "[[", "heights"))
lg <- lapply(gl, function(g) {g$widths <- widths; g$heights <- heights; g})

# New code
library(gtable)
gt = cbind(lg[[1]], lg[[2]][, -(1:3)], size = "first")

Then the width of the remaining space between the two plots can be adjusted:

gt$widths[5] = unit(2, "lines")

# Draw the plot
grid.newpage()
grid.draw(gt)
Sandy Muspratt
  • 31,719
  • 12
  • 116
  • 122
  • So this portion of the code `[, -(1:3)], size = "first")` is deleting the y-axis and left margin of second plot? And then `gt$widths` is determining the widths of the columns for the cbinded plot? – nofunsally Jun 08 '15 at 16:11
  • @nofunsally, Correct and correct. The layout can be checked at any time with `gtable_show_layout (x)`. – Sandy Muspratt Jun 08 '15 at 21:00