Change Arrow linewidth/size in stat_valleys/stat_peaks

31 Views Asked by At

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?

1

There are 1 best solutions below

0
Pedro J. Aphalo On BEST ANSWER

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