I'm working on a problem where I want to create many plots based on some grouping vars. Some of these groups have many values I want to facet, while others only have a few. I want to display all of the facets to be the same size.
In this reprex, the 8 cyl group only has 2 facets while the others have 3. I want the 2 facets in the 8 cyl group to be the same size as facets in the other group, and the space for the 3rd missing facet to just be blank.
library(tidyverse)
for(i in unique(mtcars$cyl)){
sub_data <- filter(mtcars, cyl == i)
p <- ggplot(sub_data, aes(wt, drat))
geom_point()
facet_wrap(~gear)
labs(title = paste(i, "cyl"))
print(p)
}
CodePudding user response:
One option would be ggh4x::facet_manual
which allows to add blank panels to a plot. For each of your plots you could specify a design
which could be filled with blank panels so that each plot has the same number of panels.
library(ggplot2)
library(dplyr)
library(ggh4x)
# Maximum number of panels
nmax <- max(tapply(mtcars$gear, mtcars$cyl, n_distinct))
for(i in unique(mtcars$cyl)){
sub_data <- filter(mtcars, cyl == i)
# Number of panels for plot i
ngear <- n_distinct(sub_data$gear)
# Create design
design = paste(c(LETTERS[seq(ngear)], rep("#", nmax - ngear)), collapse = "")
print(design)
p <- ggplot(sub_data, aes(wt, drat))
geom_point()
facet_manual(~gear, design = design, trim_blank = FALSE)
labs(title = paste(i, "cyl"))
print(p)
}
#> [1] "ABC"
#> [1] "ABC"
#> [1] "AB#"
CodePudding user response:
I used @stefan 's advice to look into ggh4x, but ended up ditched design
and just used facet_wrap2()
and specified rows and columns. The data I am using this on was going to have up to 20 facets so using facet_wrap2
made more sense and avoided the need of building a function to robustly declare the design
.
Without the loop it looks like this.
library(tidyverse)
library(ggh4x)
p <- ggplot(mpg, aes(displ, hwy, colour = as.factor(cyl))) geom_point()
labs(x = "Engine displacement", y = "Highway miles per gallon")
guides(colour = "none")
p facet_wrap2(vars(class), nrow = 3, ncol = 4, trim_blank = FALSE)
I was confused for a bit but then embraced the trim blank
argument.
You can check out the final product for my project here if you want.