Networkx 多个圆形布局组合在一起

问题描述 投票:0回答:1

我正在尝试建立一个公司联系网络。主要公司位于中心。内圈是其子公司。外圈代表与子公司合作的公司。到目前为止我做了以下网络表示。

但问题来了。我希望内圈和外圈彼此靠近,换句话说,方向相同。我保留内圆的坐标,但无法根据固定内圆计算外圆的坐标。


G1 = nx.from_pandas_edgelist(layer1_edges,
                           source='source',
                           target='target',
                           create_using=nx.MultiDiGraph())


pos1 = nx.circular_layout(G1,  scale=200, center=(0, 0))
pos1["centered_node"] = np.array([0.0, 0.0])

G2 = nx.from_pandas_edgelist(layer2_edges,
                           source='source',
                           target='target',
                           create_using=nx.MultiDiGraph())


pos2 = nx.circular_layout(G2,  scale=300, center=(0, 0))

F = nx.compose(G1, G2)
pos_f = pos1.copy()

for name, pos in pos2.items():
   if name not in pos_f:
       pos_f[name] = pos

python-3.x network-programming networkx network-analysis pyvis
1个回答
0
投票

以下答案假设您要解决的问题是连接的节点通常彼此距离不近。

看起来您有一个多方网络,并且正在尝试使用 shell 布局来绘制该网络。 NetworkX 确实实现了shell 布局但是,此函数没有实现边缘交叉减少或任何其他技术,以使连接的节点在可视化中彼此靠近。

由于 graph-tool 的 igraph 似乎都没有实现 shell 布局,因此您唯一的选择可能是 Netgraph,一个我编写和维护的库。 Netgraph 支持各种节点布局的边交叉减少,这在分层图中通常具有将连接的节点分组在一起的效果。对于壳布局,它使用 Eades & Wormald (1994) 中提出的算法。可以在此处找到教程。可以使用以下代码创建与您类似的简单可视化:

import numpy as np
import matplotlib.pyplot as plt
import networkx as nx

from itertools import product
from netgraph import InteractiveGraph

################################################################################
# SIMULATE DATA

# initialize shells
shell_sizes = [1, 20, 100]

ctr = 0
shells = []
for size in shell_sizes:
    shells.append(list(range(ctr, ctr+size)))
    ctr += size

# initialize edges
multipartite_edges = []

# the node in the first layer connects to all nodes in the second layer
multipartite_edges.extend(list(product(shells[0], shells[1])))

# nodes in subsequent layers only connect to a subset of nodes in the next layer
minimum_edges = 1
maximum_edges = 3
for p1, p2 in zip(shells[1:-1], shells[2:]):
    for target in p2:
        total_edges = np.random.randint(minimum_edges, maximum_edges, 1)
        sources = np.random.choice(p1, total_edges, replace=False)
        multipartite_edges.extend([(source, target) for source in sources])

graph = nx.Graph(multipartite_edges)

################################################################################
# DRAW

node_size = dict()
for node in range(ctr):
    if node in shells[0]:
        node_size[node] = 9
    elif node in shells[1]:
        node_size[node] = 3
    else:
        node_size[node] = 1

g = InteractiveGraph(
    graph, node_layout='shell',
    node_layout_kwargs=dict(shells=shells, reduce_edge_crossings=True),
    node_size=node_size,
    edge_width=0.5,
)
plt.show()

© www.soinside.com 2019 - 2024. All rights reserved.