ggplot2: как легко совместить несколько графиков в одном, часть 2 +14


Эта статья шаг за шагом покажет, как совместить несколько ggplot-графиков на одной или нескольких иллюстрациях, с помощью вспомогательных функций, доступных в пакетах R ggpubr, cowplot и gridExtra. Также опишем, как экспортировать полученные графики в файл.

Изменение расположения по строкам или столбцам


Используем пакет ggpubr


Воспользуемся вложенными функциями ggarrange() для изменения расположения графиков по строкам или столбцам.

Например, код ниже делает следующее:

  • диаграмма разброса (sp) будет находиться в первой строке и занимать две колонки
  • диаграмма рассеивания (bxp) и точечная диаграмма (dp) будут занимать вторую строку и две разных колонки

ggarrange(sp,  # Первая строка с диаграммой разброса
          ggarrange(bxp, dp, ncol = 2, labels = c("B", "C")), # Вторая строка с диаграммой рассеивания и точечной диаграммой
          nrow = 2, 
          labels = "A"   # Метки диаграммы разброса
          ) 



Используем пакет cowplot


Следующую комбинацию функций [из пакета cowplot] можно использовать, чтобы расположить графики в определенных местах заданного размера: ggdraw() + draw_plot() + draw_plot_label().

ggdraw(). Инициализируем пустое полотно:


ggdraw()

Обратите внимание, что по умолчанию координаты изменяются от 0 до 1, и точка (0, 0) находится в нижнем левом углу полотна (см. иллюстрацию ниже).


draw_plot(). Располагает график где-то на полотне:


draw_plot(plot, x = 0, y = 0, width = 1, height = 1)

  • plot: график для размещения (ggplot2 или gtable)
  • x, y: координаты x/y левого нижнего угла графика
  • width, height: ширина и высота графика

draw_plot_label(). Добавляет метку в правом верхнем углу графика


Может работать с векторами меток с ассоциированными координатами.

draw_plot_label(label, x = 0, y = 1, size = 16, ...)

  • label: вектор меток
  • x, y: вектор с х/у координатами каждой метки соответственно
  • size: размер шрифта метки

Например, так можно комбинировать несколько графиков разного размера с определенным расположением:

library("cowplot")
ggdraw() +
  draw_plot(bxp, x = 0, y = .5, width = .5, height = .5) +
  draw_plot(dp, x = .5, y = .5, width = .5, height = .5) +
  draw_plot(bp, x = 0, y = 0, width = 1, height = 0.5) +
  draw_plot_label(label = c("A", "B", "C"), size = 15,
                  x = c(0, 0.5, 0), y = c(1, 1, 0.5))



Используем пакет gridExtra


Функция arrangeGrop()gridExtra] помогает изменить расположение графиков по строкам или столбцам.

Например, код ниже делает следующее:

  • диаграмма разброса (sp) будет находиться в первой строке и занимать две колонки
  • диаграмма рассеивания (bxp) и точечная диаграмма (dp) будут занимать вторую строку и две разных колонки

library("gridExtra")
grid.arrange(sp,                            # Первая строка с одним графиком на две колонки
             arrangeGrob(bxp, dp, ncol = 2),# Вторая строка с двумя графиками в двух колонках
             nrow = 2)                      # Количество строк



В функции grid.arrange() можно также использовать аргумент layout_matrix для создания сложного взаимного расположения графиков.

В коде ниже layout_matrix — матрица 2х2 (2 строки и 2 столбца). Первая строка — все единицы, там, где первый график, занимающий две колонки; вторая строка содержит графики 2 и 3, каждый из которых занимает свою колонку.

grid.arrange(bp,                                # столбчатая диаграмма на две колонки
             bxp, sp,                               # диаграммы рассеивания и разброса
             ncol = 2, nrow = 2, 
             layout_matrix = rbind(c(1,1), c(2,3)))



Также можно добавить аннотацию к выводу функции grid.arrange(), используя вспомогательную функцию draw_plot_label()cowplot].

Для того, чтобы легко добавлять аннотации к выводам функций grid.arrange() или arrangeGrob() (тип gtable), сначала нужно преобразовать их в тип ggplot с помощью функции as_ggplot()ggpubr]. После можно применять к ним фунцию draw_plot_label()cowplot].

library("gridExtra")
library("cowplot")
# Упорядочиваем графики с arrangeGrob
# возвращает тип gtable (gt)
gt <- arrangeGrob(bp,                               # столбчатая диаграмма на две колонки
             bxp, sp,                               # диаграммы рассеивания и разброса
             ncol = 2, nrow = 2, 
             layout_matrix = rbind(c(1,1), c(2,3)))
# Добавляем метки к упорядоченным графикам
p <- as_ggplot(gt) +                                # преобразуем в ggplot
  draw_plot_label(label = c("A", "B", "C"), size = 15,
                  x = c(0, 0, 0.5), y = c(1, 0.5, 0.5)) # Добавляем метки
p



В коде выше мы использовали arrangeGrob() вместо grid.arrange(). Основное отличие этих двух функций состоит в том, что grid.arrange() автоматически выводит упорядоченные графики. Поскольку мы хотели добавить аннотацию к графикам до того, как их нарисовать, предпочтительно в таком случае использовать функцию arrangeGrob().

Используем пакет grid


Пакет grid позволяет задать сложное взаимное расположение графиков с помощью функции grid.layout(). Он также предоставляет вспомогательную функцию viewport()для задания региона, или области видимости. Функция print() применяется для размещения графиков в заданном регионе.

Шаги можно описать так:

  1. Создать графики: p1, p2, p3, ….
  2. Перейти на новую страницу с помощью функции grid.newpage()
  3. Создать расположение 2X2 — количество столбцов = 2; количество строк = 2
  4. Задать область видимости: прямоугольная область на графическом устройстве
  5. Напечатать график в области видимости

library(grid)
# Перейти на новую страницу
grid.newpage()
# Создать расположение: nrow = 3, ncol = 2
pushViewport(viewport(layout = grid.layout(nrow = 3, ncol = 2)))
# Вспомогательная функция для задания области в расположении
define_region <- function(row, col){
  viewport(layout.pos.row = row, layout.pos.col = col)
} 
# Упорядочить графики
print(sp, vp = define_region(row = 1, col = 1:2))   # Расположить в двух колонках
print(bxp, vp = define_region(row = 2, col = 1))
print(dp, vp = define_region(row = 2, col = 2))
print(bp + rremove("x.text"), vp = define_region(row = 3, col = 1:2))



Использование общей легенды для совмещенных ggplot-графиков


Чтобы задать общую легенду для нескольких упорядоченных графиков, можно использовать функцию ggarrange()ggpubr] с такими аргументами:

  • common.legend = TRUE: сделать общую легенду
  • legend: задать положение легенды. Разрешенное значение — одно из c(“top”, “bottom”, “left”, “right”)

ggarrange(bxp, dp, labels = c("A", "B"),
          common.legend = TRUE, legend = "bottom")



Диаграмма разброса с графиками плотности безусловного распределения


# Диаграмма разброса, цвет по группе ("Species")
sp <- ggscatter(iris, x = "Sepal.Length", y = "Sepal.Width",
                color = "Species", palette = "jco",
                size = 3, alpha = 0.6)+
  border()                                         
# График плотности безусловного распределения по x (панель сверху) и по y (панель справа)
xplot <- ggdensity(iris, "Sepal.Length", fill = "Species",
                   palette = "jco")
yplot <- ggdensity(iris, "Sepal.Width", fill = "Species", 
                   palette = "jco")+
  rotate()
# Почистить графики
yplot <- yplot + clean_theme() 
xplot <- xplot + clean_theme()
# Упорядочить графики
ggarrange(xplot, NULL, sp, yplot, 
          ncol = 2, nrow = 2,  align = "hv", 
          widths = c(2, 1), heights = c(1, 2),
          common.legend = TRUE)



В следующей части:

  • смешиваем таблицу, текст и ggplot2-графики
  • добавляем графический элемент в ggplot (таблицу, диаграмму рассеивания, фоновое изображение)
  • располагаем графики на нескольких страницах
  • вложенное взаиморасположение
  • экспорт графиков




К сожалению, не доступен сервер mySQL