#----------------------------------------------------------------------------#
#' Convert a list of ggplot objects into a (multi-page) PDF.
#'
#' Given a list of ggplot objects - arrange the plots on a page (with a specified number of plots columns/rows per page) and save as a (multi-page) PDF
#'
#' @details Maintained by: Clara Marquardt
#'
#' @export
#' @import ggplot2
#' @import plotflow
#' @import grid
#' @import gridExtra
#' @import scales
#'
#' @param ggplt_list List of ggplot objects (list - ggplot).
#' @param ncol_plot Number of plot columns on each page of the final PDF (integer) [default: 3].
#' @param nrow_plot Number of plot rows on each page of the final PDF (integer) [default: 3].
#' @param output_path Path where the final PDF is to be saved ("...../") (character).
#' @param output_file Namer under which the final PDF is to be saved ("...pdf") (character).
#' @param orientation Page orientation of the final PDF (character - "vertical"/"horizontal") [default: "vertical"].
#' @param share_legend Whether or not all plots on a page are to share one legend (logical - TRUE/FALSE) [default: FALSE].
#' @param quiet Whether to print status updates as individual pages are generated (logical - TRUE/FALSE) [default: FALSE].
#'
#' @return Generate and save a PDF with all plots.
#'
#' @examples \{dontrun
#' plot_1 <- ggplot(data=dia[1:15]) +
#' geom_bar(aes(x=dia_code)) +
#' theme_basic()
#' plot_list <- list(plot_1, plot_1, plot_1, plot_1,plot_1, plot_1, plot_1)
#' generate_pdf(ggplt_list=plot_list, ncol_plot=3, nrow_plot=2,
#' output_path="", output_file="merge_pdf_test", orientation="horizontal",
#' share_legend=FALSE, quiet=FALSE)
#'}
generate_pdf <- function(ggplt_list, ncol_plot=3, nrow_plot=3,
output_path, output_file, orientation="vertical", share_legend=FALSE, quiet=FALSE,
height_plot=NULL, width_plot=NULL, height_overall=NULL, width_overall=NULL) {
# define parameters
graph_cat <- length(ggplt_list)
graph_count <- nrow_plot*ncol_plot
graph_page <- ceiling(graph_cat/(graph_count))
# helper function
grid_arrange_shared_legend <- function(...) {
plots <- list(...)
g <- ggplotGrob(plots[[1]] + theme(legend.position="bottom"))$grobs
legend <- g[[which(sapply(g, function(x) x$name) == "guide-box")]]
lheight <- sum(legend$height)
grid.arrange(arrangeGrob(grobs=lapply(plots, function(x)
x + theme(legend.position="none")),ncol = ncol_plot, nrow=nrow_plot),
legend,
ncol = 1,
heights = unit.c(unit(1, "npc") - lheight, lheight))
}
# create a temporary directory
temp_folder_plot <- paste0("temp_plot_folder_", as.character(format(Sys.time(),
"%H_%M_%S_%d_%m_%y")), "_", toupper(sample(letters, 1)))
dir.create(temp_folder_plot)
# loop over graphs - generate PDF pages
temp1 <- 1
temp2 <- graph_count
for (k in 1:graph_page) {
if(orientation=="vertical") pdf(paste0(temp_folder_plot, "/", output_file, "_", k, ".pdf"))
else pdf(paste0(temp_folder_plot, "/", output_file, "_", k, ".pdf"),
height=ifelse(is.null(height_overall), 7.6, height_overall),
width=ifelse(is.null(width_overall), 11, width_overall))
temp2 <- min(temp2, length(plot_list))
onepage <- plot_list[temp1:temp2]
if(share_legend==FALSE) {
width_value <- NULL
height_value <- ifelse(is.null(height_plot), list(7.6/(ncol_plot+0.5)), list(height_plot))[[1]]
width_value <- NULL
width_value <- if(!is.null(width_plot)) width_value <- width_plot
do.call(grid.arrange,c(onepage, list(ncol=ncol_plot,
heights=rep(height_value,nrow_plot),
widths=rep(width_value,ncol_plot))))
} else {
do.call(grid_arrange_shared_legend,c(onepage))
}
dev.off()
temp1 <- temp1 + graph_count
temp2 <- temp2 + graph_count
if (quiet==FALSE) print(paste0("successfully generated page ", k,
" out of ", graph_page))
}
# ensure that the file list is correctly sorted
file_list <- file.path(temp_folder_plot, dir(temp_folder_plot))
file_list <- file_list[order(as.numeric(gsub("(.*)(_)([0-9]*)(\\.pdf)$", "\\3", file_list)))]
# merge the generated PDF & save
merge_PDF(pdf_list=file_list,
output_file=paste0(output_path, output_file, "_combined.pdf"))
# delete the temporary folder
unlink(temp_folder_plot, recursive=TRUE)
}
#----------------------------------------------------------------------------#
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.