Networkx绘图时如何固定图布局保证每次运行方向一致
问题根源
两次nx.draw调用参数不一致导致布局随机:
- 第一次绘图传入了你提前生成的固定节点坐标,布局是确定的
- 第二次(最终带色条的出图)调用
nx.draw时未传入pos参数,Networkx会默认使用带随机初始化的弹簧布局生成节点位置,未固定随机种子的前提下每次运行生成的位置、方向都会随机变化,和邻接矩阵是否固定无关。
修复方案
- 提前将预定义的节点坐标存为固定变量,避免重复取值
- 所有
nx.draw调用都传入这个固定坐标参数,不要依赖默认随机布局 - 补全绘图对象的ax绑定,避免色条和画布错位
修正后的可运行核心代码:
import networkx as nx import numpy as np import matplotlib import matplotlib.pyplot as plt N = 2 def pos(): x, y = 1, N + 3 - 1 for _ in range(2 * N * (N + 1)): yield (x, y) y -= (x + 2) // (N + 3) x = (x + 2) % (N + 3) G = nx.Graph() it_pos = pos() for u in range(2 * N * (N + 1)): G.add_node(u + 1, pos=next(it_pos)) if u % (2 * N + 1) < N: for v in (u - 2 * N - 1, u - N - 1, u - N): if G.has_node(v + 1): G.add_edge(u + 1, v + 1) elif u % (2 * N + 1) == N: G.add_edge(u + 1, u - N + 1) elif u % (2 * N + 1) < 2 * N: for v in (u - 1, u - N - 1, u - N): G.add_edge(u + 1, v + 1) else: for v in (u - 1, u - N - 1): G.add_edge(u + 1, v + 1) # 提前提取固定节点坐标 fixed_pos = nx.get_node_attributes(G, 'pos') D=len(G.nodes) print(D) fig, ax = plt.subplots(1, 1) P=np.array([[1.00000000e-04, 1.90053824e-05, 3.70041863e-05, 5.50029902e-05, 7.30017941e-05, 8.20011961e-05, 1.00059804e-05, 9.10005980e-05, 2.80047843e-05, 1.00657843e-06, 4.60035882e-05, 1.01000000e-04]]) # 关键修正:传入固定pos参数,绑定ax对象 nx.draw(G, pos=fixed_pos, with_labels=True, node_color=[P], node_size=1000, cmap='Blues', ax=ax) # ------------------------------------- norm = matplotlib.colors.Normalize(vmin=np.min(P), vmax=np.max(P)) sm = plt.cm.ScalarMappable(cmap='Blues', norm=norm) sm.set_array([]) clb=fig.colorbar(sm, ax=ax) clb.set_label('r (m)',labelpad=-50, y=1.1, rotation=0) # ------------------------------------- plt.show()
补充说明
如果后续不需要自定义坐标,要使用Networkx自带的布局算法(如spring_layout、kamada_kawai_layout等),只需要在调用布局函数时传入固定随机种子即可保证每次布局一致,示例:pos = nx.spring_layout(G, seed=42)
修复后运行即可得到固定的预期布局:
未修复时每次运行会生成随机布局,示例效果:
内容的提问来源于stack exchange,提问作者Wiz123
相关产品推荐
相关产品推荐

