使用 grid_2d_graph 在 networkx 中绘制 MxM 节点的正方形网格时移除旋转效果

Remove rotation effect when drawing a square grid of MxM nodes in networkx using grid_2d_graph

我需要生成一个具有 100x100 个节点的规则图(也称为网格网络)。我开始使用以下代码绘制 10x10 图:

import numpy
from numpy import *
import networkx as nx
from networkx import *
import matplotlib.pyplot as plt

G=nx.grid_2d_graph(10,10)        
nx.draw(G)

plt.axis('off')
plt.show()

但我得到的是:

有什么方法可以消除输出的这种旋转效果吗?我的最终网络必须看起来像国际象棋table,就像这样(请忽略标签):

此外,我需要为每个节点提供其 ID,范围从 0 到 9999(在 100x100 网络的情况下)。任何想法将不胜感激!

默认情况下,networkx.draw 使用 spring 布局。相反,您可以使用参数 pos 提供您自己的仓位。这实际上非常简单,因为给定的节点标签 networkx.grid_2d_graph 实际上是一个(行,列)元组:

>>> G=nx.grid_2d_graph(2,2)
[(0, 1), (1, 0), (0, 0), (1, 1)]

因此您可以使用节点的名称作为其位置。所以你只需要创建一个字典映射节点到自己,并将其作为位置传递。

pos = dict( (n, n) for n in G.nodes() )

但是,由于您还想添加节点标签,因此您应该使用 networkx.draw_networkx,它将自定义标签的字典作为可选参数。您需要将节点映射到新标签的字典。由于 NetworkX 默认为每个节点分配标签 (row, column),我们可以只用 row * 10 + column:

标记每个节点
labels = dict( ((i, j), i * 10 + j) for i, j in G.nodes() )

将它们放在一起,您将得到以下代码,生成下图:

import networkx as nx
import matplotlib.pyplot as plt

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

plt.axis('off')
plt.show()

编辑

使用@AbdallahSobehy 的建议,我们可以从左到右,从上到下标记节点。

labels = dict( ((i, j), i + (N-1-j) * 10 ) for i, j in G.nodes() )

澄清支持@mdml的回答(这里说的都是参考@mdml的回答)

1- 节点密钥使用 nx.grid_2d_graph

给节点的键是隐式地给每个节点一个描述行和列的 (i,j) 键。访问 (0,0) -> G[(0,0)]

处的节点

2- 用于绘图的标签

绘图指定的标签应按照问题中的编号方案进行如下操作:

labels = dict( ((i, j), i + (N-1-j) * N ) for i, j in G.nodes() ) 

请注意它应该是 N 而不是 10,这样更通用,就像你改变了 N 标签将不是你期望的那样。此外,这些标签仅用于绘图,因此与访问节点无关。

3- 将键链接到标签

accessing node -> G[(0,0)]指的是绘制图中的节点90(一般在左下角),G[(1,0)]就是右边的节点(91) ,而 G[(0,1)] 是标记为 (80) 的节点,因此请注意此约定,因为它可能并不明显。

4- 给出与图上的节点相同的节点 ID

您可以使用 labels 字典为每个节点添加一个名为 id 的属性,该节点保存您在绘制的图中看到的整数:

for (i,j) in labels:
    G.node[(i,j)]['id'] = labels[(i,j)]

我创建了一个 N=2 的简单图表,我使用了点 2 和 3 处的线,然后我打印出 Id,如下所示:

for i in xrange(N):
    for j in xrange(N):
        print 'Node ID at: (%d, %d) = %d'  %(i,j,G.node[(i,j)]['id'])
plt.axis('off')
plt.show()

结果:

Node ID at: (0, 0) = 2
Node ID at: (0, 1) = 0
Node ID at: (1, 0) = 3
Node ID at: (1, 1) = 1