Graph 创建网络图
我的CSV格式的示例数据集如下所示 无向图有90个节点,用数字{10,11,12…99}表示 其带权重的边定义如下 [样本数据]Graph 创建网络图,graph,social-networking,Graph,Social Networking,我的CSV格式的示例数据集如下所示 无向图有90个节点,用数字{10,11,12…99}表示 其带权重的边定义如下 [样本数据] node1 node2 weight 23 89 34.9 (i.e. there is an edge between node 23 and 89 with weight 34.9) 75 14 28.5 so on.... 我想用网络的形式来表达这一点。表示它的有效方式是什么(例如Gephi、networkx等)。边的厚度应表示边
node1 node2 weight
23 89 34.9 (i.e. there is an edge between node 23 and 89 with weight 34.9)
75 14 28.5
so on....
我想用网络的形式来表达这一点。表示它的有效方式是什么(例如Gephi、networkx等)。边的厚度应表示边的权重。使用,可以添加具有属性的边
import networkx as nx
G = nx.Graph()
G.add_edge(23, 89, weight=34.9)
G.add_edge(75, 14, weight=28.5)
如果您在Linux中,并且假设您的csv文件如下所示(例如): 您可以使用此程序:
import os
def build_G(csv_file):
#init graph dict
g={}
#here we open csv file
with open(csv_file,'r') as f:
cont=f.read()
#here we get field content
for line in cont.split('\n'):
if line != '':
fields=line.split(';')
#build origin node
if g.has_key(fields[0])==False:
g[fields[0]]={}
#build destination node
if g.has_key(fields[1])==False:
g[fields[1]]={}
#build edge origin>destination
if g[fields[0]].has_key(fields[1])==False:
g[fields[0]][fields[1]]=float(fields[2])
return g
def main():
#filename
csv_file="mynode.csv"
#build graph
G=build_G(csv_file)
#G is now a python dict
#G={'27': {}, '75': {'14': 2.85, '23': 0.9}, '89': {}, '14': {'75': 2.9}, '23': {'27': 4.9, '89': 3.49, '14': 1.29}}
#write to file
f = open('dotgraph.txt','w')
f.writelines('digraph G {\nnode [width=.3,height=.3,shape=octagon,style=filled,color=skyblue];\noverlap="false";\nrankdir="LR";\n')
f.writelines
for i in G:
for j in G[i]:
#get weight
weight = G[i][j]
s= ' '+ i
s += ' -> ' + j + ' [dir=none,label="' + str(G[i][j]) + '",penwidth='+str(weight)+',color=black]'
if s!=' '+ i:
s+=';\n'
f.writelines(s)
f.writelines('}')
f.close()
#generate graph image from graph text file
os.system("dot -Tjpg -omyImage.jpg dotgraph.txt")
main()
我之前一直在寻找构建复杂图形的有效解决方案,这是我发现的最简单(没有任何python模块依赖性)的方法
以下是无向图的图像结果(使用dir=none):
如果您有一个大型csv,我建议您将其用于任务的I/O部分
networkx
有一个有用的方法来与调用的pandas
接口。假设您的数据采用上述格式的csv格式,则此命令应适用于您:
df = pd.read_csv('path/to/file.csv', columns=['node1', 'node2', 'weight'])
但为了演示,我将在您的需求范围内使用10条随机边(您不需要导入numpy
,我只是使用它生成随机数):
上一块中的所有内容都应生成与您的pd.read\u csv
命令相同的内容。产生此数据帧,df
:
node1 node2 weight
0 16 13 0.548814
1 17 15 0.715189
2 17 10 0.602763
3 18 12 0.544883
4 11 13 0.423655
5 15 18 0.645894
6 18 11 0.437587
7 14 13 0.891773
8 13 13 0.963663
9 10 13 0.383442
使用来自数据帧的进行初始化。这假定将有多条边连接到一个节点(OP中未指定)。要使用此方法,您必须在convert_matrix.py
文件中的networkx
源代码中进行简单的更改(这是一个简单的错误)
这将生成您的多重图形,您可以使用以下工具将其可视化:
详细内容:
positions
是一个字典,其中每个节点都是一个键,值是图形上的一个位置。我将在下面描述我们存储位置的原因。通用的draw
将绘制节点位于指定位置的多重图实例MG
。但是,正如您所看到的,这些边的宽度都相同:
但是你有你需要的一切来增加重量。首先将权重放入名为权重的列表中。通过迭代(列表理解)每个边,我们可以提取权重。我选择乘以5
,因为它看起来最干净:
weights = [w[2]['weight']*5 for w in MG.edges(data=True)]
最后,我们将使用,它只绘制图形的边(没有节点)。因为我们有节点的位置
,并且我们设置了hold=True
,所以我们可以在前面的可视化视图上绘制加权边
nx.draw_networkx_edges(MG, pos=positions, width=weights) #width can be array of floats
您可以看到节点(14,13)
具有数据帧df
中最重的行和最大的值(除了(13,13)
)。您应该编辑csv文件开头的行,如下所示:
源目标类型权重
23 89无向34.9(即节点23和89之间有一条边,权重为34.9)
75 14无向28.5
等等
之后,您可以将csv文件导入Gephi,以表示边的厚度代表权重的图形,例如:
如果您的系统上不存在点二进制文件@Stefani,您可以从终端使用sudo apt get install graphviz
。。!!我的图形是无向的,我如何删除方向。@用户1659936不客气,您需要在构造期间添加dir=none,因此请替换该行:s+='->'+j+'[label=“'+str(G[I][j])+”,penwidth='+str(weight)+',color=black]
bys+='->'+j+'[dir none,label=“+str(G[I][j])”,penwidth='+str(weight)+',color=black]'
删除direction@user1659936:我根据您的需要更改代码。使用上面的代码,我的dotgraph.txt
文件似乎在Windows上正确生成,但我找不到.png
输出。我怎样才能让它在Windows而不仅仅是Linux上工作呢?在nx.Multigraph()上,我遇到了这样一个错误:TypeError:unhabable type:“dict”如果您在代码块前面的段落中做了更改,它应该可以工作这个此外,如果您完全使用
参数删除create\u,则只有在您知道图形是图形
而不是多重图形
的情况下,此操作才有效。
MG = nx.from_pandas_dataframe(df,
'node1',
'node2',
edge_attr='weight',
create_using=nx.MultiGraph()
)
positions = nx.spring_layout(MG) # saves the positions of the nodes on the visualization
# pass positions and set hold=True
nx.draw(MG, pos=positions, hold=True, with_labels=True, node_size=1000, font_size=16)
weights = [w[2]['weight']*5 for w in MG.edges(data=True)]
nx.draw_networkx_edges(MG, pos=positions, width=weights) #width can be array of floats