rggplot2

control y-axis title positions when combining several plots with patchwork package


I would like to be able to control the y-axis title position for each plot with respect to the y-axis itself, so that when I input differing antibiotic name lengths into the top plot, the y-axis title in the bottom plot is the same distance from the y-axis and I do not have to manually change this in the bottom plot everytime I change the antiobiotic names in the top plot. Anyone able to help?

The first plot shows the default without any adjustment.

The second plot shows the desired distance the y-axis title should be from the y-axis labels.

The third plot demonstates how varying the antibiotic name length in top plot means the correction needs to be changed. I would like to try to code this to happen automatically.

library(tidyverse)
library(patchwork)

therapy_1 <- tibble(
  antibiotic = c("IV Piperacillin-tazobactam", "IV Piperacillin-tazobactam"),
  time_point = c("start", "end"),
  date = c("2023-04-10","2023-04-25")) %>% 
  mutate(date = as_date(date))

therapy_2 <-tibble(
  antibiotic = c("PO co-trimoxazole", "PO co-trimoxazole"),
  time_point = c("start", "end"),
  date = c("2023-04-10","2023-04-25")) %>% 
  mutate(date = as_date(date))

inflammatory_markers <- tibble(
  date = c("2023-04-10", "2023-04-12"),
  value = c("38.1", "37.8")) %>%
  mutate(date = as_date(date))

p1 <- therapy_1 %>%
  ggplot(aes(x = date)) +
  geom_line(aes(y = antibiotic, colour = antibiotic)) +
  theme(legend.position = "none")

p2 <- therapy_2 %>%
  ggplot(aes(x = date)) +
  geom_line(aes(y = antibiotic, colour = antibiotic)) +
  theme(legend.position = "none")

default <- inflammatory_markers %>%
  ggplot(aes(x = date)) +
  geom_point(aes(y = value))

desired <- inflammatory_markers %>%
  ggplot(aes(x = date)) +
  geom_point(aes(y = value)) +
  theme(axis.title.y = element_text(margin = margin(r = -160)))

# default output
p1 / default


# desired output
p1 / desired


# when length of y-axis labels shortened
p2 / desired

Created on 2023-05-08 with reprex v2.0.2


Solution

  • Different enough to merit a second answer (IMO). If you're happy to use another package, you can also use egg::ggarrange which should do exactly what you need.

    library(egg)
    
    ggarrange(p1, desired)
    

    ggarrange(p2, desired)
    

    Created on 2023-05-08 with reprex v2.0.2