I want to create a facet-like effect with ggExtra::ggMarginal
plots. This is not yet directly possible, so I tried to use patchwork::wrap_plots
, cowplot::plot_grid
, and egg::ggarrange
to do it myself. I have everything properly developed—except for the plot sizing. patchwork
and egg
make the panels of ggplot
objects the same size, but this behavior does not apply to the ggExtraPlot
objects that ggMarginal
creates.
For example, consider the following patchwork
of ggplot
s (code below):
But once I add the marginal densities, the arrangement looks like this:
As you can see, the panels of each plot are no longer equally sized; rather, the entire objects are. I want the panel sizes of each ggplot
in the second plot to be the same, as in the first plot.
Attempted solutions:
widths
and heights
arguments in wrap_plot
to set proper relative sizes of the ggMarginal
-ized objects; unfortunately, I spent many hours unsuccessfully digging through the ggplotGrob
output. For instance, I used grid::convertWidth(sum(ggplotGrob(p1)$widths), "in", TRUE)
and grid::convertWidth(sum(ggplotGrob(p2)$widths), "in", TRUE)
to attempt to calculate the widths of the plots in inches (p1
has a y-axis, p2
doesn't), but the results were vastly different: 0.87 and 0.19. It didn't make sense to me that simply removing the axis title, text, and ticks would so heavily decrease the width. Certainly setting the relative widths at around 4.5 and 1 wouldn't generate the proper patchwork
plot!patchwork::get_dim
and patchwork::set_dim
to manually set the area for each subplot (using patchwork::area
) but couldn't figure it out.ggMarginal
to each plot in the patchwork, but this didn't work.I would appreciate advice on guaranteeing equal panel sizes for the four plots, ideally without relying on the actual size (i.e., in pixels) of the components. It would be awesome to see ggMarginal
allow faceting and to see patchwork
extend beyond simple ggplot
objects!
b <- ggplot(mtcars, aes(x = disp, y = mpg)) +
geom_point() +
labs(x = "some\nlines",
y = "many\nnew\nlines")
p1 <- b +
theme(axis.title.x = element_blank(),
axis.text.x = element_blank(),
axis.ticks.x = element_blank())
p1m <- ggExtra::ggMarginal(p1, margins = "y")
p2 <- b +
theme(axis.title = element_blank(),
axis.text = element_blank(),
axis.ticks = element_blank())
p2m <- ggExtra::ggMarginal(p2, margins = "y")
p3 <- b
p3m <- ggExtra::ggMarginal(p3, margins = "y")
p4 <- b +
theme(axis.title.y = element_blank(),
axis.text.y = element_blank(),
axis.ticks.y = element_blank())
p4m <- ggExtra::ggMarginal(p4, margins = "y")
patchwork::wrap_plots(p1, p2, p3, p4, nrow = 2) # this looks great!
patchwork::wrap_plots(p1m, p2m, p3m, p4m, nrow = 2) # this doesn't :(
Instead of relying on ggMarginal
one option would be to manually create your density plots and glue both your main and the density plots together using patchwork
:
library(ggplot2)
library(patchwork)
dp <- ggplot(mtcars, aes(y = mpg)) +
geom_density() +
theme_void()
list(p1, dp, p2, dp, p3, dp, p4, dp) |>
wrap_plots(nrow = 2, widths = c(5, 1, 5, 1))