0

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

Anke
  • 527
  • 1
  • 6
  • 19
  • 1
    You could try this? https://stackoverflow.com/a/53274897/2966246 – phalteman Mar 22 '22 at 20:06
  • If other packages are an option for you then have a look at `patchwork` which does a great job in aligning plots. – stefan Mar 22 '22 at 20:08
  • 1
    ```Patchwork``` is brilliant! Thank you for sharing. If you add it as an answer, I'll select it as the accepted ~. @Gnueghoidune answer works perfectly as well, but ```patchwork``` makes it so much cleaner and easier. – Anke Mar 23 '22 at 02:28

2 Answers2

3

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!

Quinten
  • 35,235
  • 5
  • 20
  • 53
Mick
  • 81
  • 4
1

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

Gnueghoidune
  • 1,237
  • 4
  • 13