Объединение двух заголовков по оси Y в пэчворк

Любые идеи относительно того, как я могу «объединить» два одинаковых заголовка по оси Y в один, а затем поместить этот заголовок по оси Y посередине между графиком? Мне удалось объединить легенды с помощью plot_layout(guides = "collect"), но я не могу найти ничего подобного для топоров. В этом случае я бы объединил заголовки двух осей с именем disp_disp_disp в один.

mtcars

library(ggplot2)
library(patchwork)

p1 <- ggplot(mtcars) + 
  geom_point(aes(mpg, disp)) + 
  labs(x = "mpg", y = "disp_disp_disp_disp_disp")

p2 <- ggplot(mtcars) + 
  geom_boxplot(aes(gear, disp, group = gear)) + 
  labs(x = "gear", y = "disp_disp_disp_disp_disp")

p3 <- ggplot(mtcars) + 
  geom_point(aes(hp, wt, colour = mpg)) + 
  ggtitle('Plot 3')

p1 / (p2 | p3)
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
13
0
7 428
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Единственный способ, который я мог придумать, - взломать это на уровне gtable, но я также был бы рад узнать более удобные способы. Вот метод gtable:

library(ggplot2)
library(patchwork)
library(grid)

p1 <- ggplot(mtcars) + 
  geom_point(aes(mpg, disp)) + 
  labs(x = "mpg", y = "disp_disp_disp_disp_disp")

p2 <- ggplot(mtcars) + 
  geom_boxplot(aes(gear, disp, group = gear)) + 
  labs(x = "gear", y = "disp_disp_disp_disp_disp")

p3 <- ggplot(mtcars) + 
  geom_point(aes(hp, wt, colour = mpg)) + 
  ggtitle('Plot 3')

p123 <- p1 / (p2 | p3)

# Convert to gtable
gt <- patchworkGrob(p123)

# Stretching one y-axis title
is_yaxis_title <- which(gt$layout$name == "ylab-l")
# Find new bottom position based on gtable::gtable_show_layout(gt)
gt$layout$b[is_yaxis_title] <- gt$layout$b[is_yaxis_title] + 18

# Deleting other y-axis title in sub-patchwork
is_patchwork <- which(gt$layout$name == "patchwork-table")
pw <- gt$grobs[[is_patchwork]]
pw <- gtable::gtable_filter(pw, "ylab-l", invert = TRUE)

# Set background to transparent
pw$grobs[[which(pw$layout$name == "background")[1]]]$gp$fill <- NA

# Putting sub-patchwork back into main patchwork
gt$grobs[[is_patchwork]] <- pw

# Render
grid.newpage(); grid.draw(gt)

Created on 2020-12-14 by the reprex package (v0.3.0)

Ответ принят как подходящий

Я думаю, было бы немного проще убрать заголовок оси Y до того, как график будет построен, а затем снова нарисовать его после того, как он построен:

library(ggplot2)
library(patchwork)

p1 <- ggplot(mtcars) + 
  geom_point(aes(mpg, disp)) + 
  labs(x = "mpg", y = "disp_disp_disp_disp_disp")

p2 <- ggplot(mtcars) + 
  geom_boxplot(aes(gear, disp, group = gear)) + 
  labs(x = "gear", y = "disp_disp_disp_disp_disp")

p3 <- ggplot(mtcars) + 
  geom_point(aes(hp, wt, colour = mpg)) + 
  ggtitle('Plot 3')

ylab <- p1$labels$y
p1$labels$y <- p2$labels$y <- " "

p1 / (p2 | p3)
grid::grid.draw(grid::textGrob(ylab, x = 0.02, rot = 90))

Другой вариант, если вы хотите вообще не замарать руки гробами, — указать только текстовый ggplot и добавить его в качестве текста вашей оси:

p4 <- ggplot(data.frame(l = p1$labels$y, x = 1, y = 1)) +
      geom_text(aes(x, y, label = l), angle = 90) + 
      theme_void() +
      coord_cartesian(clip = "off")

p1$labels$y <- p2$labels$y <- " "

p4 + (p1 / (p2 | p3)) + plot_layout(widths = c(1, 25))

Это ведет себя немного лучше и при изменении размера.

Последняя, ​​p4, великолепна

Paul 'Joey' McMurdie 02.02.2022 23:23

Еще один способ сделать это с помощью gridExtra.

library(ggplot2)
library(patchwork)
library(gridExtra)

p1 <- ggplot(mtcars) + 
  geom_point(aes(mpg, disp)) + 
  labs(x = "mpg") +
  theme(axis.title.y = element_blank())

p2 <- ggplot(mtcars) + 
  geom_boxplot(aes(gear, disp, group = gear)) + 
  labs(x = "gear") +
  theme(axis.title.y = element_blank())

p3 <- ggplot(mtcars) + 
  geom_point(aes(hp, wt, colour = mpg)) + 
  ggtitle('Plot 3')


grid.arrange(patchworkGrob(p1 / (p2 | p3)), left = "disp_disp_disp_disp_disp")

Другие вопросы по теме