New! For animation examples, see Basic animation examples.
New! For interactive click animation examples, see Advanced animation examples.

The new grapjhs function makes it easy to plot interactive 3-d graph objects from the igraph package.

This vignette explores basic use of the graphjs function using the LeMis data included in the threejs package. The LeMis data contain character coappearance data for Victor Hugo’s novel Les Misérables, compiled in the Stanford Graph Database by Donaled Knuth (see http://www-cs-faculty.stanford.edu/~uno/sgb.html) and taken from the D3.js force directed graph example by Mike Bostock (http://bl.ocks.org/mbostock/4062045).

We explore the graphjs function by looking at the graph of character coappearance in Les Misérables. We then illustrate a few measures of network centrality and connectivity.

Interactivity in graphjs

Plots produced by graphjs are primarily designed for mouse interaction. They do also try to support touch interfaces with touch analogs of the indicated mouse operations.

An attempt is made to support touch equivalents to the mouse operations, but touch interfaces will likely not work as well as a traditional mouse or trackpad set up.

Also see the vignette on crosstalk interaction here: https://bwlewis.github.io/rthreejs/crosstalk.html .

A force directed graph

Let’s plot a force directed graph of the characters in Les Misérables. Each circle in the plot represents a character and an edge between circles indicates that the corresponding characters interacted in the novel. The colors are taken from http://bl.ocks.org/mbostock/4062045.

suppressPackageStartupMessages(library(threejs, quietly=TRUE))
data(LeMis)
graphjs(LeMis, vertex.size = 1)


Degree centrality

Perhaps most intuitive measure of graph centrality, degree centrality of a node simply counts the number of other nodes it’s connected to.

The following example computes degree centrality and adjusts the sizes of the nodes accordingly. Bigger nodes are connected to more nodes than smaller ones.

M = as_adjacency_matrix(LeMis)
v = Matrix::colSums(M)
v = v / max(v)    # normalize
graphjs(LeMis, vertex.size = 3 * v)


Eigen centrality

One possibile criticism of degree centrality is that it does not take into account how “important” the nodes connected to a given node are. Eigen centrality helps to account for that by, loosely, recursively measuring degree centrality—that is, nodes connected to other nodes that themselves are highly connected receive more weight.

Eigen centrality is defined by the entries of the eigenvector of the adjacency matrix associated with the largest eigenvalue. We can say “largest” eigenvalue because our adjacency matrix is symmetric, and therefore its eigenvalues are real numbers. The fact that there is a single, non-degenerate largest eigenvalue is a consequence of the Perron-Frobenius theorem, one of the most beautiful results in linear algebra.

The next example adjusts the sizes of the nodes by eigen centrality.

v = abs(eigen(M)$vector[,1])
v = v / max(v)
graphjs(LeMis, vertex.size = 3 * v)


f-subgraph centrality

Eigen centrality gives more weight to nodes that are connected to other nodes with lots of connections. Other measures like f-subgraph centrality (see, for example, E. Estrada and D. J. Higham, Network properties revealed through matrix functions, SIAM Rev., 52 (2010), pp. 696–714.) adjust this concept to emphasize shorter paths more than longer ones. Roughly, nodes that are connected to lots of other nodes by relatively short paths recieve more weight in this measure of graph centrality.

The next example illustrates f-subgraph centrality for the exponential function f(x)=exp(x) using the matrix exponential function expm from R’s Matrix package.

library(Matrix)
v = diag(expm(M))
v = v / max(v)
graphjs(LeMis, vertex.size = 3 * v)