Объединение участков с лоскутным рисунком, когда соотношение сторон участка равно 1

#r #ggplot2 #patchwork

Вопрос:

Я столкнулся с проблемой объединения графиков с использованием patchwork when theme(aspect.ratio = 1) . Приведено несколько примеров:

 library(tidyverse)
library(patchwork)

# Create the base plots
plotlist = list(
  fig1 = iris %>% 
    filter(Species == "setosa") %>% 
    ggplot(aes(x = Sepal.Length, y = Sepal.Width))  
    geom_point(),
  
  fig2 = iris %>% 
    filter(Species == "versicolor") %>% 
    ggplot(aes(x = Sepal.Length, y = Sepal.Width))  
    geom_point(),
  
  fig3 = iris %>% 
    filter(Species == "virginica") %>% 
    ggplot(aes(x = Sepal.Length, y = Sepal.Width))  
    geom_point()
)

# Here patchwork combines the plots nicely
plotlist$fig1 / (plotlist$fig2   plotlist$fig3)
 

 
# However, if we change the aspect.ratio to 1 things don't look so nice anymore
plotlist = lapply(plotlist, function(x) {
  x   theme(aspect.ratio = 1)
})

# Notice the large gap between plots. Instead, I would like the plots in the second row to be almost directly under the first row.
plotlist$fig1 / (plotlist$fig2   plotlist$fig3)
 

 # I tried setting the margins to zero, but that doesn't change anything
plotlist = lapply(plotlist, function(x) {
  x   theme(plot.margin = margin(0, 0, 0, 0, unit = "pt"))
})

plotlist$fig1 / (plotlist$fig2   plotlist$fig3)
 

Как я могу улучшить макет с помощью пэчворка? Участки во втором ряду должны иметь половину ширины первого ряда, как и первый участок, но соотношение сторон должно быть 1 для всех участков.

Комментарии:

1. Как насчёт plotlist$fig1 / (plotlist$fig2 plotlist$fig3) plot_layout(widths = 1)

2. Это хорошее предложение! Хотя это и решило проблему с расстоянием, это не дало желаемого макета (участки во втором ряду должны быть ограничены шириной первого ряда). Использование widths = c(1,2) этого тоже не решило.

3. Трудно понять правильно. Это приближает его. design <- "#1# #23" plotlist$fig1 / (plotlist$fig2 plotlist$fig3) plot_layout(design = design, widths = c(1,2)) . кстати, дизайн должен быть на 2-х кодовых линиях. Копирование вставки из комментария работает не очень хорошо.

4. К сожалению, это сработало не так, как ожидалось, и тоже не design <- c(area(1, 1), area(2, 3)) сработало . Без соотношения сторон ваше предложение работает, но когда aspect.ratio = 1 оно не дает желаемого макета.

Ответ №1:

Я также много боролся с фигурами, которые имеют пропорции, используя пэчворк.

Сначала я дам вам решение, а ниже я дам вам немного больше объяснений о том, почему я думаю, что этот код воспроизводит правильный рисунок.

Решение:

 design <- "
  33
  12
    "
plotlist$fig2   plotlist$fig3   plotlist$fig1   
    plot_layout(
        design = design, 
        heights = unit(c(2,-1),c("null","null"))
  )
 

введите описание изображения здесь


Дополнительная Информация:

Одна из ключевых идей, которая у меня была, заключается в том, что в аргументах и можно указать -1 нулевую единицу height width , которая указывает, что столбцы и строки с такой единицей должны адаптироваться к размерам фигур с фиксированным соотношением сторон (я думаю…).

Например, в приведенном ниже коде я приведу вам пример, где у меня есть фигура с соотношением сторон 1, которую я хочу сохранить, но я хочу иметь возможность указывать ширину других столбцов. Здесь я указал, что средний столбец должен иметь ширину 3 см (по крайней мере, когда я делал снимок экрана), правый столбец должен соответствовать соотношению сторон рисунка (например, -1 NULL единица измерения), а левый столбец может заполнить оставшееся пространство (например 1 NULL , единица измерения).

 library(ggplot2)
library(patchwork)
p1 <- ggplot(mtcars)   geom_point(aes(mpg, disp))
p2 <- ggplot(mtcars)   geom_boxplot(aes(gear, disp, group = gear))   theme(aspect.ratio = 1)
p1   p1   p2   plot_layout(widths = unit(c(1,3,-1), c("null","cm","null")))
 

введите описание изображения здесь

Но я не могу винить вас за то, что вы этого не знаете, поскольку это, похоже, нигде не задокументировано. Я сам тоже не совсем понимаю это и просто наткнулся на этот факт, заглянув в тестовую папку пакета patchwork.

Таким образом, чтобы создать вашу фигуру, я указываю, что последняя строка должна соответствовать соотношению сторон фигур, указывая при этом, что первая строка должна быть в два раза выше.


Будьте осторожны:

Обратите внимание, что дизайн был подобран тщательно, так как по какой-то причине следующий дизайн, похоже, не работает:

 design <- "
  11
  23
    "
plotlist$fig1   plotlist$fig2   plotlist$fig3 
 

Мне это кажется ошибкой, и я сообщу об этом как о проблеме разработчику.