Max
Max

Reputation: 425

How to create uneven facet_wrap grid in R with ggplot?

I am currently working on a graph with ggplot2 in R where I want to use facet_wrap to create 5 subplots.

Here is my code so far:

# getting the data
data = structure(list(type = c("red", "blue", "orange", "yellow", "green", 
       "red", "blue", "orange", "yellow", "green", "red", "blue", "orange", 
       "yellow", "green", "red", "blue", "orange", "yellow", "green"), 
       cond = c("new", "new", "new", "new", "new", "old", "old", 
       "old", "old", "old", "new", "new", "new", "new", "new", "old", 
       "old", "old", "old", "old"), fact = c("light", "light", "light", 
       "light", "light", "light", "light", "light", "light", "light", 
       "shiny", "shiny", "shiny", "shiny", "shiny", "shiny", "shiny", 
       "shiny", "shiny", "shiny"), score = c(2L, 4L, 8L, 6L, 10L, 3L, 
       5L, 9L, 1L, 3L, 12L, 14L, 18L, 16L, 20L, 13L, 15L, 19L, 11L, 
       13L)), class = "data.frame", row.names = c(NA, -20L))

library(ggplot2)

ggplot(data=data, aes(x=cond, y=score, fill=fact)) +
  geom_bar(stat="identity", position=position_dodge()) +
  theme_bw() + facet_wrap(. ~ type, ncol=3) 

This creates the following plot:

what it looks like now

However, since one of the colours is much more important than the others, I would like to create one of these options:

desired options

Does anyone know how to get facet_wrap to do that or can point me to another option to create this?

Cheers, Max

Upvotes: 3

Views: 1810

Answers (2)

Paul
Paul

Reputation: 9097

Here's how to do it mixing patchwork and facets.

Create one plot for blue and another for everything else. Remove the legend from the blue plot and remove the y axis title from the other.

library(tidyverse)
library(patchwork)

p_other <-
  data %>%
  filter(type != "blue") %>%
  ggplot(aes(x = cond, y = score, fill = fact)) +
    geom_bar(stat = "identity", position = position_dodge()) +
    theme_bw() +
    facet_wrap(. ~ type, ncol = 2) +
    theme(axis.title.y = element_blank())

p_blue <-
  data %>%
  filter(type == "blue") %>%
  ggplot(aes(x = cond, y = score, fill = fact)) +
    geom_bar(stat = "identity", position = position_dodge()) +
    theme_bw() +
    facet_wrap(. ~ type, ncol = 2) +
    theme(legend.position = "none")

Add a column using | from patchwork.

(p_blue | p_other) + plot_layout(widths = c(1, 2))

plot

Upvotes: 3

Duck
Duck

Reputation: 39605

Try this approach with patchwork, you will have to format your type variable to factor in order to have the desired order and then use a function for the plot. After that you can compose the desired plot. I have designed the function for you and this belongs to option 2 in your question. Here the code:

library(ggplot2)
library(patchwork)
#Data format
data$type <- factor(data$type,
                    levels = c("blue","green","orange", "red", "yellow"),
                    ordered = T)

We create a list for our data:

#Create list
List <- split(data,data$type)

Now, the function for plots:

#Create isolate plots
myplot <- function(x)
{
  text <- unique(as.character(x$type))
  #Plot
  G <- ggplot(data=x, aes(x=cond, y=score, fill=fact)) +
    geom_bar(stat="identity", position=position_dodge()) +
    theme_bw() + ggtitle(text)+
    theme(plot.title = element_text(hjust=0.5))
  return(G)
}

Then, we start building our plots:

#Plot for only first plot
P1 <- myplot(List[[1]])
P2 <- wrap_plots(lapply(List[-1], myplot),ncol = 2)

Finally, we arrange the plots:

#Now wrap plots
P3 <- P1 + P2
P4 <- P3 +  plot_layout(guides = 'collect')

And the output:

enter image description here

Upvotes: 3

Related Questions