R/finaliseGraph.R

Defines functions finaliseGraph

Documented in finaliseGraph

#' 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)
}
CommoditiesAI/graphHelpers documentation built on Jan. 1, 2022, 12:12 a.m.