Python NetworkX - 为什么图形总是随机旋转?

5
如果我使用NetworkX和Matplotlib多次生成同一图形,则每次生成时都会随机旋转:

运行1: Run 1

运行2: enter image description here

在不更改脚本或输入数据的情况下,每次生成图形时都会随机旋转。是否可能指定方向?

随着图形变得越来越密集(上面仅是样本,但最终我将拥有数千个节点和边),如果移动了图形图像,新添加的节点或边将很难看到。

import networkx as nx
import matplotlib.pyplot as plt
from networkx.readwrite import json_graph
#
# The graph data is loaded from JSON
#
graph = json_graph.node_link_graph(input_json)
    pos = nx.spring_layout(graph)
    nx.draw(graph, pos, with_labels=True, node_size=300)
    edge_labels=dict([((u,v,),d['weight']) for u,v,d in graph.edges(data=True)])
    nx.draw_networkx_edge_labels(graph, pos, edge_labels=edge_labels)
    plt.savefig("test.png")
第二个不太重要的问题是为什么从R1到R2和从R1到R5的边/线如此之长?更新:我没有在JSON数据源中设置"length"属性。
3个回答

9

我刚刚发现,你可以修复随机生成图形的初始状态:只需给生成器提供种子,它就会始终生成相同的随机位置集。

random_pos = nx.random_layout(graph, seed=42)
pos = nx.spring_layout(graph, pos=random_pos)

5

从文档中可以看出:

spring_layout(G, dim=2, k=None, pos=None, fixed=None, iterations=50, weight='weight', scale=1.0)

pos : dict 或 None(可选,默认值为None)

节点的初始位置,以字典形式给出,其中节点作为键,列表或元组作为值。如果为None,则使用随机初始位置。

因此,如果您没有指定节点的初始位置,NetworkX将随机生成初始位置。

https://networkx.github.io/documentation/networkx-1.9/reference/generated/networkx.drawing.layout.spring_layout.html


1
那么这是否意味着我必须指定每个节点的确切位置?如果我知道这一点,我就不需要图形库了! - jwbensley
2
您可以重复使用pos变量。spring_layout()返回位置,而您已经将它们存储在pos变量中。因此,第一次让NetworkX随机定位节点,然后将位置保存到文件并在下次显示图形时重用位置。 - Corentin Limier
1
你不必知道确切的位置,只需给算法一个起始点,它就可以优化布局。然而,networkX并不是主要用于图形库(虽然它也可以做到这一点),而是用于分析网络(例如社交网络)的工具。 - Andy
此外,这些节点需要被设置为固定值: fixed = ["R1", "R2", "R3", "R4", "R5"]; nx.spring_layout(graph, pos=positions_json, fixed=fixed) - jwbensley

2
该算法具有随机初始化 - 这在网络布局中非常标准。您将在任何图形库中遇到相同的问题。您可以通过两种方式在NetworkX中复制相同的布局:保存节点位置字典(例如作为json)并在每次要可视化时重新加载它,或者向布局算法传递种子:

seed(int、RandomState实例或None(默认值= None)可选)-设置用于确定性节点布局的随机状态。如果是int,则种子是随机数生成器使用的种子;如果是numpy.random.RandomState实例,则种子是随机数生成器;如果是None,则随机数生成器是由numpy.random使用的RandomState实例。

希望这能帮助您!

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接