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?
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