gtable of ggplot is corrupted after setting absolute panel size

I want to set the panel size of a ggplot facet_wrap to absolute values and receive a ggplot object in return. This part is working. However, for me it is important that the gtable of this ggplot is correct. And this does not seem to be the case.

Any help is very welcome!

# generate plot: works!
p1 <- 
  ggplot(mtcars) +
  geom_point(aes(mpg, disp)) +
  facet_wrap(vars(cyl))

# set panel size to absolute values: works!
p1 %>% ggplotGrob() %>% gtable::gtable_show_layout()
p1 %>% egg::set_panel_size() %>% gtable::gtable_show_layout()

# convert to ggplot: works!
p1 %>% egg::set_panel_size() %>% ggpubr::as_ggplot()
p1 %>% egg::set_panel_size() %>% ggplotify::as.ggplot()

# look at gtable of ggplot: corrupted!
p1 %>% egg::set_panel_size() %>% ggpubr::as_ggplot() %>% ggplotGrob() %>% gtable::gtable_show_layout()
p1 %>% egg::set_panel_size() %>% ggplotify::as.ggplot() %>% ggplotGrob() %>% gtable::gtable_show_layout()

# I would except to find the "4cm" that was put in via egg::set_panel_size() earlier.

Neither ggpubr::as_ggplot() nor ggplotify::as.ggplot() actually converts its input to real ggplot2 objects, rather it creates an empty ggplot2 object with an annotation of the input plot on top. You cannot really do what you want to do as the ggplot nature of the plot is completely lost when converting to a gtable and cannot be restored. So, nothing is corrupted - you are simply attempting what cannot be done. Why not just defer setting the panel size to right before it is needed?

1 Like

thanks a lot for the quick answer! I think I get your point.
So is there a way to set the panel size without taking the detour over gtables? I saw you doing something like below in patchwork, but I have a hard time understanding the magic happening under the hood.

p <- ggplot(mtcars) + geom_point(aes(mpg, disp))
fwrap <- p + facet_wrap(vars(cyl))

# works nicely
p_sized <- p + patchwork::plot_layout(widths = unit(40, "mm"), heights = unit(40, "mm"))
p_sized
p_sized %>% patchwork:::plot_table('auto') %>% gtable::gtable_show_layout()

# also works nicely
# only I would like to have 40mm x 40mm for each panel in the facet_wrap
fwrap_sized <- fwrap  + patchwork::plot_layout(widths = unit(40, "mm"), heights = unit(40, "mm"))
fwrap_sized
fwrap_sized %>% patchwork:::plot_table('auto') %>% gtable::gtable_show_layout()

Coming to your question: Why would one even like to do this?
When I prepare figures for print publication I usually do.

  1. ggplot
  2. adjust styling
  3. arrange and set panel size
  4. inspect result
  5. save to pdf

All of this is basically solved in your brilliant patchwork package.
Only one edge case is left. As mentioned above I would like to set each panel of a facet_wrap to 40mm x 40mm. It would be great if this could be done with patchwork::plot_layout()! The patchwork object is both a viable ggplot and has a way to get a proper gtable. Maybe you could give me a hint how to implement this?

1 Like

This topic was automatically closed 21 days after the last reply. New replies are no longer allowed.