I am trying to plot a a series of maps (NZ, Australia and Argentina) in a grid, with some parts of the grid being empty. I am using ggplot to create the individual maps and then patchwork to sow together the grid.
I expect the result to be a 3x3 grid with 3x NZ maps on the top row, 2x aus + an empty plot on the second row and 1x Argentina + 2x empty plots on the 3rd row.
My problem is the plots do not maintain a 3x3 grid and the countries are very different sizes. An example:
library(tidyverse)
library(sf)
library(rnaturalearth)
library(patchwork)
# basic country maps
nz <- ne_countries(country = 'new zealand', type = 'countries', returnclass = "sf")
aus <- ne_countries(country = 'australia', type = 'countries', returnclass = "sf")
arge <- ne_countries(country = 'argentina', type ='countries', returnclass = "sf")
# plot nz
p1 <- ggplot() +
geom_sf(data = nz) +
theme_void()
# plot aus
p2 <- ggplot() +
geom_sf(data = aus) +
theme_void()
# plot arg
p3 <- ggplot() +
geom_sf(data = arge) +
theme_void()
# combine plots
p1 + p1 + plot_spacer() /
p2 + plot_spacer() + p2 /
plot_spacer() + plot_spacer() + p3
Whereas the desired output would be like this (with the maps all a similar size):
Any pointers would be much appreciated!
This is a bit of a hack which I use quite often when I have to export maps. The basic idea is to not plot or export the map directly but instead add it to an empty background plot first via patchwork::inset_element
.
For the first plot I dropped theme_void
from the background plot which shows that all subplots are actually of the same size independent what the size of the map is:
library(tidyverse)
library(sf)
library(rnaturalearth)
library(patchwork)
plist <- dplyr::lst(p1, p2, p3)
plist <- lapply(plist, function(x) {
ggplot() +
geom_blank() +
#theme_void() +
inset_element(x, left = 0, right = 1, top = 1, bottom = 0)
})
# combine plots
(plist$p1 + plist$p1 + plist$p1) /
(plist$p2 + plot_spacer() + plist$p2) /
(plot_spacer() + plot_spacer() + plist$p3)
And here is the final plot using theme_void
for the background plots too:
plist <- dplyr::lst(p1, p2, p3)
plist <- lapply(plist, function(x) {
ggplot() +
geom_blank() +
theme_void() +
inset_element(x, left = 0, right = 1, top = 1, bottom = 0)
})
# combine plots
(plist$p1 + plist$p1 + plist$p1) /
(plist$p2 + plot_spacer() + plist$p2) /
(plot_spacer() + plot_spacer() + plist$p3)