Search code examples
rggplot2labelplotmath

properly formatting a two-line caption in ggplot2


I am working on a custom function that can add two-line captions to plots and I want the caption to be formatted properly no matter what the user might choose to enter ("character" or "expression"). I have created a toy example below to illustrate two problems with the way the function has been currently implemented-

  1. When the caption is not NULL, the two lines are not aligned to the right.
  2. When an expression is entered, the concatenated caption gets completely mangled.

EDIT:

In case you have a different solution which achieves the same thing (if the user-provided caption is NULL, then the default one-line expression is printed as a caption, otherwise a two-line expression printed as a caption), I am also open to that.

It is important though that the class of the object remains "ggplot" because I would like to make further modifications to the resulting plot using ggplot2 functions.

# needed libraries
library(ggplot2)

# custom function to prepare a caption
caption_maker <- function(caption) {

  # if caption is not null then add line separator
  if (!is.null(caption)) {
    caption <- paste(caption, "; \n", sep = "")
  }

  # prepare the caption with additional info
  caption <- base::substitute(
    expr =
      paste(
        y,
        "In favor of null: ",
        "log"["e"],
        "(BF"["01"],
        ") = ",
        bf
      ),
    env = base::list(
      y = caption,
      bf = 123
    )
  )

  # return the message
  return(caption)
}

# custom function to add labels to the plot
plot_maker <-
  function(xlab = NULL,
             ylab = NULL,
             title = NULL,
             caption = NULL) {
    caption.text <- caption_maker(caption = caption)

    plot <- ggplot(mtcars, aes(wt, mpg)) + geom_point() +
      ggplot2::labs(
        x = xlab,
        y = ylab,
        title = title,
        caption = caption.text
      )

    # return the plot
    return(plot)
  }

# this works just fine
plot_maker(caption = NULL)

# this works but the caption is not aligned properly
plot_maker(caption = "This is mtcars dataset")

# this works but the caption is all mangled
plot_maker(
  caption =
    expression(paste(italic("Note"), ": This is mtcars dataset"))
)

Created on 2018-08-22 by the reprex package (v0.2.0.9000).


Solution

  • How about this:

    # needed libraries
    library(ggplot2)
    
    # custom function to prepare a caption
    caption_maker <- function(caption) {
    
      # prepare the caption with additional info
      caption <- base::substitute(
        atop(y,
             paste(
               "In favor of null: ",
               "log"["e"],
               "(BF"["01"],
               ") = ",
               bf
             )),
        env = base::list(
          bf = 123,
          y = caption
        )
      )
    
      # return the message
      return(caption)
    }
    
    # custom function to add labels to the plot
    plot_maker <-
      function(xlab = NULL,
               ylab = NULL,
               title = NULL,
               caption = NULL) {
        caption.text <- caption_maker(caption = caption)
    
        plot <- ggplot(mtcars, aes(wt, mpg)) + geom_point() +
          ggplot2::labs(
            x = xlab,
            y = ylab,
            title = title,
            caption = caption.text)
    
        # return the plot
        return(plot)
      }
    
    
    plot_maker(caption = NULL)
    plot_maker(caption = "This is mtcars:")
    plot_maker(xlab = "x Axis Title",
      caption = substitute(paste(italic("Note"), ": This is mtcars dataset"))
    )
    

    I got the atop idea from this question