Properly plotting large adjacency matrix in R
Asked Answered
B

3

10

I've got a rather large (but quite sparse) adjacency matrix (500x500) that I am trying to visually represent. It seems to me that something akin to a force directed graph is my best bet and while trying to figure out the best way to implement this, I came across more than one resource for R. The most helpful was network-visualization on http://kateto.net/network-visualization Though I have never used R before, it seems to have many helpful features for this kinda of visualization.

I have managed to produce a plot below but the image is rather small and the nodes are stacked.

enter image description here

The resolution is slightly better if I print to a pdf as opposed to a PNG, but I still have the stacking problem. My question is therefore, how would I properly plot a large adjacency matrix in R to solve these problems.

My code so far is as follows (with the last few lines several different ways I've attempted to plot my data). Any tips are greatly appreciated. Thank you in advance.

For convenience, I have uploaded the two files referenced to my GitHub here https://github.com/BStricklin/DataViz.

plot.new()
library('igraph')
setwd("D:/Downloads/polnet2016/Data files")

nodes2 <- read.csv("nodes.csv", header=T, as.is=T)
links2 <- read.csv("nodeAdjacency.csv", header=T, row.names=1)

links2 <- as.matrix(links2)

head(nodes2)
head(links2)

net2 <- graph_from_incidence_matrix(links2)
net2 <- graph_from_adjacency_matrix(links2, mode = "undirected", weighted = TRUE)
net2 <- simplify(net2, remove.multiple = F, remove.loops = T) 

V(net2)$label <- nodes2$id

deg <- degree(net2, mode="all")
V(net2)$size <- deg*3

#plot(net2)
#plot(net2, edge.label=round(E(net2)$weight, 3))
layout <- layout.reingold.tilford(net2)
#plot.igraph(net2,vertex.size=3,layout=layout.lgl)
plot.igraph(net2,vertex.size=3,vertex.label.cex=.5,layout=layout.fruchterman.reingold(net2, niter=10000))

EDIT: For anyone wondering how I ended up doing this, I had to use MATLAB and utilized the graph and plot functions. It looked about as nasty as the R image, but with some customization of the nodes and the use of the zoom feature, it worked well enough. I would still be interested in how to do this in R though.

Bismuthinite answered 19/12, 2016 at 8:15 Comment(5)
It would be interesting to see a plot of the matrix vs the graph en.wikipedia.org/wiki/Adjacency_matrixGaikwar
You are correct @user20650, the link is kateto.net/network-visualizationBismuthinite
@Zboson if you go to my github page, the file nodeAdjacency.csv is the graph so to speak. The difference is that the matrix is weighted so rather than simply being filled boxes like on the page you linked to, the numbers of the matrix represent the strength of the connections.Bismuthinite
One option is to use the statnet package and set displayisolates = FALSE in the gplot function. If you insist on using igraph, you can set a threshold value to plot edges larger than a constant.Dotty
I would consider making an interactive graph using, for example networkD3. These are often more useful than a static graph wrt deriving useful informationBrill
M
2

One thing you could start with to simplify the visualisation of the network is to remove the unconnected vertices - those with degree lower than 1:

net3 <- delete.vertices(net2, degree(net2)<1)

Then you could employ a layout algorithm more suitable for large networks, such as the layout_with_graphopt, a force-directed algorithm which allows to set the initial length of the "springs" that originate the forces which will eventually lead to the final layout:

net.graphopt <- layout_with_graphopt(net3, charge = 0.009, mass = 50, spring.length = E(net3)$weight) 

Eventually, you could plot the network in a larger plot area (as suggested above in the first answer) increasing the height and width of the pdf() command, as follows:

pdf("graphopt.pdf", height = 14, width = 14)
plot.igraph(net3,vertex.size=2,vertex.label.cex=.5,layout=net.graphopt)
dev.off()

The final result is still a bit messy, but at least it avoids too much overlapping of nodes:

Network plotted using igraph::layout_with_graphopt

Mokpo answered 12/1, 2020 at 17:18 Comment(0)
D
0

Try making the plot area larger:

png("network_name.png", width = 15, height = 15, units = "in", res = 300)
plot.igraph(net2,vertex.size=3, 
vertex.label.cex=.5, 
layout=layout.fruchterman.reingold(net2, niter=10000)) 
dev.off()
Dotty answered 23/12, 2016 at 6:45 Comment(0)
O
0

If you aim to stick with a representation as a network, one has to optimize the layout-parameters of the graph-layout algorithm, in your case the ones of Fruchterman-Reingold, in order to obtain a pretty layout.

An alternative solution would be to use another representation as a plain matrix, see "Adjacency matrix plots with R and ggplot2".

Last but not least, you might pick out the largest component and plot that one separately. That is the way I am usually taking.

Offprint answered 16/8, 2017 at 13:13 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.