假设我有一个由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)
我得到的结果类似于这张图片左侧所示的结果:
现在,假设我的网络遇到破坏性事件,导致许多节点失败(图片的右侧)。我的图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)。这样,两个网络可以比较,第二个网络只是第一个的“转换”。的谢谢!
答案 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())
可以将pos
和label
字典存储为图形属性:
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)
您可以稍后执行图表中的任何操作,例如删除一些节点:
G.remove_nodes_from([(0,0),(0,2),(2,2),(2,1)])
重新绘制图表而不需要重新计算pos
或label
词典,因为条目会自动使用图形操作进行更新。以下行与上面的绘图调用完全相同:
nx.draw_networkx(G, pos=nx.get_node_attributes(G, 'pos'),
labels=nx.get_node_attributes(G, 'labels'),
with_labels=True, node_size=500)
但这一次,产生了不同的形象:
简而言之:在节点/边缘属性中存储所有内容,因为它们将随图更改自动更新。
答案 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)
答案 2 :(得分:1)
我很难理解你为什么要问这个问题 - 代码基本上应该完全按你所希望的那样工作。但是,您有一个错误,可能是导致您提出此问题的错误。
G2= G.remove_nodes_from(failed_nodes_dict) #Failed_node_dict holds the disrupted nodes
这会使G2
成为None
。 G.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
在此代码中永远不会更改。