Search code examples
rggplot2ggpmisc

Change Arrow linewidth/size in stat_valleys/stat_peaks


I am trying to reproduce the solution here, but alter the arrows to be thicker. I am a bit stumped on how to accomplish this.

I have looked into using the arrows function since it has the ability to implement lwd but do not know how to get the mapping to x0, x1, y0, y1. Is there additional arguments that can be passed on to layer that can change the linewidth of the arrows?


Solution

  • I first answer assuming that the question is about stat_valleys() and stat_peaks() from package 'ggpmisc' and that the geom in use is geom_segment() from 'ggplot2', rather than geom_text_s() or geom_label_s() from package 'ggpp' or geom_label_repel() or geom_text_repel() from pacakge 'ggrepel'. I will use stat_peaks() for the answer as stat_valleys() works similarly.

    I have used a constant value for the linewidth aesthetic, but it is possible to map a variable instead. Arrow tips can be added to segments, segments are most frequently used without arrow tips.

    library(ggpmisc)
    library(grid)
    
    # lynx is a time.series object
    lynx_num.df <-
      try_tibble(lynx,
                 col.names = c("year", "lynx"),
                 as.numeric = TRUE) # years -> as numeric
    
    ggplot(lynx_num.df, aes(year, lynx)) +
      geom_line() +
      stat_peaks(aes(yend = after_stat(y) + 500), 
                 geom = "segment", colour = "red", 
                 arrow = arrow(length = unit(0.03, "npc"), ends = "first" ),
                 linewidth = 1)
    

    Created on 2024-03-01 with reprex v2.1.0

    It is also possible to use geom_text_s(). In the documentation of stat_peaks() and stat_valleys() there are examples using geom_text_s(). In these examples the displacement that creates the arrow is obtained by nudging. These examples can be easily modified by making the label text transparent, which is a kludge, but also works in most cases.

    ggplot(lynx_num.df, aes(year, lynx)) +
      geom_line() +
      stat_peaks(colour = "red",
                 alpha = 0, alpha.target = "text",
                 geom = "text_s",
                 position = position_nudge_keep(x = 0, y = 400),
                 arrow = arrow(length = grid::unit(1.5, "mm")),
                 segment.linewidth = 0.75) +
      expand_limits(y = 7400)
    

    Created on 2024-03-01 with reprex v2.1.0