Home > front end >  Single arrow at the end of a geom_bezier2 line
Single arrow at the end of a geom_bezier2 line

Time:11-09

I would like a curved line with a color gradient from one end to the other and a single arrow at the end using ggplot().

Using geom_curve I can get the correct curve and a nice looking arrow on the end. However, I haven't been able to add a color gradient to this. I am able to apply the color gradient and curve I am looking for by using geom_bezier2 but it looks like there are multiple arrows layered on top of each other. Is there a way to achieve the geom_bezier2 line with an arrow that looks like the geom_curve line?

#curved line with correct arrow but no color gradient
ggplot()  
  geom_curve(
    aes(x = -75, y = 42.5, xend = -85, yend = 30.5, size=3),
    curvature = -0.2, 
    lineend = "round",
    arrow = arrow(length = unit(0.3, "cm")))

#data frame for bezier
bezArrow <- data.frame(
  x = c(-75, -77, -85),
  y = c(42.5, 35, 30.5),
  color = c(3, 2, 1))

#curved line with color gradient but not the arrow I'm looking for
ggplot()  
  geom_bezier2(data = bezArrow, aes(x = x, y = y, color = color, linewidth = 3),
               lineend = 'round',
               arrow = arrow(length = unit(0.3, "cm"), ends = 'last'))  
  scale_color_gradient(high = 'grey', low = 'black')

Curved line with proper arrow using geom_curve but no color gradient.Curved line with proper gradient using geom_bezier2 but multiple arrows.

CodePudding user response:

This isn't really possible directly within ggforce, but you could do:

library(tidyverse)

ggforce:::bezierPath(bezArrow$x, bezArrow$y, 100) %>%
  as.data.frame() %>%
  rename(x = V1, y = V2) %>%
  mutate(xend = lead(x), yend = lead(y),
         color = approx(bezArrow$x, bezArrow$color, xout = x)$y,
         alpha = c(rep(0, n() - 2), 1, 1)) %>%
  ggplot(aes(x, y, xend = xend, yend = yend, color = color))  
  geom_segment(size = 3, lineend = "round", na.rm = TRUE)  
  geom_segment(size = 3, lineend = "round", aes(alpha = alpha),
            arrow = arrow(length = unit(0.3, "cm")), na.rm = TRUE)  
  scale_color_gradient(high = 'grey', low = 'black')  
  scale_alpha_identity()

enter image description here

  • Related