Порядок узлов с помощью networkx.drawing.layout.circular_layout
Я относительно новичок в программировании на Python, и я использую следующий код для создания графа с 40 узлами, а расположение узлов задается с использованием этого кода:
pos = nx.circular_layout(graph_anchor, **kwargs)
Следующий код создает graph_anchor:
graph_anchor = convert_ebunch_to_graph(ebunch_anchor)
def convert_ebunch_to_graph(ebunch):
g = nx.DiGraph()
g.add_weighted_edges_from(ebunch)
Мой вопрос: как мне определить, в каком порядке отображаются узлы, т.е. как мне понять, как этот код определяет, какие узлы разместить рядом друг с другом и в каком порядке их расположить?
1 ответ
Из источника nx.circular_layout:
def circular_layout(G, dim=2, scale=1, center=None): # dim=2 only """Position nodes on a circle. Parameters ---------- G : NetworkX graph or list of nodes dim : int Dimension of layout, currently only dim=2 is supported scale : float Scale factor for positions center : array-like or None Coordinate pair around which to center the layout. Returns ------- dict : A dictionary of positions keyed by node Examples -------- >>> G=nx.path_graph(4) >>> pos=nx.circular_layout(G) Notes ------ This algorithm currently only works in two dimensions and does not try to minimize edge crossings. """ import numpy as np G, center = process_params(G, center, dim) if len(G) == 0: pos = {} elif len(G) == 1: pos = {G.nodes()[0]: center} else: # Discard the extra angle since it matches 0 radians. theta = np.linspace(0, 1, len(G) + 1)[:-1] * 2 * np.pi theta = theta.astype(np.float32) pos = np.column_stack([np.cos(theta), np.sin(theta)]) pos = _rescale_layout(pos, scale=scale) + center pos = dict(zip(G, pos)) return pos
Кажется, что позиции генерируются делением 360 градусов на количество узлов. какой узел заканчивается, где определяется этой строкой:
pos = dict(zip(G, pos))
zip(G, pos) выполняет итерацию по узлам графа по порядку. и назначает им должности. Если вы хотите изменить позицию, вам нужно изменить порядок.
Пример:
# make dummy graph
G = nx.from_numpy_array(np.random.rand(12,12)>0.5)
# test order of nodes:
for node in G.nodes:
print(node)
0
1
2
3
4
5
6
7
8
9
10
11
pos = nx.circular_layout(G)
nx.draw_networkx(G, pos=pos)
Здесь первая назначенная позиция - это позиция узла 0, затем мы идем против часовой стрелки.
Мне не удалось найти простой способ изменить порядок узлов в G, поэтому вот небольшой обходной путь, который создает новый граф со случайным порядком:
nodes = list(G.nodes(data=True))
edges = list(G.edges(data=True))
np.random.shuffle(nodes)
H=nx.Graph()
H.add_nodes_from(nodes)
H.add_edges_from(edges)
pos = nx.circular_layout(H)
nx.draw_networkx(H, pos=pos)
Таким образом, изменение порядка узлов внутри графа меняет место их расположения в круговой компоновке.