使用 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
我需要生成一个具有 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