knitr::opts_chunk$set( collapse = TRUE, comment = "#>", fig.width = 6, fig.height = 6, warning = FALSE, message = FALSE )
One of the most convenient features of nplot() is that many aesthetics can be
mapped directly from graph attributes using a one-sided formula, instead of
building the vector of colors, shapes, or sizes by hand. This vignette walks
through the different formula interfaces available in netplot.
At a glance, nplot() understands two flavors of formula:
| Aesthetic | Formula | What it does |
|-----------------|------------------------|---------------------------------------------------------------------|
| vertex.color | ~ attr | Colors vertices by a vertex attribute (categorical, numeric, logical). |
| vertex.nsides | ~ attr | Maps each unique value of a vertex attribute to a distinct shape. |
| vertex.size | ~ attr | Scales vertex sizes from a numeric vertex attribute. |
| edge.width | ~ attr | Scales edge widths from a numeric edge attribute. |
| edge.color | ~ ego(...) + alter(...) | Blends edge colors from the two endpoints (see the last section).|
library(netplot) library(igraph)
We will use the UKfaculty network from the igraphdata package, a
friendship network among faculty at a UK university. It already carries a
Group vertex attribute (the school/department each person belongs to).
data("UKfaculty", package = "igraphdata") set.seed(225) l <- layout_with_fr(UKfaculty) # A couple of extra attributes to play with. We qualify igraph::degree() # explicitly because other packages (e.g. sna) also define a degree(). V(UKfaculty)$indeg <- igraph::degree(UKfaculty, mode = "in") V(UKfaculty)$is_hub <- V(UKfaculty)$indeg > stats::median(V(UKfaculty)$indeg)
vertex.color = ~ attrPassing vertex.color = ~ Group colors each vertex according to its Group
attribute. netplot detects the type of the attribute and picks a sensible
scale automatically:
When you print a plot built this way, netplot also draws a matching legend.
nplot(UKfaculty, layout = l, vertex.color = ~ Group)
The same syntax works for a numeric attribute, in which case a continuous color gradient is used. netplot detects that the attribute is continuous and draws a color bar (rather than a set of discrete keys) as the legend:
nplot(UKfaculty, layout = l, vertex.color = ~ indeg)
And for a logical attribute, mapping the two values to two colors:
nplot(UKfaculty, layout = l, vertex.color = ~ is_hub)
vertex.nsides = ~ attrvertex.nsides controls the number of sides of each vertex polygon (3 = a
triangle, 4 = a square, and larger numbers approximate a circle). Passing a
formula maps every unique value of the attribute to a distinct shape, which
is handy for encoding a second categorical variable alongside color:
nplot( UKfaculty, layout = l, vertex.color = ~ Group, vertex.nsides = ~ Group )
Because each group gets both a color and a shape, the figure stays readable even when printed in grayscale.
vertex.size = ~ attrvertex.size accepts a formula naming a numeric vertex attribute. Values
are rescaled to the range given by vertex.size.range, so more central actors
show up as larger nodes:
nplot( UKfaculty, layout = l, vertex.size = ~ indeg, vertex.size.range = c(.01, .04, 4) )
The formula interfaces compose, so a single nplot() call can encode several
variables at once — color, shape, and size — with very little code:
nplot( UKfaculty, layout = l, vertex.color = ~ Group, # color by department vertex.nsides = ~ Group, # distinct shape per department vertex.size = ~ indeg, # size by popularity (in-degree) vertex.size.range = c(.01, .04, 4) )
edge.width = ~ attrEdges have their own numeric attributes too. edge.width = ~ attr scales edge
widths from a numeric edge attribute; the values are normalized and mapped
to edge.width.range. Here we use the friendship weight:
nplot( UKfaculty, layout = l, edge.width = ~ weight, edge.width.range = c(1, 4, 4), skip.arrows = TRUE )
For vertex.nsides, vertex.size, and edge.width, the right-hand side of the
formula is evaluated with the graph's attributes in scope, so you are not
limited to bare attribute names — expressions work too, e.g.
edge.width = ~ log1p(weight) or vertex.size = ~ degree ^ 2.
edge.color = ~ ego(...) + alter(...)Edge colors use a richer, dedicated grammar built from two special terms:
ego() — the source vertex of the edge, andalter() — the target vertex.Each term borrows its color from the corresponding endpoint's vertex.color
(unless you pass an explicit col), and each accepts three tweaks:
col — the base color,alpha — transparency, from 0 (transparent) to 1 (opaque), andmix — how much weight that endpoint contributes when the two colors are
blended along the edge.The default, ~ ego(alpha = .1, col = "gray") + alter, fades each edge from a
faint gray at the source to the target's color. The panels below vary mix to
shift the blend from alter only to ego only:
gridExtra::grid.arrange( nplot(UKfaculty, layout = l, vertex.color = ~ Group, edge.color = ~ ego(mix = 0, alpha = .1) + alter(mix = 1)), nplot(UKfaculty, layout = l, vertex.color = ~ Group, edge.color = ~ ego(mix = .5, alpha = .1) + alter(mix = .5)), nplot(UKfaculty, layout = l, vertex.color = ~ Group, edge.color = ~ ego(mix = 1, alpha = .1) + alter(mix = 0)), ncol = 3 )
The attribute-mapping formulas for vertex color also work with
set_vertex_gpar(), so you can recolor an existing plot without rebuilding it:
np <- nplot(UKfaculty, layout = l) set_vertex_gpar(np, element = "core", fill = ~ Group)
vertex.color = ~ attr to color vertices by an attribute (with an
automatic legend), vertex.nsides = ~ attr to give each category a shape, and
vertex.size = ~ attr / edge.width = ~ attr to scale sizes and widths from
numeric attributes.edge.color = ~ ego(...) + alter(...) to blend edge colors from their
endpoints; see ?\netplot-formulae`` for the full grammar.nplot() call encode several variables
at once.
```Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.