1

I have data with two different categorical grouping variables, and to distinguish between them, I followed this guide to add a pattern to one of the categorical variable types. However, now that I've done this, my legend elements are stacked without any space between them.

image of current plot:
image of current plot

This would be fine if my legend elements did not have very long titles, but they do, and I cannot shorten them. Specifically, I want to have a thin block of empty white space between the purple, green, and blue blocks in the legend, as well as between the white block and the striped block in the legend.

I know that one solution is to move the legends so that they are next to each other in a row rather than on top of each other in a column, but I do not want to do this.

Additionally, I want to move the legend elements so that "Group 1" and "Group 2" are not directly next to each other like they currently are.

Here is a data frame that approximates the data I am dealing with:

df <- data.frame(group1  = c("A", "B", "C", "A", "B", "C"),
                 group2 = c("num1", "num1", "num1", "num2", "num2", 
                            "num2"),
                 mean = c(-0.25, -0.27, -0.23, -0.36, -0.34, -0.37),
                 conf = c(0.05, 0.06, 0.05, 0.07, 0.06, 0.05))

And here is the code I am using:

library(ggplot2)
#remotes::install_github("coolbutuseless/ggpattern")
library(ggpattern)
ggplot(df, aes(x = group2, y = mean, fill = group1, pattern = group2, 
  group = group1)) +
  geom_bar_pattern(stat = "identity", position = position_dodge(0.95),
                   color = "black", 
                   pattern_fill = "black",
                   pattern_angle = 45,
                   pattern_density = 0.1,
                   pattern_spacing = 0.025,
                   pattern_key_scale_factor = 0.6) + 
  geom_errorbar(aes(ymin=mean-conf, ymax=mean+conf), width=0.2, size = 1, 
  position=position_dodge(.95)) +
  scale_fill_manual(values = c(A = "purple", B = "lightgreen", 
                    C = "lightblue"), 
                    labels = c(A = "Very long\ntitle 1", 
    B = "Very long\ntitle 2", C = "Very long\ntitle 3")) +
  scale_pattern_manual(values = c(num2 = "stripe", num1 = "none"),
                       labels = c(num2 = "Exp. 1a", num1 = "Exp. 1b")) +
  labs(x = "", y = "Mean rating", fill = "Group 1", pattern = "Group 2") + 
  guides(pattern = guide_legend(override.aes = list(fill = "white"),
                                nrow=2, byrow = 2,
                                title.position="top", title.hjust = 0.5),
         fill = guide_legend(override.aes = list(pattern = "none"),
                             nrow=3, byrow = 3,
                             title.position="top", title.hjust = 0.5)) +
  geom_hline(yintercept=0) +
  theme_classic() +
  theme(axis.text.x=element_blank(), axis.ticks.x=element_blank(),
        axis.text=element_text(size=rel(1.7)), axis.title=element_text(size=rel(1.3)), 
        legend.text=element_text(size=rel(1.5)), legend.title=element_text(size=rel(1.3)),
        title=element_text(size=rel(1.5)),
        legend.position="top")
Allan Cameron
  • 147,086
  • 7
  • 49
  • 87
wlane
  • 13
  • 3

1 Answers1

0

You can use legend.spacing.y in theme to get the gap between the keys in each legend. Push the legends apart using legend.margin

ggplot(df, aes(x = group2, y = mean, fill = group1, 
               pattern = group2, group = group1)) +
  geom_bar_pattern(stat = "identity", position = position_dodge(0.95),
                   color = "black", pattern_fill = "black",
                   pattern_angle = 45, pattern_density = 0.1,
                   pattern_spacing = 0.025, pattern_key_scale_factor = 0.6) + 
  geom_errorbar(aes(ymin = mean - conf, ymax = mean + conf), width = 0.2, 
                linewidth = 1, position = position_dodge(0.95)) +
  scale_fill_manual(values = c(A = "purple", B = "lightgreen", C = "lightblue"), 
                    labels = c(A = "Very long\ntitle 1", B = "Very long\ntitle 2", 
                               C = "Very long\ntitle 3")) +
  scale_pattern_manual(values = c(num2 = "stripe", num1 = "none"),
                       labels = c(num2 = "Exp. 1a", num1 = "Exp. 1b")) +
  labs(x = "", y = "Mean rating", fill = "Group 1", pattern = "Group 2") + 
  guides(pattern = guide_legend(override.aes = list(fill = "white"),
                                nrow = 2, byrow = TRUE,
                                title.position ="top", title.hjust = 0.1),
         fill = guide_legend(override.aes = list(pattern = "none"),
                             direction = "vertical", byrow = TRUE, nrow = 3,
                             title.position="top", title.hjust = 0.1)) +
  geom_hline(yintercept = 0) +
  theme_classic() +
  theme(axis.text.x = element_blank(), 
        axis.ticks.x = element_blank(),
        axis.text = element_text(size = rel(1.7)), 
        axis.title = element_text(size = rel(1.3)), 
        legend.text = element_text(size = rel(1.5), hjust = 0, vjust = 0.5),
        legend.margin = margin(0, 80, 0, 80), 
        legend.title = element_text(size = rel(1.3)),
        legend.key.width = unit(10, "mm"),
        legend.key.height = unit(10, "mm"), title = element_text(size = rel(1.5)),
        legend.position = "top",
        legend.spacing.y = unit(10, "mm"))

enter image description here

Note that ggpattern is now on CRAN

Allan Cameron
  • 147,086
  • 7
  • 49
  • 87