This is similar to the question here, but I am interested in how to add and align a separate plot to a spare panel that may exists at the end of a facet_wrap()
call.
Currently I am thinking it might not be possible currently, and I would need to make all the facet plots separately, but maybe there is a way.
I made a reproducible example using the palmerpenguins dataset. I tried putting the second plot in as a grob, which worked but did not align the plot axes with the other panels and not sure I know how I could make it happen.
# if librarian is not installed, install it
if (!requireNamespace("librarian", quietly = TRUE)){
install.packages("librarian")
}
# load packages
librarian::shelf(tidyverse, palmerpenguins, ggbeeswarm, patchwork, ggplotify)
data("penguins")
# make first plot
p1 <- ggplot(penguins, aes(bill_length_mm, flipper_length_mm)) +
geom_point() +
facet_wrap(~species, ncol = 2)
# make second plot
p2 <- ggplot(penguins, aes(species, body_mass_g)) +
geom_quasirandom()
p1
p2
# make plots into grobs and insert p2 into the empty slot of p1
p3 <- ggplotGrob(p1)
p3$grobs[[5]] <- ggplotGrob(p2)
# plot new plot
as.ggplot(p3)
Created on 2024-12-05 with reprex v2.1.1
Using patchwork inset_element seems to work, however I'm not sure how robust it is if you make changes. I tried exporting at different sizes/aspect ratios and it held together.
I've plotted iris
data as I didn't have the penguin data installed and don't really think it makes a difference to the functionality of the answer.
library(ggplot2)
library(dplyr)
library(patchwork)
# create facet plot with some extra space so there will be room for axis labels on fourth plot
# move x axis label so its not hidden behind the 4th plot
pp1 <- ggplot(iris, aes(Sepal.Width, Sepal.Length))+
geom_point()+
facet_wrap(~Species, ncol = 2)+
theme(panel.spacing = unit(2.5, "lines"),
axis.title.x = element_text(hjust = 0.25))
#create 4th plot
pp2 <- ggplot(iris, aes(Species, Sepal.Length))+
geom_boxplot()
#get spacing from pp1 and apply to pp2 (in particular space where the facet label is)
pp2aligned <- set_dim(pp2,get_dim(pp1) )
#add plots, intuitively I thought the align_to should be "plot" but "full" appears better
pp1 +
inset_element(pp2aligned, left = 0.5, bottom = 0.0, right = 1, top = 0.5, align_to = "full")
Created on 2024-12-09 with reprex v2.1.1