如何使用 NetworkX 的 rescale_layout?
How to use NetworkX's rescale_layout?
我很难理解如何使用 NetworkX 的 rescale_layout
。
文档说:pos (numpy array) – positions to be scaled. Each row is a position
这不是 NetworkX 其余部分用于绘图的标准“位置字典”。我试图在“pos dict”上使用 NetworkX 的 to_numpy_array
但没有成功,to_numpy_array
的输出是 Graph adjacency matrix
,它不符合 [=11= 的要求]的Each position is one row of the array
无论如何。
我问的原因是因为我有一个从一些数据生成的网络,然后由 spring_layout 移动,但有些位置不会在 [=30] 中生成=] 方式,所以我实现了一种手动调整这些位置的方法,如果保证网络的位置始终位于某个预定义的边界内(例如图中的 [-10, 10]),这将更容易做到。然后我需要在节点上方写节点标签。
奖金问题:我想在位置 (x,y+r) 处写标签,其中 r 是绘制节点的半径。通过取输入节点大小的平方根并将其除以任意因子,我有一种破解的方法。但是,我不知道绘制的节点大小实际上是如何确定的,我制作的每个单独的图似乎每个图都有不同的内部比例,而绘制的节点大小似乎保持不变。
我翻阅了大量文档以试图理解底层方法,但我剥离的每一层只会增加更多的混乱。
这是您的布局示例:
pos = nx.random_layout(G)
它被分配给一个看起来像这样的字典:
{0: array([0.81931883, 0.8001609 ], dtype=float32),
1: array([0.89695644, 0.6070644 ], dtype=float32),
2: array([0.89160234, 0.47174907], dtype=float32),
3: array([0.20430276, 0.8206253 ], dtype=float32),
4: array([0.27929142, 0.08657268], dtype=float32)}
现在,由于 nx.rescale_layout()
的输入应该是 numpy
数组,您可以使用命令提取它
np.array(list(pos.values()))
请注意,这种方式在 Python 的其他版本上可能 different。
我将说明 pos
参数重新缩放后发生的变化:
import networkx as nx
import matplotlib.pyplot as plt
import numpy as np
G = nx.Graph()
G.add_edges_from([[0,1],[1,2],[2,3],[3,4],[4,0]])
pos = nx.random_layout(G)
coords = np.array(list(pos.values()))
fig, ax = plt.subplots()
plt.subplot(211)
nx.draw_networkx(G, pos, with_labels=True)
plt.axis('on'); plt.tick_params(left=True, bottom=True, labelleft=True, labelbottom=True) #force axis to turn on
plt.subplot(212)
new_pos = nx.rescale_layout(coords)
nx.draw_networkx(G, new_pos, with_labels=True)
plt.axis('on'); plt.tick_params(left=True, bottom=True, labelleft=True, labelbottom=True) #force axis turn on
plt.show()
我很难理解如何使用 NetworkX 的 rescale_layout
。
文档说:pos (numpy array) – positions to be scaled. Each row is a position
这不是 NetworkX 其余部分用于绘图的标准“位置字典”。我试图在“pos dict”上使用 NetworkX 的 to_numpy_array
但没有成功,to_numpy_array
的输出是 Graph adjacency matrix
,它不符合 [=11= 的要求]的Each position is one row of the array
无论如何。
我问的原因是因为我有一个从一些数据生成的网络,然后由 spring_layout 移动,但有些位置不会在 [=30] 中生成=] 方式,所以我实现了一种手动调整这些位置的方法,如果保证网络的位置始终位于某个预定义的边界内(例如图中的 [-10, 10]),这将更容易做到。然后我需要在节点上方写节点标签。
奖金问题:我想在位置 (x,y+r) 处写标签,其中 r 是绘制节点的半径。通过取输入节点大小的平方根并将其除以任意因子,我有一种破解的方法。但是,我不知道绘制的节点大小实际上是如何确定的,我制作的每个单独的图似乎每个图都有不同的内部比例,而绘制的节点大小似乎保持不变。
我翻阅了大量文档以试图理解底层方法,但我剥离的每一层只会增加更多的混乱。
这是您的布局示例:
pos = nx.random_layout(G)
它被分配给一个看起来像这样的字典:
{0: array([0.81931883, 0.8001609 ], dtype=float32),
1: array([0.89695644, 0.6070644 ], dtype=float32),
2: array([0.89160234, 0.47174907], dtype=float32),
3: array([0.20430276, 0.8206253 ], dtype=float32),
4: array([0.27929142, 0.08657268], dtype=float32)}
现在,由于 nx.rescale_layout()
的输入应该是 numpy
数组,您可以使用命令提取它
np.array(list(pos.values()))
请注意,这种方式在 Python 的其他版本上可能 different。
我将说明 pos
参数重新缩放后发生的变化:
import networkx as nx
import matplotlib.pyplot as plt
import numpy as np
G = nx.Graph()
G.add_edges_from([[0,1],[1,2],[2,3],[3,4],[4,0]])
pos = nx.random_layout(G)
coords = np.array(list(pos.values()))
fig, ax = plt.subplots()
plt.subplot(211)
nx.draw_networkx(G, pos, with_labels=True)
plt.axis('on'); plt.tick_params(left=True, bottom=True, labelleft=True, labelbottom=True) #force axis to turn on
plt.subplot(212)
new_pos = nx.rescale_layout(coords)
nx.draw_networkx(G, new_pos, with_labels=True)
plt.axis('on'); plt.tick_params(left=True, bottom=True, labelleft=True, labelbottom=True) #force axis turn on
plt.show()