问题
I'm trying to use the igraph
package to draw a (sparse) weighted graph. I currently have an adjacency matrix, but cannot get the graph.adjacency
function to recognise the edge weights.
Consider the following random symmetric matrix:
m <- read.table(row.names=1, header=TRUE, text=
" A B C D E F
A 0.00000000 0.0000000 0.0000000 0.0000000 0.05119703 1.3431599
B 0.00000000 0.0000000 -0.6088082 0.4016954 0.00000000 0.6132168
C 0.00000000 -0.6088082 0.0000000 0.0000000 -0.63295415 0.0000000
D 0.00000000 0.4016954 0.0000000 0.0000000 -0.29831267 0.0000000
E 0.05119703 0.0000000 -0.6329541 -0.2983127 0.00000000 0.1562458
F 1.34315990 0.6132168 0.0000000 0.0000000 0.15624584 0.0000000")
m <- as.matrix(m)
To plot, first I must get this adjacency matrix into the proper igraph
format. This should be relatively simple with graph.adjacency
. According to my reading of the documentation for graph.adjacency, I should do the following:
library(igraph)
ig <- graph.adjacency(m, mode="undirected", weighted=TRUE)
However, it doesn't recognise the edge weights:
str(ig)
# IGRAPH UNW- 6 8 --
# + attr: name (v/c), weight (e/n)
# + edges (vertex names):
# [1] A--E A--F B--C B--D B--F C--E D--E E--F
plot(ig)

How do I get igraph to recognise the edge weights?
回答1:
The weights are there, weight (e/n)
means that there is an edge attribute called weight, and it is numeric. See ?print.igraph
. But they are not plotted by default, you need to add them as edge.label.
plot(ig, edge.label=round(E(ig)$weight, 3))

For plotting, make sure you read ?igraph.plotting
.
回答2:
@TWL's solution can be easily generalized to represent edges' width as a function of the weights, including negative weights. The trick is to translate all weights by summing the value of the smallest weight (plus optionally an offset that represents the width of the minimum weight). For example:
# reproducible example:
set.seed(12345)
a <- matrix(runif(5*5, min=-10, max=10), ncol=5)
diag(a) <- 0 # remove loops.
>a
[,1] [,2] [,3] [,4] [,5]
[1,] 0.0000000 -6.6725643 -9.309291 -0.7501069 -0.9254385
[2,] 7.5154639 0.0000000 -6.952530 -2.2371204 -3.4649518
[3,] 5.2196466 0.1844867 0.000000 -1.9502972 9.3083065
[4,] 7.7224913 4.5541051 -9.977268 0.0000000 4.1496375
[5,] -0.8703808 9.7947388 -2.175933 9.0331751 0.0000000
# create igraph object.
g <- graph.adjacency(a, mode="undirected", weighted=TRUE)
plot(g)
# assign edge's width as a function of weights.
E(g)$width <- E(g)$weight + min(E(g)$weight) + 1 # offset=1
plot(g)

回答3:
As much as I love igraph, I've found the qgraph package easier to plot weighted networks.
With the adjacency matrix you can also just use qgraph()
from the qgraph library to plot it. It will automatically color negative edges a shade of red and positive edges a shade of green.
install.packages('qgraph')
require(qgraph)
qgraph(m)
qgraph(m,edge.labels=TRUE) #if you want the weights on the edges as well
qgraph is built on igraph, but just does everything for you.
回答4:
You can extract the edge weights with E(ig)$weight
, and assign them to the edge.width
argument in the plotting function:
plot(ig, edge.width=E(ig)$weight)
See the ?igraph.plotting
[link] for reference.
Also, please note that in this example, the weights will correspond to the width of the edges, hence they should be >= 0
.
来源:https://stackoverflow.com/questions/21300821/igraph-creating-a-weighted-adjacency-matrix