ggforce icon indicating copy to clipboard operation
ggforce copied to clipboard

`GeomLine` support for `stat_link2` + other interpolation methods

Open mattansb opened this issue 8 months ago • 0 comments

Currently, the stat_link* family plots paths, but it would be great to have a version that works like GeomLine (i.e., drawn by along the x-value), or at least support for mixing with GeomLine:

library(ggplot2)
library(ggforce)

lines <- data.frame(
  x = c(5, 12, 15, 9, 6),
  y = c(17, 20, 4, 15, 5),
  xend = c(19, 17, 2, 9, 5),
  yend = c(10, 18, 7, 12, 1),
  width = c(1, 10, 6, 2, 3),
  colour = letters[1:5]
)

default geom_link2 stat and geom:

ggplot(lines, aes(x = x, y = y, colour = colour, size = width, group = 1)) +
  layer(stat = StatLink2, geom = ggforce:::GeomPathInterpolate,
        position = position_identity(),
        params = list(n = 500, lineend = 'round'))
#> Warning: Using `size` aesthetic for lines was deprecated in ggplot2 3.4.0.
#> ℹ Please use `linewidth` instead.
#> This warning is displayed once every 8 hours.
#> Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
#> generated.

doesn’t work with GeomLine:

ggplot(lines, aes(x = x, y = y, colour = colour, size = width, group = 1)) +
  layer(stat = StatLink2, geom = GeomLine,
        position = position_identity(),
        params = list(n = 10, lineend = 'round'))

sorting by x doesn’t solve it:

dplyr::arrange(lines, x) |> 
  ggplot(aes(x = x, y = y, colour = colour, size = width, group = 1)) +
  layer(stat = StatLink2, geom = GeomLine,
        position = position_identity(),
        params = list(n = 10, lineend = 'round'))

Created on 2023-10-25 with reprex v2.0.2


Additionally, if a "GeomLine" like behavior is supported, adding more interpolation variants would allow for drawing spline interpolated lines, and others.

For example:

xout <- seq(min(lines$x), max(lines$x), len = 50)
y_linear <- approx(lines$x, lines$y, xout = xout)[["y"]]
y_spline <- spline(lines$x, lines$y, xout = xout)[["y"]]

lines_interp <- data.frame(x = xout, y_linear, y_spline)

ggplot(lines_interp, aes(x)) + 
  # geom_link2(aes(y = y), data = lines, stat = GeomPath)
  geom_line(aes(y = y_linear, color = "linear")) + 
  geom_line(aes(y = y_spline, color = "spline")) + 
  geom_point(aes(y = y), data = lines, size = 3)

Created on 2023-10-25 with reprex v2.0.2

Thanks!

mattansb avatar Oct 25 '23 19:10 mattansb