0

This question builds off of enter link description here but is in the context of faceted boxplots.

So, I have the following code:

set.seed(20210714)
dd <- data.frame(Method = rep(c("A", "B", "C"), each = 60), Pattern = rep(c("X", "Y", "Z"), times = 30), X1 = runif(180), Complexity = rep(c("High", "Low"), times = 90), nsim = rep(rep(1:10, times = 9), each = 2), n = 10)
dd1 <-  data.frame(Method = rep(c("A", "B", "C"), each = 60), Pattern = rep(c("X", "Y", "Z"), times = 30), X1 = runif(180), Complexity = rep(c("High", "Low"), times = 90), nsim = rep(rep(1:10, times = 9), each = 2), n = 5)
dd <- rbind(dd, dd1)


library(ggplot2)

# create dummy dataframe.
dummy.df <- dd
dummy.df[nrow(dd) + 1:2,"Pattern"] <- unique(dd$Pattern)[-3]
dummy.df[nrow(dd) + 1:2,"Method"] <- "ZZZ"
dummy.df[nrow(dd) + 1:2,"Complexity"] <- c("High","Low")

dummy.df$dummy <- interaction(dummy.df$Method,dummy.df$Pattern)             

ggplot(dummy.df, aes(x = dummy, y = X1, fill = Method)) +
      geom_boxplot(aes(fill = Method)) + 
  facet_grid(~Complexity) + 
    theme_light()  +
    theme(legend.position = 'bottom')  +
    guides(fill = guide_legend(nrow=1)) +
      geom_line(aes(x = dummy, 
                group=interaction(Pattern,nsim)), 
            size = 0.35, alpha = 0.35, colour = I("#525252"))  + 
    geom_point(aes(x = dummy, 
                group=interaction(Pattern,nsim)), 
               size = 0.35, alpha = 0.25, colour = I("#525252"))  +
   scale_x_discrete(labels = c("","X", "", "", "", "Y", "", "", "", "Z","","")) +
    xlab("Pattern") +
    scale_fill_brewer(breaks=c("A", "B", "C"), type="qual", palette="Paired")

dummy.df <- dd
dummy.df[nrow(dd) + 1:2,"Pattern"] <- unique(dd$Pattern)[-3]
dummy.df[nrow(dd) + 1:2,"Method"] <- "ZZZ"
dummy.df[nrow(dd) + 1:2,"Complexity"] <- c("High","Low")

dummy.df$dummy <- interaction(dummy.df$Method,dummy.df$Pattern)             
dummy.df$fill <- interaction(dummy.df$Method, dummy.df$n)
dummy.df$dummy <- interaction(dummy.df$fill, dummy.df$Pattern)
dummy.df$dummy <- factor(dummy.df$dummy, levels = levels(dummy.df$dummy)[-c(4, 12, 20, 24)])

dummy.df$dummy[361:362] <- "A.10.Z" ## dummy variables to get rid of NAs


theme_set(theme_bw(base_size = 14))

ggplot(dummy.df, aes(x = dummy, y = X1, fill = fill)) +
    geom_boxplot(aes(fill = fill),lwd=0.1,outlier.size = 0.01)  +
    facet_grid(~Complexity) +
    theme(legend.position = 'bottom')  +
    guides(fill = guide_legend(nrow=1)) +
    geom_line(aes(x = dummy, 
                  group=interaction(Pattern,nsim,n)), 
              size = 0.35, alpha = 0.35, colour = I("#525252"))  + 
    geom_point(aes(x = dummy, 
                   group=interaction(Pattern,nsim,n)), 
               size = 0.35, alpha = 0.25, colour = I("#525252"))  +
    scale_x_discrete(labels = c("X", "Y", "Z"), breaks = paste("A.10.", c("X", "Y", "Z"), sep = ""),drop=FALSE) +
    xlab("Pattern") +
    scale_fill_brewer(breaks= levels(dummy.df$fill)[-c(4,8)], type="qual", palette="Paired")

This yields the following plot. enter image description here

All is well, except with the legend. I would like the following: the dark colors to be in the First group titled "n=5" on the left, with "A", "B", "C" for the three dark colors, and the light colors to be to the right, in a Second group titled "n=10" on the right, with "A", "B", "C" for the three light colors. Sort of like in the link enter link description here above.

What I can not figure out is how to call the boxplot twice to mimic the solution there.

Is there a way to do this? Please feel free to let me know if the question is not clear.

Thanks again, in advance, for any help!

user3236841
  • 1,088
  • 1
  • 15
  • 39

1 Answers1

1

Adapting my answer on your former question this could be achieved like so:

library(ggplot2)

fill <- levels(dummy.df$fill)[-c(4,8)]
fill <- sort(fill)
labels <- gsub("\\.\\d+", "", fill)
labels <- setNames(labels, fill)
colors <- scales::brewer_pal(type="qual", palette="Paired")(6)
colors <- setNames(colors, fill)

library(ggnewscale)

ggplot(dummy.df, aes(x = dummy, y = X1, fill = fill)) +
  geom_boxplot(aes(fill = fill), lwd=0.1,outlier.size = 0.01)  +
  scale_fill_manual(name = "n = 5", breaks= fill[grepl("5$", fill)], labels = labels[grepl("5$", fill)], values = colors,
                    guide = guide_legend(title.position = "left", order = 1)) +
  new_scale_fill() +
  geom_boxplot(aes(fill = fill), lwd=0.1,outlier.size = 0.01)  +
  scale_fill_manual(name = "n = 10", breaks = fill[grepl("10$", fill)], labels = labels[grepl("10$", fill)], values = colors,
                    guide = guide_legend(title.position = "left", order = 2)) +
  facet_grid(~Complexity) +
  theme(legend.position = 'bottom')  +
  guides(fill = guide_legend(nrow=1)) +
  geom_line(aes(x = dummy, 
                group=interaction(Pattern,nsim,n)), 
            size = 0.35, alpha = 0.35, colour = I("#525252"))  + 
  geom_point(aes(x = dummy, 
                 group=interaction(Pattern,nsim,n)), 
             size = 0.35, alpha = 0.25, colour = I("#525252"))  +
  scale_x_discrete(labels = c("X", "Y", "Z"), breaks = paste("A.10.", c("X", "Y", "Z"), sep = ""),drop=FALSE) +
  xlab("Pattern")
#> Warning: Removed 2 rows containing non-finite values (new_stat_boxplot).

stefan
  • 90,330
  • 6
  • 25
  • 51
  • Thanks! Btw, how do I increase the space between the two blocks of labels? Also, can I put a box around them with a heading (say "Setup", perhaps it can be on the top or to the left of everying with a colon or something?). Thanks again! – user3236841 Aug 01 '21 at 16:34
  • Hm. Adding a box and increasing the space is in principle easily be done via theme options `legend.background` and `legend.margin`, e.g. `theme(legend.box.background = element_rect(color = "black"), legend.margin = margin(5, 40, 5, 40, "pt"))`. Unfortunately it looks like there is a bug in ggplot2 when adding the box. Adding a heading is not that easy and I'm afraid in that case you are back into the "fiddling with the gtable" business. – stefan Aug 01 '21 at 18:52