This vignette explores advanced graph animation topics with graphjs()
. We will create graph visualizations with animations triggered by user interaction (clicking on some vertices).
Consider the LeMis
character co-occurrence graph included with the package. Our example decomposes LeMis
into six clusters using the igraph cluster_louvain
method. The example displays a visualization of a reduced network consisting of the most (globally) central character from each cluster, as measured by Page Rank. When a user clicks on one of the vertices, its corresponding cluster is expanded to show all vertices in that cluster.
The first bit of code below computes the clusters, vertex Page Rank values, and most important vertex in each cluster. We color the vertices by cluster membership, but set all but the most important vertex in each cluster to be transparent so that they don’t show up in our visualization. Finally, the code also explicitly sets the vertex coordinates of each vertex identically to the most central vertex in its cluster.
library(threejs)
data(LeMis)
N <- length(V(LeMis))
# Vertex page rank values
pr <- page_rank(LeMis)$vector
# order the page rank values
i <- order(pr, decreasing=TRUE)
# Vertex cluster membership
cl <- unclass(membership(cluster_louvain(LeMis)))
# Find the index of the highest page rank vertex in each cluster
idx <- aggregate(seq(1:N)[i], by=list(cl[i]), FUN=head, 1)$x
# Create a default force-directed layout for the whole network
l1 <- norm_coords(layout_with_fr(LeMis, dim=3))
# Collapse the layout to just the idx vertices
l0 <- Reduce(rbind,Map(function(i) l1[idx[i],], cl))
# Grouped vertex colors, setting all but idx vertices transparent
col <- rainbow(length(idx), alpha=0)[cl]
col[idx] <- rainbow(length(idx), alpha=1)
We can see the labels corresponding to the most important vertex in each cluster with, for instance:
V(LeMis)$label[idx]
## [1] "Myriel" "Fantine" "Valjean" "Marius" "Gavroche" "Javert"
The interactive animations are specified by the click
parameter of the graphjs()
function. This parameter is a named list. The names correspond to vertex numbers (as enumerated in the igraph object). Each entry is itself a list of animation instructions to happen when the corresponding vertex is clicked. A subset of the usual graphjs()
parameters are supported, in particular:
layout
parametervertex.color
parameteredge.color
parameterAt least one of the igraph object or layout
parameter must be specified. And remember, the list must be named with numbers corresponding to the vertices with click actions.
The following code assembles a click
parameter from our important vertices defined above, specifying a layout
and vertex.color
for each vertex.
# animation layouts, one for each of the idx vertices, and
# animation color schemes, one scheme for each idx vertex
click <- Map(function(i)
{
x <- l0
x[cl == i, ] <- l1[cl == i, ]
c <- col
c[cl == i] <- rainbow(length(idx), alpha=1)[i]
list(layout=x, vertex.color=c)
}, seq(idx))
names(click) <- paste(idx)
Let’s take a quick look at the first few entries in this list to help see what we’ve defined:
str(head(click, 2))
## List of 2
## $ 1 :List of 2
## ..$ layout : num [1:77, 1:3] 0.708 0.781 0.229 0.229 1 ...
## .. ..- attr(*, "dimnames")=List of 2
## .. .. ..$ : chr [1:77] "init" "" "" "" ...
## .. .. ..$ : NULL
## ..$ vertex.color: chr [1:77] "#FF0000FF" "#FF0000FF" "#00FF0000" "#00FF0000" ...
## $ 24:List of 2
## ..$ layout : num [1:77, 1:3] 0.708 0.708 0.229 0.229 0.708 ...
## .. ..- attr(*, "dimnames")=List of 2
## .. .. ..$ : chr [1:77] "init" "" "" "" ...
## .. .. ..$ : NULL
## ..$ vertex.color: chr [1:77] "#FF0000FF" "#FF000000" "#00FF0000" "#00FF0000" ...
Finally, let’s make our interactive plot! Click on a vertex to display its cluster.
(graphjs(LeMis, layout=l0, click=click, vertex.color=col, fps=20, font.main="78px Arial"))
Each click animation list entry may only contain single graph, layout, color, etc. specifications (that is, not a list defining an animation sequence). This will probably change in the future.
Like the basic graph animation techniques, every layout must contain the same number of vertices (a condition imposed for performance reasons).
Click here to proceed to an animation example that accumulates expanded vertex positions.
The examples shown here are available as demos in the R package, see demo(package="threejs")
.