is there a way to draw the links or nodes of a network in igraph for R proportional to a minimum and maximum values?
Using link and node attributes for drawing is very handy in igraph, but in some networks the difference between the minimum and maximum values found in a network lead to a very ugly drawing. For instance, see this code:
#Transforming a sample network (Safariland) from the package bipartite into an igraph object
mat = Safariland
mat2 = cbind.data.frame(reference=row.names(mat),mat)
list = melt(mat2, na.rm = T)
colnames(list) = c("plant","animal","weight")
list[,1] = as.character(paste(list[,1]))
list[,2] = as.character(paste(list[,2]))
list2 = subset(list, weight > 0)
g = graph.data.frame(list2)
g2 = as.undirected(g)
#Plotting the igraph object with edge widths proportional to link weights
plot(g2,
edge.width = E(g2)$weight)
The result is an odd-looking network, as the difference between link weights it too large. How can I draw those edges within a min-max range, so the network looks better?
Thank you very much.
You can apply any math or function to the values before passing them to the plot function. What you want is for example a rescaling function to map values to a different range as in this stackoverflow answer:
mapToRange<-function(x,from,to){
return( (x - min(x)) / max(x - min(x)) * (to - from) + from)
}
make example graph with random weights that are bad as line widths:
library(igraph)
g<-erdos.renyi.game(20,0.5)
E(g)$weight<-runif(length(E(g)))^3 *100
bad plot:
plot(g, edge.width = E(g)$weight)
better plot, rescaling the edge weights to values between 1 and 10 first with above function:
weightsRescaled<-mapToRange(E(g)$weight,1,10)
plot(g, edge.width = weightsRescaled)
same thing more concise:
plot(g, edge.width = mapToRange(E(g)$weight,1,10))