Ggplot2: графики на нескольких страницах

Я рисую графики, используя ggplot2, и у меня есть функция facet_wrap для создания нескольких графиков (~ 51), но все они отображаются на одной странице. Теперь после поиска я узнал, что ggplot2 не может размещать графики на нескольких страницах.

Есть ли способ сделать это? Я рассмотрел этот вопрос (Несколько графиков на нескольких страницах с помощью ggplot) и попробовал код с небольшим успехом.

Вот мой код для моих графиков, он производит ~ 51 график на одной странице, что делает их очень маленькими и труднодоступными, если бы я мог напечатать это до 1 графа на страницу в pdf, это было бы здорово:

ggplot(indbill, aes(x = prey, y = weight), tab) +
geom_polygon(aes(group = load, color = capture), fill = NA, size = 0.75) +
facet_wrap(~ individual) +
theme(axis.ticks.x = element_blank(),
    axis.text.x = element_text(size=rel(0.5)),
    axis.ticks.y = element_blank(),
    axis.text.y = element_blank()) +
xlab("") + ylab("") +
guides(color = guide_legend(ncol=2)) +
coord_radar()

Если кто-то может написать небольшой код и объяснить его мне, это было бы здорово!

Спасибо!

Ответ 1

Один из вариантов заключается в том, чтобы просто отобразить, скажем, шесть уровней individual за один раз, используя тот же самый код, который вы используете сейчас. Вам просто нужно будет повторять его несколько раз, один раз для каждого подмножества ваших данных. Вы не предоставили образцы данных, поэтому здесь приведен пример использования фрейма данных Baseball:

library(ggplot2)
library(vcd) # For the Baseball data
data(Baseball)

pdf("baseball.pdf", 7, 5)
for (i in seq(1, length(unique(Baseball$team87)), 6)) {
   print(ggplot(Baseball[Baseball$team87 %in% levels(Baseball$team87)[i:(i+5)], ], 
                  aes(hits86, sal87)) + 
    geom_point() +
    facet_wrap(~ team87) +
    scale_y_continuous(limits=c(0, max(Baseball$sal87, na.rm=TRUE))) +
    scale_x_continuous(limits=c(0, max(Baseball$hits86))) +
    theme_bw())
}
dev.off()

В приведенном выше коде будет создан PDF файл с четырьмя страницами графиков, каждый из которых имеет шесть граней на странице. Вы также можете создать четыре отдельных файла PDF, по одному для каждой группы из шести фасетов:

for (i in seq(1, length(unique(Baseball$team87)), 6)) {
pdf(paste0("baseball_",i,".pdf"), 7, 5)
  ...ggplot code...
dev.off()
}

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

Сначала создайте все графики. Мы будем использовать team87 как наш столбец фасетки. Поэтому мы хотим сделать один график для каждого уровня team87. Мы сделаем это, разделив данные на team87 и сделав отдельный график для каждого подмножества данных.

В приведенном ниже коде split разбивает данные на отдельные кадры данных для каждого уровня team87. Оболочка lapply последовательно подает каждый подмножество данных в ggplot для создания графика для каждой команды. Мы сохраняем вывод в plist, список (в данном случае) 24 графиков.

plist = lapply(split(Baseball, Baseball$team87), function(d) {
  ggplot(d, aes(hits86, sal87)) + 
    geom_point() +
    facet_wrap(~ team87) +
    scale_y_continuous(limits=c(0, max(Baseball$sal87, na.rm=TRUE))) +
    scale_x_continuous(limits=c(0, max(Baseball$hits86))) +
    theme_bw() +
    theme(plot.margin=unit(rep(0.4,4),"lines"),
          axis.title=element_blank())
})

Теперь мы выложим шесть графиков в файл PDF. Ниже приведены два варианта: один с четырьмя отдельными PDF файлами, каждый из которых имеет шесть графиков, а другой - с одним четырехстраничным PDF файлом. Я также вставил на один из участков внизу. Мы используем grid.arrange для размещения графиков, включая использование аргументов left и bottom для добавления заголовков осей.

library(gridExtra)

# Four separate single-page PDF files, each with six plots
for (i in seq(1, length(plist), 6)) {
  pdf(paste0("baseball_",i,".pdf"), 7, 5)
  grid.arrange(grobs=plist[i:(i+5)], 
               ncol=3, left="Salary 1987", bottom="Hits 1986")
  dev.off()
}

# Four pages of plots in one PDF file
pdf("baseball.pdf", 7, 5)
for (i in seq(1, length(plist), 6)) {
  grid.arrange(grobs=plist[i:(i+5)], 
               ncol=3, left="Salary 1987", bottom="Hits 1986")
}
dev.off()

Ответ 2

Существует несколько способов разбивки на страницы: ggforce или gridExtra :: marrangeGrob. Смотрите также этот ответ для другого примера.

ggforce:

library(ggplot2)
library(ggforce)

# Standard facetting: too many small plots
ggplot(diamonds) +
  geom_point(aes(carat, price), alpha = 0.1) +
  facet_wrap(~cut:clarity, ncol = 3)

# Pagination: page 1
ggplot(diamonds) +
  geom_point(aes(carat, price), alpha = 0.1) +
  facet_wrap_paginate(~cut:clarity, ncol = 3, nrow = 3, page = 1)

# Pagination: page 2
ggplot(diamonds) +
  geom_point(aes(carat, price), alpha = 0.1) +
  facet_wrap_paginate(~cut:clarity, ncol = 3, nrow = 3, page = 2)

# Works with grid as well
ggplot(diamonds) +
  geom_point(aes(carat, price), alpha = 0.1) +
  facet_grid_paginate(color~cut:clarity, ncol = 3, nrow = 3, page = 4)

gridExtra:

library(gridExtra)

set.seed(123)
pl <- lapply(1:11, function(.x) 
  qplot(1:10, rnorm(10), main=paste("plot", .x)))

ml <- marrangeGrob(pl, nrow=2, ncol=2)

## non-interactive use, multipage pdf
## ggsave("multipage.pdf", ml)
## interactive use; calling 'dev.new' multiple times
ml

Создано 2018-08-09 пакетом представлением (v0.2.0.9000).

Ответ 3

что-то вроде:

by(indbill, indbill$individual, function (x){
    ggplot(x, aes(x = prey, y = weight), tab) +
    geom_polygon(aes(group = load, color = capture), fill = NA, size = 0.75) +
    theme(axis.ticks.x = element_blank(),
        axis.text.x = element_text(size=rel(0.5)),
        axis.ticks.y = element_blank(),
        axis.text.y = element_blank()) +
    xlab("") + ylab("") +
    guides(color = guide_legend(ncol=2)) +
    coord_radar()
}