如何将节点和边添加到Networkx中的网络分析图?

时间:2015-12-08 01:06:34

标签: python graph nodes networkx network-analysis

我正在尝试学习网络分析,所以我在线使用希拉里克林顿的电子邮件,看谁通过电子邮件发送给谁。

我的数据位于名为hrc_dict的字典中。我有发送者和接收者的元组,然后是电子邮件的频率。这是字典的一部分:

  

{('Hillary Clinton','Cheryl Mills'):354,('Hillary Clinton','l'):1,('Linda Dewan','Hillary Clinton'):1,''Hillary Clinton' ,'Capricia Marshall'):9,('Phillip Crowley','Hillary Clinton'):2,('Cheryl Mills','Anne-Marie Slaughter'):1}

我在Jupyter中使用Networkx来创建图表。我的代码如下:

import networkx as nx
import matplotlib.pyplot as plt

G = nx.Graph()

G.add_nodes_from(hrc_dict)

for s, r in hrc_dict:
    G.add_edge((s,r), hrc_dict[(s,r)])

G.add_edge((s,r), hrc_dict[(s,r)])

当我调用nx.Graph()时,没有打印出来,当我调用G.nodes()时,并非所有节点都显示出来。我在这里粘贴了一些输出:

  

[1,    2,    3,    4,    5,    6,    7,    8,    '马克佩恩',    10,    ('托德斯特恩','希拉里克林顿'),    12,]

当我打电话给G.edges()时,我会得到以下内容,这似乎是正确的

  <(1,('Hillary Clinton','l')),(1,('Linda Dewan','Hillary Clinton')),(1,('Hillary Clinton','Thomas Shannon')) ,(1,('Cheryl Mills','Anne-Marie Slaughter')),(1,('Christopher Butzgy','希拉里克林顿'))]

有谁知道如何正确地将节点添加到我的图表中。我假设每个人都需要成为一个节点,那么如何分解元组并单独添加名称呢?边缘是否正确显示还是需要以不同方式输入?

2 个答案:

答案 0 :(得分:3)

要将每个人添加为节点,您还需要更改add_nodes_from

的使用

这样的事情:

srcs, dests = zip(* [(fr, to) for (fr, to) in hrc_dict.keys()])
G.add_nodes_from(srcs+dests)

现在意味着来自G.nodes()的节点列表将是:

['Cheryl Mills',
 'Capricia Marshall',
 'Anne-Marie Slaughter',
 'Phillip Crowley',
 'Hillary Clinton',
 'l',
 'Linda Dewan']

(因为networkx将图形存储为字典,所以不会有任何重复。)

注意:如果您使用下面的方法添加边缘,则不需要首先添加节点 - 但是如果有某些原因可能导致您没有邻居的节点(或其他原因)只有节点很重要),这段代码就可以了。

然后根据Joel的答案基本添加边缘;还要注意使用属性“weight”,因此布局可以直接利用信息。

import networkx as nx
import matplotlib.pyplot as plt

hrc_dict = {('Hillary Clinton', 'Cheryl Mills'): 355, ('Hillary Clinton', 'l'): 1, ('Linda Dewan', 'Hillary Clinton'): 1, ('Hillary Clinton', 'Capricia Marshall'): 9, ('Phillip Crowley', 'Hillary Clinton'): 2, ('Cheryl Mills', 'Anne-Marie Slaughter'): 1}

G = nx.Graph()

# To add the a node for each of the email parties:
srcs, dests = zip(* [(fr, to) for (fr, to) in hrc_dict.keys()])
G.add_nodes_from(srcs + dests)
# (but it isn't needed IF the following method is used
#  to add the edges, since add_edge also creates the nodes if
#  they don't yet exist)

# note the use of the attribute "weight" here
for (s,r), count in hrc_dict.items():
    G.add_edge(s, r, weight=count)

# produce info to draw:
# a) if weight was used above, spring_layout takes 
#    into account the edge strengths
pos = nx.spring_layout(G)

# b) specifiy edge labels explicitly
# method from https://groups.google.com/forum/#!topic/networkx-discuss/hw3OVBF8orc
edge_labels=dict([((u,v,),d['weight'])
             for u,v,d in G.edges(data=True)])

# draw it
plt.figure(1);
nx.draw_networkx(G, pos, with_labels=True)
nx.draw_networkx_edge_labels(G,pos,edge_labels=edge_labels)

plt.axis('equal') # spring weighting makes more sense this way
plt.show()

这就是我们可能会看到的:

Example output - note that because the HC/A-MS edge is so strong it is very short

答案 1 :(得分:0)

你的问题基本上就在这一点:

G.add_edge((s,r), hrc_dict[(s,r)])

networkx将此解释为“在第一个参数(s,r)和第二个参数hrc_dict[(s,r)]之间添加边缘。”因此,例如('Hillary Clinton', 'Cheryl Mills'): 354成为节点('Hillary Clinton', 'Cheryl Mills')和节点354之间的边缘。而是尝试

G.add_edge(s, r, count = hrc_dict[(s,r)])