Anke
Anke

Reputation: 651

Make ggplot panels the same height in ggarrange

I have two ggplots that I'm combining with ggarrange(). One plot has long labels, that I wrap with scale_x_discrete(labels = function(x) str_wrap(x, width = 10)), where str_wrap() is from the stringr package. However, when I combine them, the first panel is reduced in height to accommodate for the space required by the wrapped labels. I already tried all kinds of variations of adjusting the margins both in theme(plot.margin = margin()) as well as axis.text.x=element_text(margin = unit(c(), "cm")), to no avail. I'm probably missing something very obvious, but I just can't get the panels to match in height, regardless of how much space is needed by the axis labels.

Thanks!

plot1 <- ggplot(data=dat, aes(x=x, y=y)) +
  theme_bw() +
  geom_point(size=2) +
  labs(x='', y='', title='') +
  scale_x_discrete(labels = function(x) str_wrap(x, width = 10))

plot2 <- ggplot(data=dat, aes(x=x2, y=y2)) +
  theme_bw() +
  geom_point(size=2) +
  labs(x='', y='', title='') 

ggarrange(plot1, plot2, ncol=2)

ggarrange plot

Upvotes: 0

Views: 3195

Answers (2)

Mick
Mick

Reputation: 121

it's doable within ggarrange using the argument align.

Here using the iris example from above

# The plots
plot1 <- ggplot(iris, aes(x = Species, y = Sepal.Length)) +
  geom_boxplot() +
  scale_x_discrete(labels = c("setosa" = "Setosa", "versicolor" = "Versicolor", "virginica" = "A very long name for \n Vircinica just to reproduce \n the problem"))
plot2 <- ggplot(iris, aes(x = Sepal.Length, fill = Species)) +
  geom_density(alpha = 0.8) + theme(legend.position = "none")

Default:

ggarrange(plot1, plot2, ncol = 2)

link to unaligned plots

With align:

ggarrange(plot1, plot2, ncol = 2, align = "h")

link to aligned plots

Apparently, I'm not allowed to post images so you'll have to click on the link or run the code.

Hope that helps!

Upvotes: 3

Gnueghoidune
Gnueghoidune

Reputation: 1357

One option to stick with ggarrange is to adjust the heights of your plots. To illustrate the case with iris data:

plot1 <- ggplot(iris, aes(x = Species, y = Sepal.Length)) +
  geom_boxplot() +
  scale_x_discrete(labels = c("setosa" = "Setosa", "versicolor" = "Versicolor", "virginica" = "A very long name for \n Vircinica just to reproduce \n the problem"))

plot2 <- ggplot(iris, aes(x = Sepal.Length, fill = Species)) +
  geom_density(alpha = 0.8) + theme(legend.position = "none")

ggarrange(plot1, plot2, ncol = 2)

enter image description here

You can then use ggplotGrob and grid::unit.pmax to get the same hight for both plots:

pg1 <- ggplotGrob(plot1)
pg2 <- ggplotGrob(plot2)

maxHeight = grid::unit.pmax(pg1$heights, pg2$heights)
pg1$heights <- as.list(maxHeight)
pg2$heights <- as.list(maxHeight)

ggarrange(pg1, pg2, ncol = 2)

enter image description here

Upvotes: 2

Related Questions