rggplot2annotategeom-segment

Plot arrow outside of figure instead of inside


I am trying to plot the arrow outside of the figure. I have tried a number of different options, but they keep plotting the arrow inside the figure. Is there a way to plot it outside the bounding box?

set.seed(57)
discharge <- data.frame(date = seq(as.Date("2011-01-01"), as.Date("2011-12-31"), by="days"),
discharge = rexp(365))

test <- ggplot(discharge) +
geom_line(aes(x = date, y = discharge)) +
geom_hline(yintercept = 5.5, linetype= "dashed", color = "red") + 
geom_text(aes(x = date[13], y = 5.5, label = "High"))

(test + annotate(geom = "segment", x = as.Date("2011-01-01"), 
              y = -1, xend = as.Date("2011-01-01"), yend = 0, 
              arrow = arrow(length = unit(3, "mm")), color = "red"))

Solution

  • One of the nice features introduced with ggplot2 >= 3.5.0 (!!!) is that it is now possible to place annotations as numbers in relative units of the plot panel (see here). To this end we have to wrap the positions inside annotate in I(). Doing so has the advantage that adding an annotation does not affect the range of the scale.

    Additionally, as usual we have to set clip="off" in coord_cartesian and make some room outside of the plot panel e.g. via plot.margin.

    set.seed(57)
    discharge <- data.frame(
      date = seq(as.Date("2011-01-01"), as.Date("2011-12-31"), by = "days"),
      discharge = rexp(365)
    )
    
    library(ggplot2)
    
    packageVersion("ggplot2")
    #> [1] '3.5.0'
    
    test <- ggplot(discharge) +
      geom_line(aes(x = date, y = discharge)) +
      geom_hline(yintercept = 5.5, linetype = "dashed", color = "red") +
      geom_text(data = ~.x[13, , drop = FALSE], aes(x = date, y = 5.5, label = "High"))
    
    test + 
      annotate(
        geom = "segment", x = as.Date("2011-01-01"),
        y = I(-.125), xend = as.Date("2011-01-01"), yend = I(-.05),
        arrow = arrow(length = unit(3, "mm")), color = "red"
      ) +
      coord_cartesian(clip = "off") +
      theme(plot.margin = margin(5.5, 5.5, 22, 5.5))