使用python3表示实体之间的关系

时间:2018-02-28 02:30:58

标签: python python-3.x matplotlib graph networkx

我想使用Python的networkx库来表示一系列数据,但我不知道如何处理这个问题。

基本上我在relation之间有一个entities,它位于名为nations.csv的csv文件中。它看起来像这样:

China, Economicaid, Egypt
China, Economicaid, Indonesia
USSR, Economicaid, Cuba 
USSR, Economicaid, India
USSR, Economicaid, Poland
UK, Economicaid, India 
UK, Economicaid, Jordan
USA, Economicaid, Brazil

理解第一行是与第二行之间的第三行(实体2)相关的实体之一:

relation

我已经解析了csv文件,以便将每一行存储在字典中,如下所示:

d = {}
d['entity1'] = []
d['relation'] = []
d['entity2'] = []

dictReader = csv.DictReader(open('nations.csv', 'rt'), fieldnames = 
['entity1', 'relation', 'entity2'], delimiter = ',', quotechar = '"')

for row in dictReader:
    for key in row:
        d[key].append(row[key])

我设法做的是使用函数add_node()绘制节点,如下例所示:

import csv
import networkx as nx
import matplotlib.pyplot as plt


d = {}
d['entity1'] = []
d['relation'] = []
d['entity2'] = []

dictReader = csv.DictReader(open('nations.csv', 'rt'), fieldnames = ['entity1', 'relation', 'entity2'], delimiter = ',', quotechar = '"')

for row in dictReader:
    for key in row:
        d[key].append(row[key])

print()

for i in range (1, len(d['entity1'])):
    r.append(d['entity1'][i])

for k in range (1, len(d['entity2'])):
    o.append(d['entity2'][k])


G=nx.Graph()

for j in range(len(r)):
    G.add_node(r[j])
    G.add_node(o[j])

nx.draw_networkx(G, with_labels = True, node_size = 500)

plt.show()

但问题来自于我想表示节点之间的边缘,因为它不仅是边缘本身,它还有自己的标签,具有意义。

1 个答案:

答案 0 :(得分:2)

基本上,标志with_labels应该被称为with_node_labels,因为它只触发节点标签的绘图。因此,您需要在绘制图形(networkx.draw`)后手动添加边标签(networkx.draw_networkx_edge_labels),并且您需要1)在同一轴上绘图,并且2)对两者使用相同的图形布局地块。

import numpy as np
import matplotlib.pyplot as plt
import networkx as nx
import csv

# load data
dictReader = csv.DictReader(open('nations.csv', 'rt'), fieldnames = ['entity1', 'relation', 'entity2'], delimiter = ',', quotechar = '"')

# create a more amenable data structure
edge_to_label = {(d['entity1'], d['entity2']) : d['relation'] for d in dictReader}

# create graph
G = nx.from_edgelist(edge_to_label.keys())

# precompute layout (default layout used here)
layout = nx.layout.fruchterman_reingold_layout(G)

# create figure so we plot the graph and labels on the same plot
fig, ax = plt.subplots(1,1)

# draw graph
nx.draw(G, pos=layout, ax=ax, with_labels=True)

# draw labels using the same, pre-computed graph layout
nx.draw_networkx_edge_labels(G, pos=layout, edge_labels=edge_to_label, ax=ax)

plt.show()

enter image description here