Skip to content
Prev 398042 / 398502 Next

ggplot with arrows

On 8/1/2025 4:15 PM, Rui Barradas wrote:
Hello,

Sorry, my previous code is a bit messy.

You don't need to group, so I removed 'id' from the arrow_data.
It's better to define the arrows' end points x coordinates as variables, 
it makes it easier to change the plot at will.

And the function is now defined with the intercept as last argument.

f <- function(x, m, b = -25) m*x + b

# here plot with linetype = "dashed"
x0 <- c(-5, 5)
x1 <- c(-6, 6)
arrow_data <- data.frame(
   x = x0,
   y = f(x = x0, m = c(-10, 10)),
   xend = x1,
   yend = f(x = x1, m = c(-10, 10))
)

ggplot() +
   stat_function(
     fun = function(x) x^2,
     color = "blue", linewidth = 1.25,
     xlim = c(-5, 5)
   ) +
   geom_segment(
     data = arrow_data,
     mapping = aes(x = x, y = y, xend = xend, yend = yend),
     arrow = arrow(length = unit(0.5, "cm")),
     linewidth = 1.25,
     linetype = "dashed",
     inherit.aes = FALSE
   ) +
   theme_linedraw()


#---

# here the line type is the default solid, so
# start the arrows a bit away from the parabola, 0.1 away.
x0 <- c(-5.1, 5.1)
x1 <- c(-6, 6)
arrow_data <- data.frame(
   x = x0,
   y = f(x = x0, m = c(-10, 10)),
   xend = x1,
   yend = f(x = x1, m = c(-10, 10))
)

ggplot() +
   stat_function(
     fun = function(x) x^2,
     color = "blue", linewidth = 1.25,
     xlim = c(-5, 5)
   ) +
   geom_segment(
     data = arrow_data,
     mapping = aes(x = x, y = y, xend = xend, yend = yend),
     arrow = arrow(length = unit(0.5, "cm")),
     linewidth = 1.25,
     inherit.aes = FALSE
   ) +
   theme_linedraw()


Hope this helps,

Rui Barradas