NetworkX: adjacency matrix does not correspond to graph
Solution 1
Networkx doesn't know what order you want the nodes to be in.
Here is how to call it: adjacency_matrix(G, nodelist=None, weight='weight')
.
If you want a specific order, set nodelist to be a list in that order.
So for example adjacency_matrix(G, nodelist=range(9))
should get what you want.
Why is this? Well, because a graph can have just about anything as its nodes (anything hashable). One of your nodes could have been "parrot"
or (1,2)
. So it stores the nodes as keys in a dict, rather than assuming it's the non-negative integers starting at 0. Dict keys have an arbitrary order.
Solution 2
A more general solution, if your nodes have some logical ordering as is the case if you generate a graph using G=nx.grid_2d_graph(3,3)
(which returns tupples from (0,0) to (2,2), or in your example would be to use:
adjacency_matrix(G,nodelist=sorted(G.nodes()))
This sorts the returned list of nodes of G and passes it as the nodelist
FaCoffee
NHL Winnipeg Jets fan - GO JETS GO! Getting a lot of valuable help here. For DOWN VOTERS: if you are going to down vote, tell the recipient why you are doing so - this way he/she can actually make improvements and gain confidence. Improductive critics should be banned.
Updated on August 05, 2022Comments
-
FaCoffee over 1 year
Say I have two options for generating the Adjacency Matrix of a network:
nx.adjacency_matrix()
and my own code. I wanted to test the correctness of my code and came up with some strange inequalities.Example: a
3x3
lattice network.import networkx as nx N=3 G=nx.grid_2d_graph(N,N) pos = dict( (n, n) for n in G.nodes() ) labels = dict( ((i,j), i + (N-1-j) * N ) for i, j in G.nodes() ) nx.relabel_nodes(G,labels,False) inds=labels.keys() vals=labels.values() inds.sort() vals.sort() pos2=dict(zip(vals,inds)) plt.figure() nx.draw_networkx(G, pos=pos2, with_labels=True, node_size = 200)
The adjacency matrix with
nx.adjacency_matrix()
:B=nx.adjacency_matrix(G) B1=B.todense() [[0 0 0 0 0 1 0 0 1] [0 0 0 1 0 1 0 0 0] [0 0 0 1 0 1 0 1 1] [0 1 1 0 0 0 1 0 0] [0 0 0 0 0 0 0 1 1] [1 1 1 0 0 0 0 0 0] [0 0 0 1 0 0 0 1 0] [0 0 1 0 1 0 1 0 0] [1 0 1 0 1 0 0 0 0]]
According to it, node
0
(entire 1st row and entire 1st column) is connected to nodes5
and8
. But if you look at the image above this is wrong, as it connects to nodes1
and3
.Now my code (to be run in in the same script as the above):
import numpy import math P=3 def nodes_connected(i, j): try: if i in G.neighbors(j): return 1 except nx.NetworkXError: return False A=numpy.zeros((P*P,P*P)) for i in range(0,P*P,1): for j in range(0,P*P,1): if i not in G.nodes(): A[i][:]=0 A[:][i]=0 elif i in G.nodes(): A[i][j]=nodes_connected(i,j) A[j][i]=A[i][j] for i in range(0,P*P,1): for j in range(0,P*P,1): if math.isnan(A[i][j]): A[i][j]=0 print(A)
This yields:
[[ 0. 1. 0. 1. 0. 0. 0. 0. 0.] [ 1. 0. 1. 0. 1. 0. 0. 0. 0.] [ 0. 1. 0. 0. 0. 1. 0. 0. 0.] [ 1. 0. 0. 0. 1. 0. 1. 0. 0.] [ 0. 1. 0. 1. 0. 1. 0. 1. 0.] [ 0. 0. 1. 0. 1. 0. 0. 0. 1.] [ 0. 0. 0. 1. 0. 0. 0. 1. 0.] [ 0. 0. 0. 0. 1. 0. 1. 0. 1.] [ 0. 0. 0. 0. 0. 1. 0. 1. 0.]]
which says that node
0
is connected to nodes1
and3
. Why does such difference exist? What is wrong in this situation?