Reputation: 373
I'm trying to create a plot for a publication that requires faceting. It has to show the same x axis on each facet and maintain even spacing of each y-axis metric.
facet_grid
allows me to create the y metric spacing I want, but I can't get the x-axis to show across each facet. This seems to be part of how facet_grid
works though as per this answer
facet_wrap
allows me to show the x-axis on each facet, but it disrupts the y metric spacing. The values of each x-axis are also different which I need to be the same.
facet_rep_grid
seems like it should be a solution but it throws me an error "Error in axisgrob$height$arg1 : $ operator is invalid for atomic vectors"
Using patchwork
seems like it could be a solution but this also disrupts the y axis spacing that I need to be the exact same for each grid.
Reproducible examples of the plots I just described:
install.packages("lemon")
library(lemon)
data("mtcars")
df <- mtcars %>%
rownames_to_column(var = "car")
mt <- ggplot(df, aes(mpg, car, colour = factor(cyl))) +
theme(strip.placement = "outside")+
geom_point()
# Good y metric spacing, can't get x-axis to show on each
mt +
facet_grid(vars(cyl), switch = "y", scales = "free", space = "free")
# Incorrect y metric spacing, shows x-axis on each but uses different scales
mt +
facet_wrap(~cyl, scales = "free", ncol=1, switch = "y")
# Throws an error
mt +
facet_rep_grid(vars(cyl), scales = "free"
, switch = "both", space = "free")
facet_grid version:
facet_wrap version:
Upvotes: 3
Views: 5881
Reputation: 1
If you are using facet_wrap, just make sure to set scales = "free", and it will show each axes on every facet.
Upvotes: 0
Reputation: 78907
Here is an approximate solution using complete different approach:
library(tidyverse)
df_list <- mtcars %>%
rownames_to_column("car") %>%
group_split(cyl)
create_plot <- function(df) {
ggplot(df, aes(mpg, car, color = factor(cyl))) +
theme(strip.placement = "outside") +
geom_point(show.legend = FALSE) +
xlim(0, 30) +
scale_color_manual(values = c("red", "green", "blue"),
limits = levels(factor(mtcars$cyl)))+
facet_grid(cyl ~ .,
scales = "free_y", switch = "y")
}
# Use map to apply function to each data frame in list
plots_list <- map(df_list, create_plot)
library(patchwork)
plots_list[[1]] / plots_list[[2]] / plots_list[[3]] + plot_layout(ncol = 1, heights = c(0.8, 0.5, 1))
Upvotes: 0
Reputation: 123768
Actually using lemon::facet_rep_grid
works fine for me. But another option would be ggh4x::facet_grid2
which also allows to add interior axes:
library(ggplot2)
library(ggh4x)
library(tibble)
df <- mtcars %>%
rownames_to_column(var = "car")
mt <- ggplot(df, aes(mpg, car, colour = factor(cyl))) +
theme(strip.placement = "outside") +
geom_point()
mt +
facet_grid2(cyl ~ .,
scales = "free_y",
axes = "x", space = "free_y", switch = "y"
)
Upvotes: 2
Reputation: 1074
Your final solution works for me.
mt +
facet_rep_grid(vars(cyl), scales = "free"
, switch = "both", space = "free",
repeat.tick.labels = T)
If you still are getting an error can you post it? I had to re-install rlang
and vctrs
packages to get it to work.
Upvotes: 2