knitr::opts_chunk$set(collapse = T, comment = "#>") library(igraph) library(network) library(arcdiagram)
"arcdiagram"
is a package for producing pretty arc diagrams of graphs in R. You can think of "arcdiagram"
as a plugin of the package "igraph"
(by Gabor Csardi and Tamas Nepusz). In this document we will discuss how to use "arcdiagram"
to produce arc diagrams of graphs from the package "network"
(by Carter Butts, David Hunter, and Mark Handcock).
network
R has several packages dedicated to graphs and network analysis. There is even a CRAN Task View for graphical models that you can check at:
http://cran.r-project.org/web/views/gR.html
"arcdiagram"
has been designed to fit like a glove for graph edge lists obtained from "igraph"
. However, graph edge lists can also be obtained using the package "network"
. Let's see how to play with "arcdiagram"
and "network"
.
First let's load the packages "arcdiagram"
and "network"
(I'm assuming you already installed them)
# load 'arcdiagram' library(arcdiagram) # load 'network' library(network)
Let's start with a very simple example. We will generate a random graph with 7 nodes. One way to do this is by generating an adjacency matrix first and then create the graph with the function network()
:
# generate a random adjacency matrix set.seed(95) toy_matrix <- matrix(rbinom(49,1,.25), 7, 7) diag(toy_matrix) = 0 # create a graph from the adjacency matrix toy_graph <- network(toy_matrix, directed = FALSE)
edgelist
Once we have the network, we need to extract the edge list which will be used as the main argument for arcplot()
. The way to obtain an edge list from a "network"
object is with the function as.matrix()
and the argument matrix.type = "edgelist"
# edgelist toy_edges <- as.matrix(toy_graph, matrix.type = "edgelist")
The edge list toy_edges
is all you need to produce an arc diagram with arcplot()
:
# plot arc diagram op <- par(mar = c(1, 0.5, 0.5, 0.5)) arcplot(toy_edges, las=1) par(op)
Let's see another example using a more interesting data set. We will use the data "flo"
which is one of the datasets available in "network"
. This data set consists of weddings among leading Florentine families (in Italy).
flo
The way to get a graph (i.e. network) from the data "flo"
is by using the function network()
:
# load data 'flo' data(flo) # network netflo <- network(flo) # what does 'netflo' look like? netflo
Because the main argument for arcplot()
is an edge list, we need to use as.matrix()
with its argument matrix.type = "edgelist"
to get such a list form netflo
:
# edgelist flo_edges <- as.matrix(netflo, matrix.type="edgelist")
Now we can get a first arc diagram:
# second plot op = par(mar = c(2, 0.5, 1, 0.5)) arcplot(flo_edges, las=1) par(op)
If you inspect either the object netflo
or the edgelist flo\_edges
, you will see that we have the names of the nodes (i.e. the vertices) as an attribute, for instance:
# print netflo
netflo
As you can see in the last lines of the output, netflo
contains the vertex attribute names vertex.names
. One way to get these names is by using the function get.vertex.attribute()
:
# try to get vertex names get.vertex.attribute(netflo, "vertex.names")
If by any chance you find an error message telling you something like this (don't panic):
Error in get.vertex.attribute(netflo, "vertex.names") : Not a graph object
The cause of the problem is a "compatibility" issue between the packages "igraph"
and "network"
(remember that "arcdiagram"
depends on "igraph"
). Both packages have the same name for some of their functions ---get.vertex.attribute()
among them---. Actually, since we first load "arcdiagram"
, this implies that the homonym functions of "network"
are masked by those of "igraph"
. The solution? Use the double colon operator ::
. To get the vertex names from netflo
we have to specify the namespace
under which the required get.vertex.attribute()
function is located:
# get vertex names flo_names <- network::get.vertex.attribute(netflo, "vertex.names") # show me the names flo_names
An alternative way to get the vertex names is by extracting them directly from the edge list flo_edges
with the function attributes()
:
# another way to get vertex names attributes(flo_edges)$vnames
Of course, this a painless way to get the names, but I wanted to show you the hard way in case you find yourself trapped in that quandary.
Having extracted the vertex.names
, it seems that we are ready to plot an arc diagram with the node labels:
# arc plot with node labels arcplot(flo_edges, labels=flo_names)
Well, we are not ready yet. The problem is that we have more labels than nodes in the edge list (node 12 does not appear in flo\_edges
). The solution is a bit elaborated: first we need to get the node numbers from the edgelist, and then we have to select their corresponding names:
# numeric indices in 'flo_edges' temp <- unique(as.vector(t(flo_edges))) temp # node labels flo_labels = attributes(flo_edges)$vnames[temp] # check it flo_labels
Now we are ready to produce the desired arc diagram:
# second plot op = par(mar = c(5, 0, 1, 0)) arcplot(flo_edges, labels=flo_labels) par(op)
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.