从grid_2d_graph中一致删除节点

时间:2015-10-28 15:57:53

标签: python dictionary matplotlib networkx

假设我有一个由G个节点组成的常规二维网格图NxN=100x100。我通过调用来创建这样的网络:

N=100
G=nx.grid_2d_graph(N,N)
pos = dict( (n, n) for n in G.nodes() ) #Dictionary of all positions
labels = dict( ((i, j), i + (N-1-j) * N ) for i, j in G.nodes() )
nx.draw_networkx(G, pos=pos, labels=labels,with_labels=False, node_size=10)

我得到的结果类似于这张图片左侧所示的结果:

enter image description here

现在,假设我的网络遇到破坏性事件,导致许多节点失败(图片的右侧)。我的图G不再由相同数量的节点组成:图G2现在拥有K<NxN个节点。鉴于这种情况,我希望能够通过调用

来绘制G2
G2=G.remove_nodes_from(failed_nodes_dict) #Failed_node_dict holds the disrupted nodes
nx.draw_networkx(G2, pos=pos, labels=labels,with_labels=False, node_size=10)

我的问题。我怎样才能这样做,以确保位置字典pos不被改变? 这意味着:如果节点0位于情境 1)的位置(0,0)(左上角)并且它没有失败,那么它必须出现情况相同的情况 2)。这样,两个网络可以比较,第二个网络只是第一个的“转换”。的谢谢!

3 个答案:

答案 0 :(得分:2)

我会延伸@AbdallahSobehy的答案。但是,对于networkx图的更一般的可重用性,我建议将位置和标签信息存储在图结构中,而不是存储在单独的容器中。

从简化版图表开始(N = 5):

N = 5
G = nx.grid_2d_graph(N,N)
pos = dict((n, n) for n in G.nodes())
labels = dict(((i, j), i + (N-1-j) * N) for i, j in G.nodes())

可以将poslabel字典存储为图形属性:

nx.set_node_attributes(G, 'pos', pos)
nx.set_node_attributes(G, 'labels', labels)

并将它们用于绘图:

nx.draw_networkx(G, pos=nx.get_node_attributes(G, 'pos'),
                 labels=nx.get_node_attributes(G, 'labels'),
                 with_labels=True, node_size=500)

enter image description here

您可以稍后执行图表中的任何操作,例如删除一些节点:

G.remove_nodes_from([(0,0),(0,2),(2,2),(2,1)])

重新绘制图表而不需要重新计算poslabel词典,因为条目会自动使用图形操作进行更新。以下行与上面的绘图调用完全相同:

nx.draw_networkx(G, pos=nx.get_node_attributes(G, 'pos'),    
                 labels=nx.get_node_attributes(G, 'labels'), 
                 with_labels=True, node_size=500)

但这一次,产生了不同的形象:

enter image description here

简而言之:在节点/边缘属性中存储所有内容,因为它们将随图更改自动更新。

答案 1 :(得分:1)

您可以通过将节点从(i,j)重新标记为您在标签词典中的数字上看到的数字来实现。然后删除失败的节点。最后,通过简单地反转标签字典,调整pos字典以将位置映射到节点的新标签。以下是我在代码后添加的内容:

nx.relabel_nodes(G,labels,False)
G.remove_nodes_from([0,4,12,18])            
pos = {y:x for x,y in labels.iteritems()}
nx.draw_networkx(G, pos=pos, with_labels=True, node_size = 300)

对于N = 5和失败的节点[0,4,12,18],这是我在之前(左)和之后(右)失去的节点被删除的结果。 enter image description here

答案 2 :(得分:1)

我很难理解你为什么要问这个问题 - 代码基本上应该完全按你所希望的那样工作。但是,您有一个错误,可能是导致您提出此问题的错误。

G2= G.remove_nodes_from(failed_nodes_dict) #Failed_node_dict holds the disrupted nodes

这会使G2成为NoneG.remove_nodes_from(L)L移除G中的节点。它不会创建看起来像G但没有这些节点的新图形。所以它不会返回任何东西。因此G2没有给出任何价值。图G删除了这些节点。

所以以下内容应该有效:

N=100
G=nx.grid_2d_graph(N,N)
pos = dict( (n, n) for n in G.nodes() ) #Dictionary of all positions
labels = dict( ((i, j), i + (N-1-j) * N ) for i, j in G.nodes() )
nx.draw_networkx(G, pos=pos, labels=labels,with_labels=False, node_size=10)

#find failed nodes here

G.remove_nodes_from(failed_nodes_dict) #Failed_node_dict holds the disrupted nodes
nx.draw_networkx(G, pos=pos, labels=labels,with_labels=False, node_size=10)

pos在此代码中永远不会更改。