2

There are multiple R packages for arc diagram such as ggraph or arcdiagram, but if there're more than one connection of different nature, it will show as overlapping arcs of the same radius connecting the same origin and destination. Is it possible to have arc of different radius representing different categories? Something like in this rough graph? Thanks! enter image description here

santoku
  • 3,297
  • 7
  • 48
  • 76

1 Answers1

2

We may use ggplot2 for that. Let the ending points be defined in df as

library(ggplot2)
df <- data.frame(x1 = 2, x2 = 3, y1 = 21, y2 = 15)

Then we use geom_curve. It seems that we cannot use the curvature parameter as an aesthetic, but lapply allows to deal with that:

ggplot(data = df, aes(x = x1, y = y1, xend = x2, yend = y2)) + 
  lapply(-5:5 / 10, function(cu) geom_curve(curvature = cu)) + theme_bw()

enter image description here

As to get multiple symmetric arcs I use various values of curvature defined as

A numeric value giving the amount of curvature. Negative values produce left-hand curves, positive values produce right-hand curves, and zero produces a straight line.

Julius Vainora
  • 47,421
  • 9
  • 90
  • 102
  • I wonder if it is possible to only change `cu` if the curves overlap, i.e. if the data rows are duplicated, if not then keep `cu` as default. For example this data: `df <- data.frame(x1 = c(2, 2, 1), x2 = c(3, 3, 4), y1 = 0, y2 = 0)` – zx8754 Mar 21 '18 at 16:15
  • @zx8754, the problem is that one `geom_curve` gives one arc for each data row. I think you need to start with `ggplot() +` and then keep adding arcs, like in `ggplot() + geom_curve(aes(x=1 ,y=2, xend = 3, yend = 0), curvature = 0.4) + geom_curve(aes(x=1 ,y=2, xend = 4, yend = 0), curvature = 0.2)` and so on. You may again use `lapply`, even a `for` loop to build some list `l` that will contain all the arcs, and also `duplicated(df)` is going to be useful to make things shorter. – Julius Vainora Mar 21 '18 at 17:55
  • Thank you, Ideally you should be able to pass cu as aes. – zx8754 Mar 21 '18 at 18:27
  • btw is there a way to add text label to the middle of each arc? – santoku Mar 22 '18 at 01:17
  • @santoku, I don't think there is a function to achieve that very easily. I think you need `geom_text` and then use some math to compute the coordinates for a given `curvature` value. 1) it seems that when `curvature = +-1`, we get a circle, 2) the gaps between the arcs in the middle seem to be proportional to the differences between `curvature` values. That should allow to calculate the middle of each arc. If you post it as a new question I will try to write an answer. – Julius Vainora Mar 22 '18 at 01:28
  • @santoku, actually it's more difficult than that. The curves are not at the same place all the time; be resizing the plot their position changes.. – Julius Vainora Mar 22 '18 at 02:50
  • @Julius thanks, I realized the same too, as the curvatures are kinda independent from the coordinates – santoku Mar 22 '18 at 13:09