f.lechleitner
f.lechleitner

Reputation: 3812

Draw a "grid" between arranged plots

I'm working with 4 different plots and I'm using ggarrange() from the ggpubr-package to put them in a single plot. I've prepared an example:

library(ggpubr)
library(ggplot2)

p1 <- ggplot(iris, aes(x = Sepal.Length, y = Sepal.Width)) + geom_point() + ggtitle("Plot 1")
p2 <- ggplot(iris, aes(x = Petal.Length, y = Petal.Width)) + geom_point() + ggtitle("Plot 2")
p3 <- ggplot(iris, aes(x = Sepal.Length, y = Petal.Width)) + geom_point() + ggtitle("Plot 3")
p4 <- ggplot(iris, aes(x = Petal.Length, y = Sepal.Width)) + geom_point() + ggtitle("Plot 4") +
  facet_wrap(~Species)

plot.list <- list(p1, p2, p3, p4)

ggarrange(plotlist = plot.list)

Output: enter image description here

I would like to draw a border around the single plots, like so:

enter image description here

Is there any way to draw this border? Thanks!

Upvotes: 6

Views: 3394

Answers (2)

Carles
Carles

Reputation: 2829

grid.polygon() is quite manual but I think it can do the trick:

Using RStudio

library("ggpubr")
library(ggplot2)
library(gridExtra)
library(grid)
p1 <- ggplot(iris, aes(x = Sepal.Length, y = Sepal.Width)) + geom_point() + ggtitle("Plot 1")
p2 <- ggplot(iris, aes(x = Petal.Length, y = Petal.Width)) + geom_point() + ggtitle("Plot 2")
p3 <- ggplot(iris, aes(x = Sepal.Length, y = Petal.Width)) + geom_point() + ggtitle("Plot 3")
p4 <- ggplot(iris, aes(x = Petal.Length, y = Sepal.Width)) + geom_point() + ggtitle("Plot 4") +
  facet_wrap(~Species)

plot.list <- list(p1, p2, p3, p4)

ggarrange(plotlist = plot.list)
x = c(0, 0.5, 1, 0.5, 0.5, 0.5)
y = c(0.5, 0.5, 0.5,0, 0.5, 1)
id = c(1,1,1,2,2,2)
grid.polygon(x,y,id)

enter image description here Using Shiny (Edit)

When doing it within a shiny-app, ones needs to add the grid using annotation_custom(), as follows:

    ggarrange(plotlist = plot.list) + 
    annotation_custom(
             grid.polygon(c(0, 0.5, 1, 0.5, 0.5, 0.5),
                          c(0.5, 0.5, 0.5,0, 0.5, 1), 
                          id = c(1,1,1,2,2,2), 
                          gp = gpar(lwd = 1.5)))

Upvotes: 6

camille
camille

Reputation: 16862

Not sure if this will work for you, but you can just put borders around your individual plots. However, this includes borders on the outside of the layout. Your description seems like you're not opposed to that, but there are only inner gridlines in your example plot.

You could add the theme call when you create the plots; rather than editing the plot creation, I just did it to each plot in the list before sticking them all together.

library(ggpubr)
library(ggplot2)

#### same plot creation here ######

plot.list <- lapply(list(p1, p2, p3, p4), 
                    function(p) p + theme(plot.background = element_rect(color = "black")))

ggarrange(plotlist = plot.list)

Upvotes: 5

Related Questions