lep
lep

Reputation: 67

How can I move the legend position with grid.arrange

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:

enter image description here

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

Answers (2)

Habib Karbasian
Habib Karbasian

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)))

enter image description here

Upvotes: 0

user20650
user20650

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

enter image description here

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)))

enter image description here

Upvotes: 5

Related Questions