Home > Back-end >  Setting per-column y axis limits with facet_grid
Setting per-column y axis limits with facet_grid

Time:01-12

I am, in R and using ggplot2, plotting the development over time of several variables for several groups in my sample (days of the week, to be precise). An artificial sample (using long data suitable for plotting) is this:

library(tidyverse)

groups1 <- rep(1:2, each = 7 * 100)
groups2 <- rep(rep(1:7, times = 2), each = 100)
x <- rep(1:100, times = 14)
values <- c(rnorm(n = 700), rgamma(n = 700, shape = 2))

data <- tibble(x, groups1, groups2, values)

data %>% ggplot(mapping = aes(x = x, y = values))   geom_line()   facet_grid(groups2 ~ groups1)

which gives

sample image

In this example, the first variable -- shown in the left column -- has unlimited range, while the second variable -- shown in the right column -- is weakly positive.

I would like to reflect this in my plot by allowing the Y axes to differ across the columns in this plot, i.e. set Y axis limits separately for the two variables plotted. However, in order to allow for easy visual comparison of the different groups for each of the two variables, I would also like to have the identical Y axes within each column.

I've looked at the scales option to facet_grid(), but it does not seem to be able to do what I want. Specifically,

  • passing scales = "free_x" allows the Y axes to vary across rows, while
  • passing scales = "free_y" allows the X axes to vary across columns, but
  • there is no option to allow the Y axes to vary across columns (nor, presumably, the X axes across rows).

As usual, my attempts to find a solution have yielded nothing. Thank you very much for your help!

CodePudding user response:

I think the easiest would to create a plot per facet column and bind them with something like {patchwork}. To get the facet look, you can still add a faceting layer.

library(tidyverse)
library(patchwork)

groups1 <- rep(1:2, each = 7 * 100)
groups2 <- rep(rep(1:7, times = 2), each = 100)
x <- rep(1:100, times = 14)
set.seed(42) ## always better to set a seed before using random functions
values <- c(rnorm(n = 700), rgamma(n = 700, shape = 2))

data <- tibble(x, groups1, groups2, values)
data %>%
  group_split(groups1) %>%
  map({
    ~ggplot(.x, aes(x = x, y = values))  
  geom_line()   
  facet_grid(groups2 ~ groups1)
  }) %>%
  wrap_plots()

Created on 2023-01-11 with reprex v2.0.2

  • Related