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
- Firstly, the graph seems to always start from arbitrary points on the circle, while the default should be 90 degrees (12 o'clock). Setting different values for the offset argument, which should be passed to
[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. - The second issue is that I wish for overlapping edges (those connecting the same vertices) to be very slightly offset, but usual ggplot2 functions such as
position_dodge()
shift the entire edge. I don't want any shifts where edges are connected to the vertices, but withoutposition_dodge()
or similar functions (or withposition_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.
CodePudding user response:
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!