thomasp85 / ggforce

Accelerating ggplot2
https://ggforce.data-imaginist.com
Other
916 stars 105 forks source link

Order of geom_edge_link plotting does not match order of input data for more than 9 edges #314

Closed mjsmith037 closed 7 months ago

mjsmith037 commented 9 months ago

When using geom_edge_link(), sorting the input graph edges does not have the expected effect on the plotting order of those edges (in particular when the number of edges is greater than 9).

library(tidyverse)
library(tidygraph)
library(ggraph)

# create a toy graph
g <- tbl_graph(edges=tibble(from=1:12, to=13:24), directed=FALSE) %E>%
  mutate(z=1:n()) %N>%
  mutate(type=c(rep(TRUE, 12), rep(FALSE, 12)))

# standardize layout for comparisons (and so that edges cross)
layout <- igraph::layout_as_bipartite(g) %>%
  {cbind(c(.[1:12,1], .[13:24,1] / -0.5 + 12), .[,2])}

We would expect the edges to be plotted in order (from top to bottom in the dataframe/tidygraph), however, we see that the ninth edge is actually on top (this is true regardless of the naming convention).

# does not work
ggraph(g, layout=layout) +
  geom_edge_link(aes(colour=z, label=z), width=3)

geom_edge_link0 seems to work, as does manually setting the group variable to be the same for all edges, so I suspect it has to do with assigning the group variable on line 197 of geom_edge_link.R.

# works!
ggraph(g, layout=layout) +
  geom_edge_link0(aes(colour=z), width=3)

# works!
ggraph(g, layout=layout) +
  geom_edge_link(aes(colour=z, label=z, group=I(1)), width=3)

The order of plotting is reminiscent of the order you get when sorting an integer range that has been converted to a character:

1:12 %>% as.character() %>% sort()
#>  [1] "1"  "10" "11" "12" "2"  "3"  "4"  "5"  "6"  "7"  "8"  "9"

and, indeed, considering the number of edges up to 100, the 99th edge is plotted last:

a <- 100
g <- tbl_graph(edges=tibble(from=1:a, to=(a+1):(2*a)), directed=FALSE) %E>%
  mutate(z=1:n()) %N>%
  mutate(type=c(rep(TRUE, a), rep(FALSE, a)))
layout <- igraph::layout_as_bipartite(g) %>%
  {cbind(c(.[1:a,1], .[(a+1):(2*a),1] / -0.5 + a), .[,2])}
ggraph(g, layout=layout, ncol=2) +
  geom_edge_link(aes(colour=(z==99), label=z), width=3)

Created on 2023-12-08 with reprex v2.0.2

mjsmith037 commented 9 months ago

Could be related to the issue mentioned in thomasp85/ggraph#279

thomasp85 commented 8 months ago

Moving this to ggforce since the underlying issue is in StatLink/GeomLink