Add Common Legend to Combined ggplot2 Plots in R (Example)


In this article, I’ll illustrate how to create a shared legend for multiple ggplot2 graphics in the R programming language.

Table of contents:

Let’s get started…


Example Data

In the example of this R tutorial, we’ll use the following example data frames:

# Create example data
data1 <- data.frame(x = round(runif(2000), 2),
                    y = round(runif(2000), 2),
                    group = c(rep("A", 1000), rep("B", 1000)))
data2 <- data.frame(x = round(rnorm(2000), 2),
                    y = round(rnorm(2000), 2),
                    group = c(rep("A", 1000), rep("B", 1000)))

The previous R code creates two data frames. Both of these data frames contain the three columns x, y, and a grouping variable.

Furthermore, we need to install and load the ggplot2 and gridExtra packages:

# Install and load packages

Now, we can move on to the plotting of the data…


Example: How to Add a Shared Legend to GGplots in R

As a first step, we need to create two (or more) plots with the ggplot package. The following R syntax stores two ggplot2 graphics in the data objects ggp1 and ggp2. Note that these two plots do not show a legend:

# Create two plots without legends
ggp1 <- ggplot(data1, aes(x = x, y = y, group = group, col = group)) +
  geom_point() +
  theme(legend.position = "none")
ggp2 <- ggplot(data2, aes(x = x, y = y, group = group, col = group)) +
  geom_point() +
  theme(legend.position = "none")

Now, we need to create one of these plots again, but this time with the legend that we want to show later on in the side-by-side graphic. In this case we are creating a legend at the bottom of the plots. However, you may modify this legend to your specific needs.

# Create plot with legend
ggp1_legend <- ggplot(data1, aes(x = x, y = y, group = group, col = group)) +
  geom_point() +
  theme(legend.position = "bottom")

Next, we define our own function, which enables us to extract the legend of the previously created plot. Note that the code for this function is based on this Stack Overflow thread.

# Create user-defined function, which extracts legends from ggplots
extract_legend <- function(my_ggp) {
  step1 <- ggplot_gtable(ggplot_build(my_ggp))
  step2 <- which(sapply(step1$grobs, function(x) x$name) == "guide-box")
  step3 <- step1$grobs[[step2]]

We can now apply our function to our ggplot as follows:

# Apply user-defined function to extract legend
shared_legend <- extract_legend(ggp1_legend)

Our legend is now stored in the data object shared_legend. In order to draw our two plots side-by-side and in order to add a common legend, we can use the grid.arrange and arrangeGrob functions of the gridExtra package:

# Draw plots with shared legend
grid.arrange(arrangeGrob(ggp1, ggp2, ncol = 2),
             shared_legend, nrow = 2, heights = c(10, 1))

Figure 1 illustrates the output of the previous R code. As you can see, we created a graph with a shared legend below the two plots.


shared legend ggplot2 plot in r

Figure 1: Two ggplot2 Plots with a Common Legend in R.


In this example, we created a common legend for two scatterplots. However, please note that we could also use other types of ggplots (e.g. barplots, heatmaps, line graphs, boxplots, and so on…) and we could use any amount of plots we want.


Video, Further Resources & Summary

Do you want to know more about the creation of shared legends in grid-plots? Then you may want to watch the following video of my YouTube channel. In the video, I’m explaining the topics of this article.


Please accept YouTube cookies to play this video. By accepting you will be accessing content from YouTube, a service provided by an external third party.

YouTube Content Consent Button Thumbnail

YouTube privacy policy

If you accept this notice, your choice will be saved and the page will refresh.


Furthermore, you might want to have a look at some of the other tutorials of Some other tutorials are shown below:


In this tutorial you learned how to share a legend for multiple combined ggplot2 plots in R programming. Don’t hesitate to tell me about it in the comments section, in case you have further questions.


Subscribe to the Statistics Globe Newsletter

Get regular updates on the latest tutorials, offers & news at Statistics Globe.
I hate spam & you may opt out anytime: Privacy Policy.

8 Comments. Leave new

  • Excellent on the legend extraction. What would be the code to have the legend at the top? I have manipulated the provided code but no luck

    • Hi Tim,

      Thanks for the great question! You would have to modify the grid.arrange() code as follows:

                   arrangeGrob(ggp1, ggp2, ncol = 2),
                   nrow = 2, heights = c(1, 10))

      I hope that helps!


  • Thank you so much for code to get the legend at the top of the Grob. However, I am having trouble creating the Grob for exporting to a PNG file. Here is code I am using:
    P3<-(arrangeGrob(shared_legend, P1 + theme(legend.position="none"), P2, ncol = 3), heights = c(0.5, 10))

    I get the error stating ("Unexpected token ','"). I think the code does not like the "," after shared_legend

    I am creating the P3 file so that I can export the PNG file with this code
    ggsave(P3,file="c:/destination/P3.png", width=9.5, height=6.5)

    Please advise. Unless you have a different method to export the Grob as a PNG file?

  • Muhammad Usman
    December 30, 2020 7:26 pm

    Dear Joan, Thank you for your tutorial for making singlle ledend for multiple figures. It is good for discrete values. How to modify this code, If I have continous values inform of matrices and I want to make single legends for two different matrices have different scale range.

  • Hi Joachim,
    thank you so much for your helpful tutorial video on how extracting the legend. Is it possible to modify your code to put the legend on the right of the graphs?

    • Hey Farzaneh,

      Thanks a lot, glad you like it!

      Yes, this is possible. You have to remove this line of code when creating the legend:

      theme(legend.position = "bottom")


      ggp1_legend <- ggplot(data1, aes(x = x, y = y, group = group, col = group)) +

      And then you have to modify the last line of code when creating the final graphic:

      grid.arrange(arrangeGrob(ggp1, ggp2, shared_legend, ncol = 3, widths = c(2, 2, 1)))

      I hope that helps!



Leave a Reply

Your email address will not be published. Required fields are marked *

Fill out this field
Fill out this field
Please enter a valid email address.