#' finaliseGraph
#'
#' @description Function for finalising a plot - resize, add logo and caption, then save.
#'
#' Running this function will save the given or last plot with the correct guidelines for publication.
#' It will left align title, subtitle and caption, add the given logo at the bottom right and save it to a specified file name and location.
#'
#' Basis of this is the BBCplot function
#'
#' @param plot The name of the plot
#' @param caption The text for the caption. "None" for no caption. "Existing" for the existing caption
#' @param filename Desired file name
#' @param filepath Path to the directory
#' @param size Specify the size - "full", "half", "long", or "manual", which references height and width
#' @param width Width in pixels defaults to 640
#' @param height Height in pixels defaults to 450
#' @param unit Default is pixels (px), but accepts cm
#' @param logo_path File path for the logo image - PNG format
#' @param overwrite Whether to overwrite existing files, without asking
#'
#' @return An updated ggplot object invisibly
#'
#' @export
#'
#' @import dplyr grid ggplot2 ggpubr jpeg png rsvg stringr
finaliseGraph <- function(plot = last_plot(),
caption = "Source: CA&I\xA9",
filename,
filepath = getwd(),
size = "full",
width = 640,
height = 450,
unit = "px",
logo_path,
overwrite = TRUE) {
# Helper functions
# save_plot
save_plot <- function(plot_grid, width, height, save_file_path) {
grid.draw(plot_grid)
ggsave(filename = save_file_path, device = "png",
plot = plot_grid, width = (width/72), height = (height/72), bg = "white")
}
# Left_align
left_align <- function(plot, pieces){
grob <- ggplotGrob(plot)
n <- length(pieces)
grob$layout$l[grob$layout$name %in% pieces] <- 2
return(grob)
}
# create_footer
create_footer <- function(caption, logo_path) {
footer <- grobTree(linesGrob(x = unit(c(0, 1), "npc"), y = unit(1, "npc")), # Height of line
textGrob(caption, x = 0.004, hjust = 0, gp = gpar(fontsize = 10)), # Size of text
rasterGrob(readPNG(logo_path), x = 0.99, just = "right")) # Position of logo
return(footer)
}
# Fill in any missing options
if(missing(logo_path)) {
logo_path <- "http://commoditiesanalysis.co.uk/wp-content/uploads/2018/07/cropped-CAI-logo-4.png"
}
if(missing(filename)) {
filename <- glue::glue("UnnamedPlot_{format(Sys.time(), '%m%b_%H%M')}.png")
}
# Cope with plot being passed with or without quotes
if(any(class(plot) == "character")) {
plot <- get(plot)
}
# Check that the filen ame ends in .png, .jpg, or .gif. If not, add ".png" to the end of the file name
filename <- ifelse(sum(endsWith(filename, c(".png", ".jpg", ".gif")) == 1), filename, glue::glue("{filename}.png"))
save_file_path <- glue::glue("{filepath}/{filename}")
# If file exists, warn and offer to stop
if(!overwrite && file.exists(save_file_path)) {
goNoGo <- readline(glue::glue("File {filename} already exists in directory {filepath} - Overwrite? 'No' to stop "))
if(tolower(goNoGo) == "no") {
stop("Stopped to avoid overwriting existing saved graphic")
}
}
# if passed measures are in cm, convert to pixels
if(unit == str_to_lower("cm")) {
width <- width * 37.795276
height <- height * 37.795276
}
# Case of size, to give width and height
size <- str_to_lower(size)
height <- dplyr::case_when(
size == "full" ~ 450, # Full page graphic
size == "half" ~ 450, # Half page graphic, e.g. Powerpoint
size == "long" ~ 220, # Long graphic across page, e.g. up and over
size == "manual" ~ height, # User chosen
TRUE ~ 450) # Standard if not specified
width <- dplyr::case_when(
size == "full" ~ 650,
size == "half" ~ 315,
size == "long" ~ 650,
size == "manual" ~ width,
TRUE ~ 650)
# if logo is specified, use it, otherwise use default
link <- logo_path
# Check if file exists, if not, download it from the website
# logoFile <- tempfile(pattern = "logo", fileext = tools::file_ext(link))
if(file.exists(basename(link)) == FALSE) {
utils::download.file(link, destfile = basename(link), mode = 'wb')
}
# Convert files to PNG
# If file is .svg
if(tools::file_ext(link) == "svg") {
rsvg_png(basename(link), str_replace(basename(link), ".svg", ".png"))
}
# If file is .jpg
if(tools::file_ext(link) == "jpg") {
writePNG(readJPEG(basename(link)), str_replace(basename(link), ".jpg", ".png"))
}
logo <- readPNG(basename(link))
footer <- create_footer(caption, logo_path = glue::glue("{getwd()}/{basename(link)}"))
logo <- readPNG(basename(link))
# Build footer
# Create new caption, if wanted
if(str_to_lower(caption) == "existing") {
caption <- plot$labels$caption
plot$labels$caption <- NULL
}
if(str_to_lower(caption) == "none") {
caption <- " "
plot$labels$caption <- NULL
}
if(str_to_lower(caption) == "keep") {
caption <- " "
}
footer <- create_footer(caption, logo_path = glue::glue("{getwd()}/{basename(link)}"))
# Draw left-aligned grid
plot_left_aligned <- left_align(plot, c("subtitle", "title", "caption"))
plot_grid <- ggarrange(plot_left_aligned, footer,
ncol = 1, nrow = 2,
heights = c(1, 0.065/(height/450))) # Changes the size of logo
# Save the plot
message(glue::glue("Saving graphic to {save_file_path}"))
save_plot(plot_grid, width, height, save_file_path)
# Return (invisibly) a copy of the graph, so can be assigned to a variable or ignored
invisible(plot_grid)
}
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.