This is a simple python program to generate a network graph. Everything was fine when I placed the data inside the program but when I decided to place the data in two input files, things started to get interesting. There are two input files: nodes (or vertices) and edges. When I read the nodes information from the input files called 'Step3-Vertices.txt', it did not give any error but additional information were added to the nodes which I did not supply. Here is a list of additional information :
'[', '{', "'", '0', '2', ',', ' ', '6', '8', 'W', '}', '.', '1', '5', '3', '7', '4', 'O', 'X', 'D', ']', '\n'
I then read in the 2nd file called 'Step3-Edges.txt', this time I got a list of error messages which I could not comprehend.
ERROR MESSAGES - NETWORKX FAILED WHEN EDGES INFORMATION ARE ADDED FROM FILE :
Traceback (most recent call last):
File "step4_test1.py", line 30, in <module>
G.add_edges_from(data_edges)
File "/home/desmond/anaconda3/lib/python3.6/site-packages/networkx/classes/graph.py", line 934, in add_edges_from
"Edge tuple %s must be a 2-tuple or 3-tuple." % (e,))
networkx.exception.NetworkXError: Edge tuple [ must be a 2-tuple or 3-tuple.
Could someone help me please?
Here is my program:
""" THIS PROGRAM WORKS PROPERLY WHEN DATA ARE PASSED TO LOCAL VARIABLES CALLED "nodes" and "edges". THE EXACT DATA ARE ALSO STORED IN TWO FILES: "nodes" in 'Step3-Vertices.txt' and "edges" in 'Step3-Edges.txt'. PROBLEMS STARTED WHEN NODES AND EDGES ARE READ FROM BOTH FILES. FIRST, RUN THIS PROGRAM AND IT SHOULD GENERATE A GRAPH. THEN REPLACE THE "nodes" with "data_nodes" in "G.add_nodes_from" AND THIS WILL GENERATE UNEXPECTED ADDITIONAL NODES WHICH ARE NOT SUPPOSED TO BE THERE. NEXT, REPLACE THE "edges" with "data_edges" in "G.add_nodes_from" AND ERROR MESSAGES ARE DISPLAYED."""
import networkx as nx
import matplotlib.pyplot as plt
""" READ NODES INFORMATION FROM FILE """
with open('Step3-Vertices.txt', encoding='utf-8') as data_file:
data_nodes = data_file.read()
print(data_nodes)
""" READ EDGESS INFORMATION FROM FILE """
with open('Step3-Edges.txt', encoding='utf-8') as data_file:
data_edges = data_file.read()
print(data_edges)
G=nx.Graph()
""" PASS NODES INFORMATION TO A VARIABLE CALLED 'nodes' """
nodes = ['0000000002', '0000000101', '0000000111', '0000000200', '0000000502', '0000000600', '0000001000', '0000001001', '0000001069', '0000001253', '0000001462', '0000003013', '0000003200', '0000004100', '0000004305', '0000005100', '0000005460', '0000006600', '0000010021', '0000010101', '0000010200', '0000010314', '0000012000', '0000012151', '0000012600', '0000015201', '0000016100', '0000017002', '0000020002', '0000020050', '0000020100', '0000021001', '0000022044', '0000022100']
""" PASS EDGES INFORMATION TO A VARIABLE CALLED 'edges' """
edges = [{'0000000002', '6080022W'}, {'80.015.012.210', '0000000002'}, {'80.015.012.210', '0000000502'}, {'0000012000', '0000000502'},{'0000000101', '012.105.123.127'}, {'0000000111', '2442032O'}, {'105.103.02.110', '0000000111'}, {'0604054X', '0000000200'}, {'100.001.008.002', '0000000200'}, {'0000000502', '1002567D'}, {'208.08.032.1', '0000000502'}]
"""THIS IS WHERE YOU ADD DATA TO THE NODES AND EDGES, BY DEFAULT, LOCAL VARIABLES ARE USED. TO ADD DATA FROM THE INPUT FILES - replace 'nodes' with 'data_nodes' and replace 'edges' with 'data_edges' """
G.add_nodes_from(nodes)
G.add_edges_from(edges)
print("Nodes of graph: ")
print(G.nodes())
print("Edges of graph: ")
print(G.edges())
### DRAW A GRAPH ###
nx.draw(G)
plt.savefig("test1.png") # save as png
plt.show() # display
答案 0 :(得分:0)
add_edges_from
期望的格式是以最基本形式的元组列表,作为要连接的(u,v)对的列表。
您的文件没有适当格式的数据,因此networkx不知道如何处理它们。如果文本与您在“ edges”变量中所写的完全相同,则下面是一种将其整理成正确的列表的方法。您可以对节点进行类似的处理,尽管这只需要一个元素列表,而不是一个元组列表,因此更简单。
with open("edgefile.txt") as data_file:
data_edges = data_file.read()
# split on the comma, assuming this divides elements, remove the curly braces and quotes
elems = ([f.strip(" {}'") for f in data_edges.strip().split(',')])
# use zip to turn the flat list into a lst of pairs
edge_list = zip(elems[::2], elems[1::2])
# now we are in a form that nx.add_edges_from can handle
G = nx.Graph()
G.add_nodes_from(nodes)
G.add_edges_from(edge_list)
您应该在此处阅读有关阅读图形的文档:https://networkx.github.io/documentation/stable/reference/readwrite/index.html
描述如何从各种标准图形格式读取。
编辑,位于评论中的qu之后:
在图形中有许多“意外”节点的原因是因为nx.add_nodes_from采用可迭代的类型,并且当您将整个文件读入文本变量时,一次遍历该字符串需要一个字符。这将生成诸如0
,'
和\n
之类的单字符节点。因此,我们可以通过将字符串解析为列表来修复它,然后遍历列表给出一个元素,例如'0000000002'
。
这里是一个例子:
# assume that the file describing nodes is read into this string:
node_txt = "'0000000002', '0000000101', '0000000111', '0000000200', '0000000502', '0000000600', '0000001000', '0000001001', '0000001069', '0000001253', '0000001462', '0000003013', '0000003200', '0000004100', '0000004305', '0000005100', '0000005460', '0000006600', '0000010021', '0000010101', '0000010200', '0000010314', '0000012000', '0000012151', '0000012600', '0000015201', '0000016100', '0000017002', '0000020002', '0000020050', '0000020100', '0000021001', '0000022044', '0000022100'\n"
G1 = nx.Graph()
G1.add_nodes_from(node_txt)
print(G1.nodes())
print(set(node_txt))
# output of these two commands shows that the node names are 1 char each:
>>> [' ', "'", '\n', ',', '1', '0', '3', '2', '5', '4', '7', '6', '9']
>>> set([' ', "'", '\n', ',', '1', '0', '3', '2', '5', '4', '7', '6', '9'])
# reference: what we really wanted
node_list = ['0000000002', '0000000101', '0000000111', '0000000200', '0000000502', '0000000600', '0000001000', '0000001001', '0000001069', '0000001253', '0000001462', '0000003013', '0000003200', '0000004100', '0000004305', '0000005100', '0000005460', '0000006600', '0000010021', '0000010101', '0000010200', '0000010314', '0000012000', '0000012151', '0000012600', '0000015201', '0000016100', '0000017002', '0000020002', '0000020050', '0000020100', '0000021001', '0000022044', '0000022100']
G2 = nx.Graph()
G2.add_nodes_from(node_list)
print(G2.nodes())
print(set(node_list))
那么如何将node_txt
转换成node_list
的形式呢?我们对边缘执行与上述相同的过程-这个过程要简单一些。
elems = [f.strip(" '") for f in node_txt.strip().split(',')]
print(elems == node_list)
# output: True -> so here we recovered the node names correctly from node_txt