Draw a node-link diagram on a PlotSpec from vgraph(). mark_edges() draws
the edges (straight lines, batched), mark_nodes() the vertices (points),
mark_node_text() the vertex labels, and mark_edge_text() labels on the
edges. Draw order is fixed regardless of the order you pipe them: edges under
edge labels under nodes under node labels. Edges (and edge labels) default to
the edge table (vgraph()'s edge_data), nodes and node labels to the node
table; the x/y/xend/yend/label/name columns those tables carry are
mapped automatically, so bare mark_edges() |> mark_nodes() just works.
Usage
mark_edges(
plot,
...,
color = NULL,
linewidth = NULL,
alpha = NULL,
linetype = NULL,
arrow = FALSE,
routing = c("straight", "elbow"),
elbow_at = c("mid", "start", "end"),
elbow_axis = c("auto", "v", "h"),
gradient = FALSE,
auto = FALSE,
blend = NULL,
effects = list(),
sketch = NULL,
data = NULL
)
mark_edge_bundle(
plot,
...,
type = c("force", "divided", "stub", "path", "hammer", "mingle"),
color = NULL,
linewidth = NULL,
alpha = NULL,
linetype = NULL,
params = list(),
blend = NULL,
effects = list(),
sketch = NULL,
data = NULL
)
mark_flow_map(
plot,
...,
root,
type = c("spiral", "steiner"),
weight = NULL,
width_range = c(0.3, 3),
color = NULL,
alpha = NULL,
params = list(),
blend = NULL,
effects = list(),
sketch = NULL,
data = NULL
)
mark_nodes(
plot,
...,
size = NULL,
shape = NULL,
fill = NULL,
color = NULL,
alpha = NULL,
blend = NULL,
effects = list(),
sketch = NULL,
data = NULL
)
mark_node_text(
plot,
...,
label = NULL,
color = NULL,
size = NULL,
alpha = NULL,
dist = 0,
top_n = NULL,
by = NULL,
repel = FALSE,
box_padding = 1,
point_padding = 1,
min_segment_length = 2,
seed = NULL,
effects = list(),
blend = NULL,
data = NULL
)
mark_edge_text(
plot,
...,
label = NULL,
color = NULL,
size = NULL,
alpha = NULL,
angle = NULL,
effects = list(),
blend = NULL,
data = NULL
)
mark_node_hull(
plot,
...,
fill = NULL,
color = NULL,
alpha = 0.25,
expand = 0.08,
data = NULL
)
mark_node_pie(
plot,
cols,
...,
size = 4,
inner = 0,
fill = NULL,
color = "white",
linewidth = 0.5,
alpha = NA,
data = NULL
)Arguments
- plot
- ...
Encodings mapping node/edge attributes to aesthetics. Nodes:
size,color/fill,shape,alpha. Edges:color,linewidth,linetype,alpha. The position channels are supplied byvgraph()and need not be mapped.- linewidth
For
mark_edges(), the edge width; a constant or (viascale_edge_width()) a mapped expression such aslinewidth = weight. Formark_node_pie(), the wedge border width.- linetype
For
mark_edges(), the edge line type; a constant or (viascale_edge_linetype()) a mapped expression.- arrow
For
mark_edges(),TRUEto draw a closed arrowhead at each edge's target end (the directed convention),FALSE/NULLfor none, or avellum::vl_arrow()spec for full control (ends,type,length,angle) – e.g.arrow = vellum::vl_arrow(ends = "both", type = "open"). Edges are capped exactly at each endpoint's node boundary (per vertex, at any size/resolution), so the head sits on the node edge; self-loops are drawn as teardrop loops sized to the node, with the head on the node boundary.- routing
For
mark_edges(), edge routing:"straight"(default) or"elbow"– orthogonal right-angle steps for tree / DAG / dendrogram layouts (still straight segments, no curvature). Elbows keep node-boundary caps and arrowheads.- elbow_at, elbow_axis
For
mark_edges(routing = "elbow"), the corner placement and axis.elbow_atis"mid"(default, an S-bend at the midpoint), or"start"/"end"for the corner at the source / target –"start"gives the dendrogram bracket (siblings share a bar at the parent's level).elbow_axisis"auto"(default, the longer side),"v", or"h"to force which axis the corner steps along.- gradient
For
mark_edges(),TRUEto fade each (straight) edge from faint at its source to opaque at its target – a direction cue that needs no arrowhead (igraph'sedge.gradient). Ignored withrouting = "elbow".- auto
For
mark_edges(),TRUEto datashade a large graph's edges as a density raster (vellum::datashade_segments()) once the edge count exceeds the datashade threshold, instead of drawing each edge as a vector segment — the fast, overplotting-honest path for hairballs. The device-space refinements of the vector path (parallel-edge offsets, node-boundary caps, arrowheads, teardrop self-loops) do not apply to the rasterised edges.- blend
Optional blend mode (see
mark_point()).- effects
A list of layer render effects (
glow(),outline(),shadow()) applied to the mark at draw time. On the text marks (mark_node_text()/mark_edge_text()) onlyshadow()applies.- sketch
A
sketch()spec giving the layer a hand-drawn look,NA/FALSEto force it crisp, orNULL(default) to inherit.- data
Optional layer data; overrides the default table.
- type
For
mark_edge_bundle(), the bundling algorithm:"force"(default, force-directed / FDEB),"divided"(force-directed with direction-split bundles),"stub"(short stubs at each endpoint),"path"(shortest-path bundling),"hammer"(hammer bundling), or"mingle"(multilevel agglomerative edge bundling). Delegated toedgebundle::edge_bundle(). Formark_flow_map(), the flow-tree layout:"spiral"(default, angle-restricted spiral tree; edgebundle only) or"steiner"(approximate Steiner tree; also needs interp).- params
For
mark_edge_bundle(), a named list of extra arguments passed toedgebundle::edge_bundle()for the chosentype(e.g.params = list(compatibility_threshold = 0.8)). Formark_flow_map(), extra arguments for the flow-tree builder –edgebundle::flow_tree()whentype = "spiral"(e.g.list(alpha = 30)),edgebundle::tnss_tree()whentype = "steiner"(e.g.list(gamma = 0.9)). Empty by default.- root
For
mark_flow_map(), the source vertex the flow fans out from: a vertex name (matched against the node table) or a vertex index.- weight
For
mark_flow_map(), the per-edge flow volume (a mapped edge column, e.g.weight = migrants). Defaults to the graph'sweightedge attribute, or1if there is none.- width_range
For
mark_flow_map(), the drawn branch width rangec(min, max)(inlinewidthunits) that the computed flow is mapped onto. Defaultc(0.3, 3).- size, shape
For
mark_nodes(), the node size (mm) / shape; a constant or a mapped expression.sizeis also the label font size formark_node_text()/mark_edge_text().- fill, color, alpha
Convenience aesthetics; a constant or a mapped expression. For nodes,
fill(orcolor) is the marker colour; formark_edges(),color/alphamap through the edge scales.- label
For
mark_node_text(), the label expression (default the vertexname); formark_edge_text(), the edge label expression (no default – map an edge attribute, e.g.label = weight).- dist
For
mark_node_text(), a radial offset (mm) pushing each label outward from the layout centroid, so labels clear the node markers instead of sitting on them.0(default) centres the label on the vertex.- top_n, by
For
mark_node_text(), label only thetop_nvertices with the largestby(an edge/vertex metric column, e.g.by = degree) – the idiomatic "label just the hubs" filter.NULL(default) labels every vertex.- repel
For
mark_node_text(),TRUEto move overlapping labels apart with a force-directed layout (ggrepel-style), drawing a thin leader line back to each vertex.box_padding,point_padding,min_segment_length, andseedtune it exactly as inmark_text().- box_padding, point_padding, min_segment_length, seed
Repel tuning for
mark_node_text(repel = TRUE); seemark_text().- angle
For
mark_edge_text(), the label rotation: a constant in degrees, or"along"to rotate each label along its edge.NULL(default) draws horizontal labels.- expand
For
mark_node_hull(), the fraction to grow each hull outward from its centroid so it encloses the node markers (default0.08).- cols
For
mark_node_pie(), the compositional columns (a character vector of node-table column names, at least two) whose values size each node's wedges.- inner
For
mark_node_pie(), the inner-radius fraction:0(default) draws a pie,> 0a donut (e.g.0.5).
Value
The modified PlotSpec.
Details
Edge colour, opacity, and line type train on their own scales
(scale_edge_color(), scale_edge_alpha(), scale_edge_linetype(), plus
scale_edge_width()), independent of the node colour/alpha/linetype scales –
so a plot can map node fill to a discrete community and edge colour to a
continuous weight without the two legends colliding.
mark_node_text() has the label-legibility tools a dense graph needs:
repel = TRUE nudges overlapping labels apart with leader lines, dist pushes
labels radially clear of the node markers, top_n/by label only the hubs,
and effects = list(shadow()) drops a shadow behind each label so it stays
readable over edges. mark_edge_text() takes the same effects. (Only
shadow() applies to text; a glyph outline / glow is not available yet.)
Two more decorations: mark_node_hull() shades communities with a convex hull
behind the graph (grouped by a mapped fill, drawn under the edges), and
mark_node_pie() replaces node markers with pie / donut glyphs whose wedges
come from a set of compositional columns.
mark_edge_bundle() is a drop-in alternative to mark_edges() that routes the
edges as bundled curves instead of straight lines, so a hairball collapses
into a few legible trunks. It delegates the geometry to the edgebundle
package (install it) and draws the returned paths with the edge aesthetics –
type picks the algorithm ("force", "divided", "stub", "path",
"hammer", "mingle") and params passes tuning through. Bundled edges are
faint by default (alpha = 0.3) so overlapping trunks read as density.
mark_flow_map() draws a flow map: a single root fans out to many
destinations along smooth, merging branches whose width tracks the flow volume
(the Minard / migration-map idiom). It expects a one-to-many (star) graph
rooted at root, laid out at fixed coordinates; edge weight drives the flow.
type = "spiral" (default, an angle-restricted spiral tree) needs only
edgebundle; type = "steiner" (an approximate Steiner tree) additionally
needs interp. Branch width is mapped from the computed flow into
width_range.
These are thin over the point / segment / text marks; igraph need not be
installed to use them (only vgraph() needs it). mark_edge_bundle() and
mark_flow_map() also need the edgebundle package.
Examples
if (FALSE) { # \dontrun{
g <- igraph::make_graph("Zachary")
vgraph(g) |>
mark_edges(alpha = 0.5) |>
mark_nodes(size = 4, fill = "steelblue")
} # }
