Эта статья шаг за шагом покажет, как совместить несколько ggplot-графиков на одной или нескольких иллюстрациях, с помощью вспомогательных функций, доступных в пакетах R ggpubr, cowplot и gridExtra. Также опишем, как экспортировать полученные графики в файл.
Cмешиваем таблицу, текст и ggplot2-графики
В этом разделе покажем, как вывести таблицу и текст вместе с графиком. Будем использовать набор данных iris.
Начнем с создания таких графиков:
- график плотности переменной Sepal.Length. Функция R:
ggdensity()
[в ggpubr] - сводная таблица, содержащая описательные статистики (среднее, стандартное отклонение, т.д.) Sepal.Length
- Функция R для вычисления описательных статистик:
desc_statby()
[в ggpubr] - Функция R для создания таблицы с текстом:
ggtexttable()
[в ggpubr]
- Функция R для вычисления описательных статистик:
- абзац текста. Функция R:
ggparagraph()
[в ggpubr]
Завершим, скомбинировав все три графика с помощью функции ggarrange()
[в ggpubr].
# График плотности "Sepal.Length"
#::::::::::::::::::::::::::::::::::::::
density.p <- ggdensity(iris, x = "Sepal.Length",
fill = "Species", palette = "jco")
# Вывести сводную таблицу Sepal.Length
#::::::::::::::::::::::::::::::::::::::
# Вычислить описательные статистики по группам
stable <- desc_statby(iris, measure.var = "Sepal.Length",
grps = "Species")
stable <- stable[, c("Species", "length", "mean", "sd")]
# График со сводной таблицей, тема "medium orange" (средний оранжевый)
stable.p <- ggtexttable(stable, rows = NULL,
theme = ttheme("mOrange"))
# Вывести текст
#::::::::::::::::::::::::::::::::::::::
text <- paste("iris data set gives the measurements in cm",
"of the variables sepal length and width",
"and petal length and width, respectively,",
"for 50 flowers from each of 3 species of iris.",
"The species are Iris setosa, versicolor, and virginica.", sep = " ")
text.p <- ggparagraph(text = text, face = "italic", size = 11, color = "black")
# Разместить графики на странице
ggarrange(density.p, stable.p, text.p,
ncol = 1, nrow = 3,
heights = c(1, 0.5, 0.3))
Добавляем графический элемент в ggplot
Для добавления таблиц, графиков или других элементов на основе таблиц в рабочую область ggplot есть функция annotation_custom()
[в ggplot2]. Упрощенный формат:
annotation_custom(grob, xmin, xmax, ymin, ymax)
- grob: внешний графический элемент для отображения
- xmin, xmax: x-расположение в координатах (горизонтальное расположение)
- ymin, ymax: y-расположение в координатах (вертикальное расположение)
Помещаем таблицу в ggplot
Используем графики density.p и stable.p, созданные в предыдущем разделе.
density.p + annotation_custom(ggplotGrob(stable.p),
xmin = 5.5, ymin = 0.7,
xmax = 8)
Помещаем диаграмму рассеивания в ggplot
- Создаем диаграмму разброса для y = “Sepal.Width” по x = “Sepal.Length” из набора данных iris. Функция R:
ggscatter()
[ggpubr]. - Создаем отдельно диаграмму рассеивания переменных х и у с прозрачным фоном. Функция R:
ggboxplot()
[ggpubr]. - Преобразуем диаграмму рассеивания в графический объект под названием “grob” в терминологии Grid. Функция R:
ggplotGrob()
[ggplot2]. - Поместим grob-ы диаграммы рассеивания внутрь диаграммы разброса. Функция R:
annotation_custom()
[ggplot2].
Поскольку помещенная внутрь диаграмма рассеивания накладывается в нескольких точках, для нее используется прозрачный фон.
# Диаграмма разброса по группам ("Species")
#::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
sp <- ggscatter(iris, x = "Sepal.Length", y = "Sepal.Width",
color = "Species", palette = "jco",
size = 3, alpha = 0.6)
# Диаграммы рассеивания переменных x/y
#::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
# Диаграмма рассеивания переменной x
xbp <- ggboxplot(iris$Sepal.Length, width = 0.3, fill = "lightgray") +
rotate() +
theme_transparent()
# Диаграмма рассеивания переменной у
ybp <- ggboxplot(iris$Sepal.Width, width = 0.3, fill = "lightgray") +
theme_transparent()
# Создать внешние графические объекты
# под названием “grob” в терминологии Grid
xbp_grob <- ggplotGrob(xbp)
ybp_grob <- ggplotGrob(ybp)
# Поместить диаграммы рассеивания в диаграмму разброса
#::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
xmin <- min(iris$Sepal.Length); xmax <- max(iris$Sepal.Length)
ymin <- min(iris$Sepal.Width); ymax <- max(iris$Sepal.Width)
yoffset <- (1/15)*ymax; xoffset <- (1/15)*xmax
# Вставить xbp_grob внутрь диаграммы разброса
sp + annotation_custom(grob = xbp_grob, xmin = xmin, xmax = xmax,
ymin = ymin-yoffset, ymax = ymin+yoffset) +
# Вставить ybp_grob внутрь диаграммы разброса
annotation_custom(grob = ybp_grob,
xmin = xmin-xoffset, xmax = xmin+xoffset,
ymin = ymin, ymax = ymax)
Добавляем фоновое изображение в ggplot2-графики
Импортировать фоновое изображение. Используйте или функцию readJPEG()
[в пакете jpeg], или функцию readPNG()
[в пакете png] в зависимости от формата фоновой картинки.
Чтобы протестировать пример ниже, убедитесь, что пакет png установлен. Можно его установить, используя команду install.packages(“png”)
.
# Импорт картинки
img.file <- system.file(file.path("images", "background-image.png"),
package = "ggpubr")
img <- png::readPNG(img.file)
Скомбинировать ggplot с фоновой картинкой. Функция R: background_image()
[в ggpubr].
library(ggplot2)
library(ggpubr)
ggplot(iris, aes(Species, Sepal.Length))+
background_image(img)+
geom_boxplot(aes(fill = Species), color = "white")+
fill_palette("jco")
Изменим прозрачность заливки в диаграммах разброса заданием аргумента alpha. Значение должно быть в промежутке [0, 1], где 0 — полная прозрачность, а 1 — отсутствие прозрачности.
library(ggplot2)
library(ggpubr)
ggplot(iris, aes(Species, Sepal.Length))+
background_image(img)+
geom_boxplot(aes(fill = Species), color = "white", alpha = 0.5)+
fill_palette("jco")
Еще один пример, накладывание карты Франции на ggplot2:
mypngfile <- download.file("https://upload.wikimedia.org/wikipedia/commons/thumb/e/e4/France_Flag_Map.svg/612px-France_Flag_Map.svg.png",
destfile = "france.png", mode = 'wb')
img <- png::readPNG('france.png')
ggplot(iris, aes(x = Sepal.Length, y = Sepal.Width)) +
background_image(img)+
geom_point(aes(color = Species), alpha = 0.6, size = 5)+
color_palette("jco")+
theme(legend.position = "top")
Располагаем графики на нескольких страницах
Если у вас длинный список ggplot-ов, скажем, n=20, возможно, вы захотите упорядочить их, разместив на нескольких страницах. Если на странице будет 4 графика, для 20 понадобится 5 страниц.
Функция ggarrange()
[в ggpubr] предоставляет удобное решение, чтобы расположить несколько ggplot-ов на нескольких страницах. После задания аргументов nrow и ncol функция ggarrange()
автоматически рассчитывает количество страниц, которое потребуется, чтобы разместить все графики. Она возвращает список упорядоченных ggplot-ов.
Например, код ниже
multi.page <- ggarrange(bxp, dp, bp, sp,
nrow = 1, ncol = 2)
возвращает две страницы с двумя графиками на каждой. Можно вывести каждую страницу вот так:
multi.page[[1]] # Вывести страницу 1
multi.page[[2]] # Вывести страницу 2
Упорядоченные графики можно экспортировать в pdf-файл с помощью функции ggexport()
[в ggpubr]:
ggexport(multi.page, filename = "multi.page.ggplot2.pdf")
Многостраничный вывод можно получить и с функцией marrangeGrob()
[в gridExtra].
library(gridExtra)
res <- marrangeGrob(list(bxp, dp, bp, sp), nrow = 1, ncol = 2)
# Экспорт в pdf-файл
ggexport(res, filename = "multi.page.ggplot2.pdf")
# Интерактивный вывод
res
Вложенное взаиморасположение с ggarrange()
Упорядочим графики, созданные в предыдущих разделах.
p1 <- ggarrange(sp, bp + font("x.text", size = 9),
ncol = 1, nrow = 2)
p2 <- ggarrange(density.p, stable.p, text.p,
ncol = 1, nrow = 3,
heights = c(1, 0.5, 0.3))
ggarrange(p1, p2, ncol = 2, nrow = 1)
Экспорт графиков
Функция R: ggexport()
[в ggpubr].
Сначала создадим список из 4 ggplot-ов, соответствующих переменным Sepal.Length, Sepal.Width, Petal.Length и Petal.Width в наборе данных iris.
plots <- ggboxplot(iris, x = "Species",
y = c("Sepal.Length", "Sepal.Width", "Petal.Length", "Petal.Width"),
color = "Species", palette = "jco"
)
plots[[1]] # Вывести первый график
plots[[2]] # Вывести второй график и т.д.
После можно экспортировать отдельные графики в файл (pdf, eps или png) (один график на странице). Можно упорядочить графики (2 на страницу) при экспорте.
Экспорт отдельных графиков в pdf (по одному на странице):
ggexport(plotlist = plots, filename = "test.pdf")
Упорядочьте и экспортируйте. Задайте nrow и ncol, чтобы вывести несколько графиков на одной странице:
ggexport(plotlist = plots, filename = "test.pdf",
nrow = 2, ncol = 1)
Автор: Анна Каплун