Reputation: 470
I'm trying to use gridExtra to combine two ggplot2 bar plots (with coordinates flipped so that the labels take up horizontal space). The problem is that some of the labels are short and some are long. I want the width of the left and right columns to be the same, irrespective of the width of the labels. Here's an example:
library(ggplot2)
library(gridExtra)
datashort <- data.frame(ecks = c("Short1", "Short2", "Short3"), why = c(30, 20, 40))
datalong <- data.frame(ecks = c(paste0("Really, Really, Really, Really Long", c(1:3))),
why = c(20, 30, 40))
plotshort <- ggplot(data = datashort, aes(x = ecks, y = why, width = .5)) +
geom_bar(stat = "identity") +
scale_y_continuous(breaks = c(10, 20, 30, 40, 50), limits = c(0, 50)) +
coord_flip()
plotlong <- ggplot(data = datalong, aes(x = ecks, y = why, width = .5)) +
geom_bar(stat = "identity") +
scale_y_continuous(breaks = c(10, 20, 30, 40, 50), limits = c(0, 50)) +
coord_flip()
grid.arrange(plotshort, plotlong, ncol = 2)
If you do that, you get a really wide left chart and a really squished right chart. I know that you can add widths to the grid arrange, but I'd like to know exactly what they should be. Here it looks like widths=c(.4, .6) works pretty well, but it's not exact. Also, you have to use trial and error to get there, which isn't ideal. Is there any way to figure out what the actual plot area is so that you can calculate the right widths?
Upvotes: 3
Views: 1389
Reputation: 76
You can wrap the labels using stringr
and modify your ggplot2
script to define your labels in st_wrap
and plot as scale_x_discrete
:
library(stringr)
plotshort <- ggplot(data = datashort, aes(x = ecks, y = why, width = .5)) +
geom_bar(stat = "identity") + coord_flip() +
scale_x_discrete(labels = str_wrap(c("Short1", "Short2", "Short3"), width = 10))
plotlong <- ggplot(data = datalong, aes(x = ecks, y = why, width = .5)) +
geom_bar(stat = "identity") + coord_flip() +
scale_x_discrete(labels = str_wrap(c("Really, Really, Really, Really Long1", "Really, Really, Really, Really Long2", "Really, Really, Really, Really Long3"), width = 10))
grid.arrange(plotshort, plotlong, ncol = 2)
Upvotes: 0
Reputation: 8110
One very simple solution would be to use cowplot
:
cowplot::plot_grid(plotshort, plotlong, ncol = 2,align = "v")
The argument align
allows you to set the plot areas equal.
Or another option would be to add some breaks to the titles:
library(stringr)
plotlong <- datalong %>%
mutate(ecks = str_replace_all(ecks, "[[:punct:]]\\s|\\s", "\\\n")) %>%
ggplot(aes(x = ecks, y = why, width = .5)) +
geom_bar(stat = "identity") +
scale_y_continuous(breaks = c(10, 20, 30, 40, 50), limits = c(0, 50)) +
coord_flip()
cowplot::plot_grid(plotshort, plotlong, ncol = 2,align = "v")
If you add the breaks, then you could use grid.arrange
grid.arrange(plotshort, plotlong, ncol = 2)
Upvotes: 3