I have been trying to create a dendrogram with hierarchical edge bundling using the ggraph package, and have run into 2 major issues.
Questions and code are revised slightly for clarity
[layout_tbl_graph_dendrogram()]
2 also has no effect. Vertices 6 and 41, connected by the red and yellow edges, should be the first and last vertices and fall near 90 degrees.position_dodge()
shift the entire edge. I don't want any shifts where edges are connected to the vertices, but without position_dodge()
or similar functions (or with position_dodge(width=0)
) the red edge completely covers the yellow, as they share the same two vertices (6 and 41).Here's a reproducible example:
library(ggraph)
#> Loading required package: ggplot2
library(igraph)
#>
#> Attaching package: 'igraph'
#> The following objects are masked from 'package:stats':
#>
#> decompose, spectrum
#> The following object is masked from 'package:base':
#>
#> union
library(ggplot2)
# hierarchical structure
d1 <- data.frame(from="origin",
to=paste("group",
seq(1,4),
sep = ""))
d2 <- data.frame(from = rep(d1$to,
each = 9),
to = paste("subgroup",
seq(1,36),
sep = "_"))
hierarchy <- rbind(d1, d2)
# vertices data.frame
vertices <- data.frame(name = unique(c(as.character(hierarchy$from),
as.character(hierarchy$to))))
# graph object with igraph
mygraph <- graph_from_data_frame(hierarchy,
vertices = vertices)
# PROBLEM 1: setting offset has no effect, and graph seems to
# always start from an arbitrary angle rather than pi/2
ggraph(mygraph,
layout = 'dendrogram',
circular = TRUE,
offset = pi) +
geom_edge_diagonal(alpha = 0.1) +
# PROBLEM 2: overlapping connections cannot be dodged without shifting
# the point of connection on the vertices. e.g., position_dodge() with
# any width shifts the points of connection as well.
geom_conn_bundle(data = get_con(from = c(6, 6, 12, 20, 25, 30),
to = c(41, 41, 15, 25, 32, 39)),
position = position_dodge(width = 0.2),
alpha = 1,
width = 1,
colour = c(rep("#FFFF00", 100),
rep("#FF0000", 100),
rep("#0000FF", 100),
rep("#00FF00", 100),
rep("#00FFFF", 100),
rep("#FF00FF", 100)),
tension = 0.9) +
theme_void()
#> Warning: position_dodge requires non-overlapping x intervals
Created on 2021-11-03 by the reprex package (v2.0.1)
Thanks for reading!
Update: I can change vertex positions on the circle manually, just creating the layout using the create_layout() and then doing some trigonometry and changing the position values. It does solve problem1 but takes quite a bit of work. I can't think of anything regarding problem2 though.
For the first problem, I just ended up taking the layout file using create_layout()
, modifying the locations of the vertices manually (doing some basic trigonometry) before sending the file to ggraph()
. For the second problem, I just found all overlapping edges and split the connections dataframe into dataframes of non-overlapping edges, then passed them to geom_conn_bundle()
functions separately and with differing tension values. It would be excellent if someone could come up with a better answer to the first problem though! Here's the repository.