2

This is a follow up problem to this question. The OP asked for a way to arrange parts of a plot in specific distances. I think teunbrand gave a very good answer.

My own suggestion (extract the legend with cowplot, and stitch them to a plot in desired proportions) is not fully satisfactory, because it worked only "by chance" in the given example - the legend labels were long enough to center the legend grob into the viewport for the third plot.

Having shorter labels reveals the problem - when adding a grob, patchwork centres this grob, basically padding equally to all sides.

My question is, do you know of a way to control this padding behaviour?

Cowplot (or any other ggplot combining package for that sake) also very welcome.

library(tidyverse)
library(patchwork)
data <- midwest %>% 
  head(5) %>% 
  select(2,23:25) %>%
  pivot_longer(cols=2:4,names_to="Variable", values_to="Percent") %>% 
  mutate(Variable=factor(Variable, 
                         levels=c("percbelowpoverty","percchildbelowpovert","percadultpoverty"),
                         labels = paste0("perc", 1:3)))

p1 <- 
  ggplot(data=data, mapping=aes(x=county, y=Percent, fill=Variable)) +
  geom_col() + 
  scale_fill_manual(values = c("#CF232B","#942192","#000000")) +
  theme(legend.background = element_rect(fill = "grey50"))

p_legend <- cowplot::get_legend(p1)

p_main <- p1 <- 
  ggplot(data=data, mapping=aes(x=county, y=Percent, fill=Variable)) +
  geom_col(show.legend = FALSE) + 
  scale_fill_manual(values = c("#CF232B","#942192","#000000"))

p_main + plot_spacer() + p_legend + 
  plot_layout(widths = c(12.5, 1.5, 4)) &
  theme(plot.margin = margin(),
        plot.background = element_rect(colour = "black"))

Not so desired result - the legend grob (with grey background) should be aligned to the left plot border (black line)

Created on 2021-04-09 by the reprex package (v1.0.0)

tjebo
  • 21,977
  • 7
  • 58
  • 94

1 Answers1

2

As far as I get it the issue is not on patchworks side. Having a look at the layout of the legend's gtable we see that it is made up of 5 rows and 5 columns and that the legend is to be placed in the cell in the center:

p_legend <- cowplot::get_legend(p1)
p_legend
#> TableGrob (5 x 5) "guide-box": 2 grobs
#>                                     z     cells                  name
#> 99_a788e923bf245af3853cee162f5f8bc9 1 (3-3,3-3)                guides
#>                                     0 (2-4,2-4) legend.box.background
#>                                               grob
#> 99_a788e923bf245af3853cee162f5f8bc9 gtable[layout]
#>                                     zeroGrob[NULL]
gtable::gtable_show_layout(p_legend)

Hence, when adding the legend patchwork centers is as demanded by the gtable layout.

One option to control the positioning or the padding of the legend would be to squash the first column via cowplot::gtable_squash_cols and if desired add some padding by adding a new column with the desired amount of padding via gtable::gtable_add_cols:

# Squash first column
p_legend <- cowplot::gtable_squash_cols(p_legend, 1)
# Add some padding by adding a new col
p_legend <- gtable::gtable_add_cols(p_legend, unit(.1, "cm"), pos = 1)

p_main <- p1 <- 
  ggplot(data=data, mapping=aes(x=county, y=Percent, fill=Variable)) +
  geom_col(show.legend = FALSE) + 
  scale_fill_manual(values = c("#CF232B","#942192","#000000"))

p_main + plot_spacer() + p_legend + 
  plot_layout(widths = c(12.5, 1.5, 4)) &
  theme(plot.margin = margin(),
        plot.background = element_rect(colour = "black"))

stefan
  • 90,330
  • 6
  • 25
  • 51
  • that's wonderful. Thanks, Stefan. As a matter of fact, the added padding after the squash isn't necessary for this purpose - `p_legend <- gtable_squash_cols(get_legend(p1), 1)` should suffice – tjebo Apr 11 '21 at 11:04
  • Really clever by the way. I was just not thinking of exploring underlying gtable to p_legend. I was almost going to submit a feature request in patchwork lol. Thanks for saving me from that – tjebo Apr 11 '21 at 11:11
  • 1
    Hi @tjebo. You are welcome. That was a very interesting and useful question. And a very good opportunity to dive a bit deeper into ggplot manipulation via gtable, cowplot, ... Best S. – stefan Apr 11 '21 at 16:08