vb66
vb66

Reputation: 373

Showing x-axis on each facet in ggplot using facet_wrap

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_grid

facet_wrap version:

facet_wrap

Upvotes: 3

Views: 5881

Answers (4)

croutonbabe
croutonbabe

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

TarJae
TarJae

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))

enter image description here

Upvotes: 0

stefan
stefan

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

dandrews
dandrews

Reputation: 1074

Your final solution works for me.

mt +
  facet_rep_grid(vars(cyl), scales = "free"
                 , switch = "both", space = "free",
                 repeat.tick.labels = T)

enter image description here

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

Related Questions