Reputation: 67
I´m trying to arrange 4 plots in a page, placing the legend in the bottom center
I used this to get the legends from one of the plots (as they will be the same for the four plots)
get_legend<-function(myggplot){
tmp <- ggplot_gtable(ggplot_build(myggplot))
leg <- which(sapply(tmp$grobs, function(x) x$name) == "guide-box")
legend <- tmp$grobs[[leg]]
return(legend)
}
then, I get the legend from any of the plots
legend <- get_legend(p2)
so for the figure I used:
tt <-grid.arrange(arrangeGrob(p6, p7, p8, p9, legend,
nrow = 2, #
left = textGrob("Mammalian species richness", rot = 90, vjust = 1,
gp = gpar(fontsize = 12))))
but what I´ve got is this:
How can I move the legend to the center button and have 2rows 2 columns?
commands nrow
, ncol
did not work as I received an error message, neither something like
tt <- tt + theme(legend.position ="bottom").
ps. just in case this info is important, if I attempt not to place any legend I could have the four plots in a grid as I want, but without legends, so, you understand is not good for publication.
Upvotes: 5
Views: 11747
Reputation: 666
To complement user20650
's answer and to answer the OP completely, I have plotted the same plot four times but I addressed the question.
To be able to use the following code, you need to have cowplot
and ggpubr
package installed for gridExtra
formatting.
Although the OP has a function to get the legend information, I encountered some issues with it so I had to use cowplot
.
For layout_matrix
format, please refer to this page.
library(cowplot)
library(ggplot2)
library(gridExtra)
library(ggpubr)
p = ggplot2::ggplot(mtcars, aes(mpg, wt, col = factor(am))) +
ggplot2::geom_point() +
scale_color_discrete(name = "Car Type", labels=c("fast", "slow"), ) +
labs(x = '', y = '') +
ggtitle('Car') +
theme_bw() +
theme(plot.title = element_text(size = 8, hjust = 0.5),
axis.text.x = element_text(angle = 30, hjust = 1),
legend.position = 'top')
legend = cowplot::get_legend(p)
p = p + ggplot2::theme(legend.position = 'none')
gridExtra::grid.arrange(grobs = list(p, p, p, p, legend),
left = ggpubr::text_grob("Width",
rot = 90,
vjust = 1),
bottom = ggpubr::text_grob("Mile Per Gallon",
rot = 0,
vjust = 0),
layout_matrix = rbind(c(5, 5),
c(1, 2),
c(1, 2),
c(1, 2),
c(1, 2),
c(1, 2),
c(1, 2),
c(1, 2),
c(3, 4),
c(3, 4),
c(3, 4),
c(3, 4),
c(3, 4),
c(3, 4),
c(3, 4)))
Upvotes: 0
Reputation: 25854
You can use the argument layout_matrix
in grid.arrange
for more control.
A reproducible example,
library(ggplot2)
library(gridExtra)
get_legend<-function(myggplot){
tmp <- ggplot_gtable(ggplot_build(myggplot))
leg <- which(sapply(tmp$grobs, function(x) x$name) == "guide-box")
legend <- tmp$grobs[[leg]]
return(legend)
}
p <- ggplot()
p2 <- ggplot(mtcars, aes(mpg, wt, col=factor(am))) + geom_point()
legend <- get_legend(p2)
grid.arrange(p, p, p, p, legend,
layout_matrix=rbind(c(1,2,3), c(4,5,5)))
Which produces
Or perhaps you want
grid.arrange(p, p ,p, p, legend,
layout_matrix=rbind(c(1,1,2,2,5), c(3,3,4,4,5)))
Upvotes: 5