如何改进networkx杠铃图的布局?

How to impoving the layout of networkx barbell graph?

我想用edgelist

画杠铃图Barbell(10,10)
0 1
0 2
0 3
0 4
0 5
0 6
0 7
0 8
0 9
1 2
1 3
1 4
1 5
1 6
1 7
1 8
1 9
2 3
2 4
2 5
2 6
2 7
2 8
2 9
3 4
3 5
3 6
3 7
3 8
3 9
4 5
4 6
4 7
4 8
4 9
5 6
5 7
5 8
5 9
6 7
6 8
6 9
7 8
7 9
8 9
9 10
10 11
11 12
12 13
13 14
14 15
15 16
16 17
17 18
18 19
19 20
20 21
20 22
20 23
20 24
20 25
20 26
20 27
20 28
20 29
21 22
21 23
21 24
21 25
21 26
21 27
21 28
21 29
22 23
22 24
22 25
22 26
22 27
22 28
22 29
23 24
23 25
23 26
23 27
23 28
23 29
24 25
24 26
24 27
24 28
24 29
25 26
25 27
25 28
25 29
26 27
26 28
26 29
27 28
27 29
28 29

我使用以下代码来可视化此图:

import numpy as np 
import networkx as nx
barbell = nx.read_edgelist('graph/barbell.edgelist')

classes = [0,] * len(gnx.nodes)
nonzero = m2 + 2
first = range(1, (nonzero + 1) // 2 + 1)
second = reversed(range(1, nonzero - len(first) + 1))
classes[m1 - 1 : (m1 + m2) + 1] = list(first) + list(second)

nx.draw(gnx, node_color=classes, cmap="jet")

然后,我可以得到如下图像:

然而,这篇论文struc2vec,使用相同的边缘并绘制出一个很好的布局如下:

那么是否可以像上面那样使用networkx改进杠铃图的布局?或者我需要使用其他工具吗?

这应该可以帮助您入门。

import networkx as nx
import matplotlib.pyplot as plt

n_clique, n_path = 10, 10
clique1 = nx.complete_graph(n_clique)
clique1_pos = nx.circular_layout(clique1)
clique2 = nx.complete_graph(n_clique)
clique2_mapping = {node: node + n_clique for node in clique2}
nx.relabel_nodes(clique2, clique2_mapping, copy=False) # avoids repeated nodes
x_diff, y_diff = 8, -1
clique2_pos = {node: clique1_pos[node-n_clique] + (x_diff, y_diff) for node in clique2}
path = nx.path_graph(n_path)
path_mapping = {node: node + 2 * n_clique for node in path}
nx.relabel_nodes(path, path_mapping, copy=False) # avoids repeated nodes
path_nodes = list(path.nodes)
path_half1_nodes = path_nodes[:n_path//2]
path_half2_nodes = path_nodes[n_path//2:]
path_dist = 0.9
clique2_entry = n_clique + n_clique // 2
path_half1_pos = {node: clique1_pos[0] + (path_dist + i * path_dist, 0) for i, node in enumerate(path_half1_nodes)}
path_half2_pos = {node: clique2_pos[clique2_entry] - (path_dist + i * path_dist, 0) for i, node in enumerate(path_half2_nodes[::-1])}
path_pos = {**path_half1_pos, **path_half2_pos}
barbell = nx.Graph()
barbell.add_edges_from(clique1.edges)
barbell.add_edges_from(clique2.edges)
barbell.add_edges_from(path.edges)
barbell.add_edges_from([(path_half1_nodes[0], 0), (path_half2_nodes[-1], clique2_entry)])
clique_pos = {**clique1_pos, **clique2_pos}
barbell_pos = {**clique_pos, **path_pos}
plt.figure(figsize=(20, 6))
nx.draw(barbell, pos=barbell_pos, with_labels=True)

Output