Bundle edges using node groups
edge_bundle_nodegroups(
g,
nodegroups,
shape = NULL,
params = NULL,
midpoint = 0.5,
detail = 10,
draw_lines = TRUE,
nodegroup_midpoints = NULL,
linear_cor_threshold = 1,
bundle_style = getOption("jam.bundle_style", "bezier"),
bundle_self = FALSE,
verbose = FALSE,
debug = getOption("debug", FALSE),
...
)
igraph
that contains layout coordinates in
graph attributes, stored as igraph::graph_attr(g, "layout")
.
list
of node names, or object with
class "communities"
as produced by igraph::cluster_*
methods such as igraph::cluster_walktrap()
. Note that
every node must be represented.
character
(optional) used to override the vertex.shape
passed in params
. It is recycled to the number of nodes,
for example by igraph::vcount(g)
.
function
representing igraph
plotting parameters
used at rendering time. The output is also produced by
parse_igraph_plot_params()
for use in jam_igraph()
plotting, and is passed to other node and edge rendering
functions.
numeric
vector of one or more values ranging
from 0
to 1
that define control point positions along the
line between two nodegroup center coordinates. When one nodegroup
contains only one node, this line segment is shortened to end
at that node border after clipping the corresponding node shape.
The position along the line is defined relative to the first node
in the edge, toward the second node in the edge.
Using midpoint=0.5
guarantees the control point is the exact middle,
while midpoint=c(0.2, 0.8)
will use two control points at 20% and
80% distance along the line segment resulting in an edge that more
closely follows the line segment.
integer
number of intermediate points along
the spline to render for each edge.
logical
indicating whether to render the edge
splines after calculating them.
list
experimental support for defining
specific control points used by bundled edges. Not fully implemented
as yet. In future, it will require two nodegroups to be defined
for each set of control point coordinates, with no requirement
for the location of control points.
numeric
value between 0 and 1.
Coordinates for each edge, and intermediate control point
coordinates are used in xspline()
to create a curved spline
from node to node. However, when the nodes and intermediate
control points are already linear, the edge will be treated
as a linear edge. To test for linearity, cor()
correlation
is calculated, and values at or above linear_cor_threshold
are considered linear.
The driving problem is when the control point is colinear with two nodes, and the control point is positioned outside the two nodes. Without this modification, the line would appear to pass from one node beyond the other node, with an arrow (if directed) pointing back to the other node from the opposite direction.
character
string describing the type of curvature
to use for edge bundles:
"bezier"
: (default) calls bezier::bezier()
to define a bezier
curve using the edge control points.
"xspline"
: calls graphics::xspline()
to define an XSpline curve
using the edge control points, however the method is customized
to include each edge endpoint twice, which makes the intermediate
curve much rounder than normal.
"angular"
: calls graphics::xspline()
to define an XSpline curve
using the edge control points. This shape tends to appear angular,
thus the name.
"bezierPath"
: calls ggforce:::bezierPath()
when ggforce
is
available, producing a bezier curve using the edge control points.
Note this method appears identical to "bezier"
above, and will
likely be removed in a future release.
"subway"
: experimental method that uses the "angular"
appearance,
with more repeated intermediate control points intended to group
all bundled edges to the same linear segment. The intent is to "dodge"
edges along the line segment, similar to the appearance of subway maps,
however it is not fully implemented.
logical
to indicate whether edges that begin and
end in the same nodegroup should be bundled through the nodegroup
center coordinate.
bundle_self=FALSE
forces all edges within a nodegroup to be
rendered as straight lines, therefore not using the nodegroup center
as the control point.
bundle_self=TRUE
overrides the validation check that
requires the distance between center points of two nodegroups to
have distance at least 0.5% the layout coordinate span. It can
be a visual aid to have connections bundle through the center
of the nodegroup, especially when the nodegroup is almost fully
connected.
logical
indicating whether to print verbose output.
logical
indicating whether to plot debug output that
may be helpful in understanding the edge bundle control points.
To specify debug only for edge bundling, use the substring "bundl",
for example options("debug"="bundling")
.
additional arguments are ignored.
data.frame
with each edge spline point represented
on its own row, with breaks in edges defined by NA
coordinates.
This edge bundling technique relies upon some form of
node grouping, usually derived from network community
detection, or from bipartite nodesets (see
get_bipartite_nodeset()
for details.)
Given a set of node groups, edges are bundled entering and exiting each node group, along the linear path between the two node group center positions, using a spline function and intermediate control points.
The default spline uses the initial node positions, and the
midpoint along the line between the two respective node groups.
The midpoints can be adjusted with the argument midpoint
and a vector of one or more fractional positions between 0
and 1
.
A useful alternative is midpoint=c(0.3, 0.7)
which adds
two control points along the linear path between node group
centers, and tends to make the edges bundle closer together
for a longer distance.
When used with bipartite nodesets, edges are bundled between
each nodeset and individual nodes. The edge bundling rules are
the same, with the default midpoint=c(0.4, 0.6)
being centered at half
the distance between the nodeset center, and the single node.
In this case, the midpoint
is directional, always pointing
from the nodeset to the single node, therefore can be adjusted
closer to the nodeset center with midpoint=0.2
or closer to
the single node with midpoint=0.8
.
Other jam igraph functions:
cnet2df()
,
cnet2im()
,
cnetplotJam()
,
cnetplot_internalJam()
,
color_edges_by_nodegroups()
,
color_edges_by_nodes_deprecated()
,
color_edges_by_nodes()
,
color_nodes_by_nodegroups()
,
communities2nodegroups()
,
drawEllipse()
,
edge_bundle_bipartite()
,
enrichMapJam()
,
fixSetLabels()
,
flip_edges()
,
get_bipartite_nodeset()
,
igraph2pieGraph()
,
jam_igraph()
,
jam_plot_igraph()
,
label_communities()
,
layout_with_qfrf()
,
layout_with_qfr()
,
mem2emap()
,
memIM2cnet()
,
mem_multienrichplot()
,
nodegroups2communities()
,
rectifyPiegraph()
,
relayout_with_qfr()
,
removeIgraphBlanks()
,
removeIgraphSinglets()
,
reorderIgraphNodes()
,
rotate_igraph_layout()
,
spread_igraph_labels()
,
subgraph_jam()
,
subsetCnetIgraph()
,
subset_igraph_components()
,
sync_igraph_communities()
,
with_qfr()
# using community detection
karate <- igraph::make_graph("Zachary")
igraph::V(karate)$name <- as.character(seq_len(igraph::vcount(karate)))
# run any igraph::cluster_*()
wc <- igraph::cluster_louvain(karate)
# define list
nodegroups_wc <- split(igraph::V(karate)$name, wc$membership)
# bonus points for colorizing nodes and edges by community
igraph::V(karate)$color <- colorjam::group2colors(igraph::membership(wc));
igraph::V(karate)$label.color <- jamba::setTextContrastColor(igraph::V(karate)$color);
igraph::V(karate)$frame.color <- jamba::makeColorDarker(igraph::V(karate)$color);
karate <- color_edges_by_nodes(karate);
# update graph layout
layout_xy <- igraph::layout_with_graphopt(karate);
igraph::graph_attr(karate, "layout") <- layout_xy;
jam_igraph(karate,
edge_bundling="nodegroups",
nodegroups=nodegroups_wc,
use_shadowText=TRUE);