07. Plotting Networks: Weighted Edges

**Feb 9, 2013: I tried running these codes in igraph v0.6, R 2.15 and all seems to be working ok. 

Now that I have described how to add node attributes to network figures, I will introduce how to add edge values or edge weights to your network. Simply put, we are now moving from a 0-1 adjacency matrix to a matrix that can have a continuous range of values. I illustrate the basic approach in igraph first, and then I show the equivalent codes for statnet below.

For example, consider our hypothetical network of birds--but now some birds are associated more strongly with each other than others. This could be that these individuals are associated in foraging groups more often, or that they interact more frequently with each other than with other individuals--whatever fits your study.


23732 23778 23824 23871 58009 58098 58256
23732 0 8 0 1 0 10 0
23778 8 0 1 15 0 1 0
23824 0 1 0 0 0 0 0
23871 1 15 0 0 1 5 0
58009 0 0 0 1 0 7 0
58098 10 1 0 5 7 0 1
58256 0 0 0 0 0 1 0

This matrix is available in .csv form at the bottom of the page as an attachment.

... and we'll also make use of the information on sex of individuals as shown before:

Bird.ID Sex
23732 F
23871 F
58009 F
23778 M
23824 M
58098 M
58256 M

This is again available at the bottom of the page as a .csv file.

Now I'll break down the codes, which are nearly identical to what I have shown in previous pages, save for a few critical differences.
library(igraph)
#import the sample_weighted_adjmatrix file from bottom of the page:
dat=read.csv(file.choose(),header=TRUE,row.names=1,check.names=FALSE) # read .csv file
m=as.matrix(dat)
net=graph.adjacency(m,mode="undirected",weighted=TRUE,diag=FALSE) #here is the first difference from the previous plot: we designate weighted=TRUE
That is all that is needed to make a weighted network in igraph: set weighted=TRUE when importing the matrix. We can confirm that the network is weighted simply by calling graph object:

summary(net)
Which will show this (*in igraph v0.6, the summary output in igraph v0.5 is different):

> summary(net)
IGRAPH UNW- 7 10 -- 
attr: name (v/c), weight (e/n)

Note that we now have an "edge attribute" called weight. This means that edges have values, and this has been assigned an object name. To call up the edge values, we simply use:
E(net)$weight
Which will show this:

> E(net)$weight
 [1]  8  1 10  1 15  1  1  5  7  1

So, we simply use E(net)$weight as part of the options for the network plot:

plot.igraph(net,vertex.label=V(net)$name,layout=layout.fruchterman.reingold, edge.color="black",edge.width=E(net)$weight)
This should produce a figure that looks something like this:


Here's the full set of codes to produce a figure of the weighted network, with nodes color coded by sex:

library(igraph)
#import the sample_weighted_adjmatrix file:
dat=read.csv(file.choose(),header=TRUE,row.names=1,check.names=FALSE) # read .csv file
m=as.matrix(dat)
net=graph.adjacency(m,mode="undirected",weighted=TRUE,diag=FALSE)

#import the sample_attributes file:
a=read.csv(file.choose())

V(net)$Sex=as.character(a$Sex[match(V(net)$name,a$Bird.ID)])

V(net)$color=V(net)$Sex
V(net)$color=gsub("F","red",V(net)$color)
V(net)$color=gsub("M","blue",V(net)$color)

plot.igraph(net,vertex.label=NA,layout=layout.fruchterman.reingold, edge.color="black",edge.width=E(net)$weight)
The color-coding of sexes is identical to what was presented in the previous "using node attributes" section.


... in this hypothetical example, I made the matrix such that edges between males and females are stronger than edges between individuals of the same sex.

***** Weighted edges in Statnet ******
Unfortunately, loading a weighted network in statnet is slightly more complicated.
The first step is to create a network object while specifying "ignore edge values = false" and also storing the edge values as an edge attribute:
library(statnet)
#import the sample_weighted_adjmatrix file:
dat=read.csv(file.choose(),header=TRUE,row.names=1,check.names=FALSE) # read the sample_weighted_adjmatrix.csv file
m=as.matrix(dat)
net=network(m,matrix.type="adjacency",directed=FALSE,ignore.eval=FALSE,names.eval="value")
# this creates a network object from the matrix, storing the edge values as an edge attribute called "value"

Now you have a network object named "net" that is a weighted network. Here's what the summary(net) function will call:

> summary(net)
Network attributes:
 vertices = 7
 directed = FALSE
 hyper = FALSE
 loops = FALSE
 multiple = FALSE
 bipartite = FALSE
 total edges = 10
   missing edges = 0
   non-missing edges = 10
 density = 0.4761905

Vertex attributes:
 vertex.names:
   character valued attribute
   7 valid vertex names

Edge attributes:

 value:
   numeric valued attribute
   attribute summary:
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max.
   1.00    1.00    3.00    5.00    7.75   15.00

Network adjacency matrix:
      23732 23778 23824 23871 58009 58098 58256
23732     0     1     0     1     0     1     0
23778     1     0     1     1     0     1     0
23824     0     1     0     0     0     0     0
23871     1     1     0     0     1     1     0
58009     0     0     0     1     0     1     0
58098     1     1     0     1     1     0     1
58256     0     0     0     0     0     1     0
>

What you see here is that the 'adjacency matrix' of this network will still show only the 0-1 values. However, an edge attribute 'value' has the edge weights stored. In order to show the sociomatrix with the actual edge weights, you need to use something like this:

wnet=as.sociomatrix(net,"value")
wnet
which will show:

> wnet=as.sociomatrix(net,"value")
> wnet
      23732 23778 23824 23871 58009 58098 58256
23732     0     8     0     1     0    10     0
23778     8     0     1    15     0     1     0
23824     0     1     0     0     0     0     0
23871     1    15     0     0     1     5     0
58009     0     0     0     1     0     7     0
58098    10     1     0     5     7     0     1
58256     0     0     0     0     0     1     0

To plot the network with edge weights, use:
gplot(net,gmode="graph",edge.lwd=net%e%'value')
net%e%'value' in statnet calls the edge attribute named 'value'. (It is equivalent to the notation E(net)$value in igraph)


Here are the full codes that will replicate the color-coded and weighted network figure in statnet, using the same .csv files:

library(statnet)
#import the sample_weighted_adjmatrix file:
dat=read.csv(file.choose(),header=TRUE,row.names=1,check.names=FALSE)
m=as.matrix(dat)
net=network(m,matrix.type="adjacency",directed=FALSE,ignore.eval=FALSE, names.eval="value")

#import the sample_attributes file:
a=read.csv(file.choose())
net%v%'Sex'=as.character(a$Sex[match(net%v%'vertex.names',a$Bird.ID)])

net%v%'color'=net%v%'Sex'
net%v%'color'=gsub("F","red",net%v%'color')
net%v%'color'=gsub("M","blue",net%v%'color')

gplot(net,gmode="graph",mode="fruchtermanreingold", edge.lwd=net%e%'value',vertex.col=net%v%'color',vertex.cex=3,vertex.sides=20)
*note the few unfamiliar options in the gplot() function: vertex.cex is the expansion factor for vertex size. vertex.sides is the number of sides that the vertex has--the default is 8. With about 20, the vertex looks like a circle. Also note that the default plotting algorithm in statnet is the Fruchterman-Reingold method, so the mode="fruchtermanreingold" here is redundant but I include it here for illustration purposes.

Here is the result:



 
ċ
sample_attributes.csv
(0k)
Dai Shizuka,
Jan 9, 2011, 10:32 AM
ċ
sample_weighted_adjmatrix.csv
(0k)
Dai Shizuka,
Jan 9, 2011, 10:32 AM
Comments