Порядок узлов с помощью 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)

Таким образом, изменение порядка узлов внутри графа меняет место их расположения в круговой компоновке.

Другие вопросы по тегам