I am trying to depict a transport network in networkx and I have been doing good till now, but the problem is the following: I have loaded an edgelist from a txt file, which is in the following form:
61 1
54 79
66 134
68 57
etc. Also, in order to plot network nodes in the correct position, I have loaded and added to the Graph a txt with nodes coordinates which is in the following form:
1 478947.434 4204495.502
2 478909.145 4204244.629
3 479065.936 4204709.003
4 478880.827 4204297.676
5 478993.409 4204167.957
After that, I run the following script and my network is correctly depicted, position-wise.
import networkx as nx
import numpy as py
import copy
import matplotlib.pyplot as plt
import xlwings as xw
from xlwings import Book, Range
pos={}
with open(r'C:\Users\alexl\Documents\new_python\nodes_coordinates.txt') as f:
for line in f:
node, x, y = line.split()
pos[node] = float(x), float(y)
print(pos)
network0 = nx.read_edgelist(r'C:\Users\alexl\Documents\new_python\init_edgelist.txt', create_using = nx.OrderedDiGraph)
nx.draw(network0, pos = pos, with_labels = True, edge_color = G, edge_cmap = plt.cm.Reds, connectionstyle = 'arc3,rad=0.1')
plt.show()
Now, what I want is to correctly assign "weights" to every edge, and color it by this attribute. For every edge there are 3 possible outcomes, 0, 1 and 2, so I want 3 different colours, for example, red for 0, green for 1 and blue for 2. What I have is a Python dictionary like this:
{0: 1.0, 1: 1.0, 2: 0.0, 3: 1.0, 4: 1.0, 5: 0.0, 6: 0.0, 7: 0.0, 8: 1.0,...
etc.The first value (1.0) corresponds to the first edge of edgelist above, the second (1.0) to the second, etc. But I see networkx does not understand this and does not colorize correctly my network. I converted dictionary to list and did the following:
var1 = G.values()
list1 = list(var1)
col = []
for n in range(len(list1)):
if list1[n] == 0:
col.append('b')
elif list1[n] == 1:
#col.append('r')
else:
#col.append('g')
nx.draw(network0, pos = pos, with_labels = True, edge_color = col, edge_cmap = plt.cm.Reds, connectionstyle = 'arc3,rad=0.1')
I checked the result but the correspondence is not the correct one. I think that, if there are 32 '0's in the list, it colors 32 edges with the color I assigned to it, but not the correct ones. (But every time I run it the same 32 edges are colored this way, so it's probably not random.) I wonder what's incorrect. I tried it also as a dictionary (not converting to list), but then colors are more than 3 actually, I don;t know why. Should I try to add these values (0, 1, 1, 2 etc) to the edgelist.txt in order the assignment to be done correctly?
The order of the edges passed to the drawing functions are important.
You need to make sure that your edge_color
list(col
) is in the same order as network0.edges
, which it isn't.
This is happening because network0.edges
is not in the same order as your init_edgelist.txt
file, as you were probably assuming.
To check this try printing network0.edges
and compare.
Instead I would suggest adding edge weights with the pretended color to the edge while creating network0
, like so:
G = {0: 1.0, 1: 1.0, 2: 0.0, 3: 1.0, 4: 1.0, 5: 0.0, 6: 0.0, 7: 0.0, 8: 1.0}
list1 = list(G.values())
col = []
for n in range(len(list1)):
if list1[n] == 0:
col.append('b')
elif list1[n] == 1:
col.append('r')
else:
col.append('g')
network0 = nx.OrderedDiGraph()
i = 0
with open(r'init_edgelist.txt') as f:
for line in f:
n1, n2 = line.split()
network0.add_edge(n1, n2, color = col[i])
i += 1
Then you just need to extract the colors and draw:
colors = [network0[u][v]['color'] for u,v in network0.edges()]
nx.draw(network0, pos = pos, with_labels = True, edge_color = colors, edge_cmap = plt.cm.Reds, connectionstyle='arc3,rad=0.1')
import networkx as nx
import numpy as py
import copy
import matplotlib.pyplot as plt
import xlwings as xw
from xlwings import Book, Range
pos={}
with open(r'nodes_coordinates.txt') as f:
for line in f:
node, x, y = line.split()
pos[node] = float(x), float(y)
#print(pos)
G = {0: 1.0, 1: 1.0, 2: 0.0, 3: 1.0, 4: 1.0, 5: 0.0, 6: 0.0, 7: 0.0, 8: 1.0}
list1 = list(G.values())
col=[]
for n in range(len(list1)):
if list1[n] == 0:
col.append('b')
elif list1[n] == 1:
col.append('r')
else:
col.append('g')
network0 = nx.OrderedDiGraph()
i = 0
with open(r'init_edgelist.txt') as f:
for line in f:
n1, n2 = line.split()
network0.add_edge(n1,n2, color=col[i])
i += 1
#print(network0.edges())
colors = [network0[u][v]['color'] for u,v in network0.edges()]
nx.draw(network0,pos=pos,with_labels=True,edge_color=colors,edge_cmap=plt.cm.Reds, connectionstyle='arc3,rad=0.1')