如何将 networkx 节点位置转换为 python-igraph 节点位置(布局)
How to convert networkx node positions to python-igraph node positions (layout)
我有一个节点位置字典(布局)node_pos_dict
(定义在此 post 的底部),其中节点 ID 作为键,节点位置作为值。为了简单起见,我省略了边缘。我正在使用它在 networkx
:
中绘制图表 G
import networkx as nx
import matplotlib.pyplot as plt
G = nx.Graph()
nodes = [i for i in range(100)]
G.add_nodes_from(nodes)
fig, ax = plt.subplots(figsize=(8, 10))
nx.draw_networkx(G, pos=node_pos_dict, ax=ax, with_labels=False)
plt.axis('off')
plt.tight_layout()
plt.show()
这给出了下图:
我正在尝试在 python-igraph
图中获得相同的布局,以便使用该包中提供的一些社区突出显示功能。
node_pos_dict
字典定义为:
node_pos_dict = {0: (144.3188, 119.44731), 1: (124.09237, -33.596596), 2: (-101.445206, -230.88632), 3: (161.83209, 0.38454914), 4: (-82.14839, -245.6368), 5: (-85.32251, -206.46722), 6: (151.14572, 82.951904), 7: (186.52087, 104.135445), 8: (-72.2828, -222.62256), 9: (180.5292, -25.867607), 10: (113.72072, 83.670166), 11: (175.75494, 134.25246), 12: (-98.248184, 116.63043), 13: (198.58878, 123.65588), 14: (-132.95235, 4.804117), 15: (53.636906, 25.208912), 16: (-96.807945, -118.86241), 17: (-42.95986, -150.97101), 18: (145.22792, -64.54069), 19: (179.72614, 60.22186), 20: (125.6956, -118.42535), 21: (-110.77464, -162.60362), 22: (-117.83106, 26.956175), 23: (-117.83714, -187.87215), 24: (-95.32954, 232.9699), 25: (34.003876, 321.52094), 26: (-68.26795, 295.06512), 27: (-63.048847, 239.11066), 28: (-75.68445, -28.730654), 29: (75.17831, -75.029854), 30: (-28.244192, -19.343128), 31: (-56.09895, -63.656025), 32: (-66.53724, -173.97981), 33: (-91.61079, -144.26376), 34: (-7.710302, 236.83008), 35: (92.75697, -83.03888), 36: (-40.09295, 73.20203), 37: (-142.14711, -26.725447), 38: (3.575774, 17.843548), 39: (-91.95948, 77.86012), 40: (200.68674, 89.53631), 41: (0.8394178, -107.49954), 42: (12.500817, -50.1444), 43: (-127.56198, 149.43623), 44: (-11.264021, -41.274815), 45: (47.784233, -134.48622), 46: (7.4685154, -76.65924), 47: (194.3162, 23.981865), 48: (212.50543, 70.98608), 49: (153.31735, 43.914085), 50: (-133.44196, 114.36704), 51: (5.701025, 85.38443), 52: (13.946121, 153.68181), 53: (-25.266066, 187.4926), 54: (25.329966, 294.0766), 55: (-85.00704, 266.47177), 56: (-61.753925, 168.47987), 57: (-56.519913, 272.79797), 58: (-21.517618, 265.3851), 59: (-48.90309, -5.526082), 60: (-109.32565, -28.847795), 61: (-56.12136, -131.05943), 62: (-19.714733, -123.95303), 63: (10.257481, 316.74423), 64: (-92.10561, 46.171707), 65: (38.559624, 259.36142), 66: (9.978462, 117.79648), 67: (-25.08352, -97.375275), 68: (40.990887, 213.83508), 69: (-14.715101, 145.84436), 70: (11.447578, 271.5689), 71: (64.48909, -109.939255), 72: (94.36185, -137.68431), 73: (9.287598, 172.41864), 74: (20.429993, -143.1729), 75: (133.95541, 18.159035), 76: (-123.929146, -47.133484), 77: (-31.405153, -173.0785), 78: (19.702349, 239.63599), 79: (-120.557686, 240.36055), 80: (-108.39326, 143.99583), 81: (-88.96142, 15.370992), 82: (-159.7047, -13.08283), 83: (-42.595707, 230.62224), 84: (180.81544, -148.1233), 85: (162.917, -181.4351), 86: (-0.9790172, 293.15427), 87: (143.01433, -204.42032), 88: (191.59567, -170.5149), 89: (157.8586, -37.603153), 90: (167.32344, -212.64957), 91: (59.633255, 209.17967), 92: (187.9868, -198.9159), 93: (147.55754, -155.44865), 94: (146.49014, -131.13498), 95: (73.7772, 229.48337), 96: (-53.127087, -105.21127), 97: (-114.917305, 264.62866), 98: (127.29826, -183.27467), 99: (-27.884693, 111.62785)}
该词典与使用 networkx
的任何内置布局算法获得的词典非常相似,例如Kamada-Kawai 布局:
alt_node_pos_dict = nx.kamada_kawai_layout(G)
alt_node_pos_dict = {0: array([ 9.99999996e-01, -2.42300517e-09]), 1: array([0.9980267 , 0.06279052]), 2: array([0.99211487, 0.12533325]), 3: array([0.98228704, 0.18738127]), 4: array([0.96858321, 0.24868989]), 5: array([0.95105666, 0.30901704]), 6: array([0.92977645, 0.36812454]), 7: array([0.90482706, 0.4257793 ]), 8: array([0.87630662, 0.48175364]), 9: array([0.84432796, 0.53582681]), 10: array([0.809017 , 0.58778526]), 11: array([0.77051321, 0.63742396]), 12: array([0.72896867, 0.68454714]), 13: array([0.68454714, 0.72896867]), 14: array([0.63742397, 0.77051322]), 15: array([0.58778529, 0.80901704]), 16: array([0.53582671, 0.84432777]), 17: array([0.48175365, 0.87630665]), 18: array([0.42577934, 0.90482715]), 19: array([0.36812454, 0.92977645]), 20: array([0.30901702, 0.95105659]), 21: array([0.24868991, 0.96858329]), 22: array([0.18738128, 0.98228708]), 23: array([0.12533325, 0.99211486]), 24: array([0.06279052, 0.9980267 ]), 25: array([5.77200179e-09, 1.00000000e+00]), 26: array([-0.06279052, 0.9980267 ]), 27: array([-0.12533326, 0.99211487]), 28: array([-0.18738128, 0.98228709]), 29: array([-0.24868993, 0.96858333]), 30: array([-0.30901695, 0.9510564 ]), 31: array([-0.36812456, 0.92977649]), 32: array([-0.42577926, 0.90482702]), 33: array([-0.48175365, 0.87630662]), 34: array([-0.53582694, 0.84432814]), 35: array([-0.58778513, 0.80901682]), 36: array([-0.63742402, 0.77051328]), 37: array([-0.6845472 , 0.72896873]), 38: array([-0.72896847, 0.68454697]), 39: array([-0.77051329, 0.63742405]), 40: array([-0.80901708, 0.58778534]), 41: array([-0.84432783, 0.53582676]), 42: array([-0.87630683, 0.48175374]), 43: array([-0.90482693, 0.42577922]), 44: array([-0.92977668, 0.36812462]), 45: array([-0.95105635, 0.30901694]), 46: array([-0.96858329, 0.24868992]), 47: array([-0.98228706, 0.18738128]), 48: array([-0.99211486, 0.12533326]), 49: array([-0.99802669, 0.06279053]), 50: array([-9.99999983e-01, 1.60126757e-08]), 51: array([-0.99802675, -0.0627905 ]), 52: array([-0.9921147 , -0.12533324]), 53: array([-0.98228737, -0.18738135]), 54: array([-0.96858307, -0.24868987]), 55: array([-0.95105661, -0.30901703]), 56: array([-0.92977645, -0.36812454]), 57: array([-0.90482715, -0.42577933]), 58: array([-0.87630663, -0.48175364]), 59: array([-0.84432783, -0.53582672]), 60: array([-0.80901714, -0.58778534]), 61: array([-0.77051324, -0.637424 ]), 62: array([-0.72896872, -0.6845472 ]), 63: array([-0.68454696, -0.72896848]), 64: array([-0.63742394, -0.77051313]), 65: array([-0.58778527, -0.80901696]), 66: array([-0.53582677, -0.84432793]), 67: array([-0.48175369, -0.87630674]), 68: array([-0.4257793 , -0.90482711]), 69: array([-0.36812453, -0.92977647]), 70: array([-0.30901697, -0.95105646]), 71: array([-0.24868993, -0.96858336]), 72: array([-0.18738128, -0.98228711]), 73: array([-0.12533326, -0.99211489]), 74: array([-0.06279052, -0.99802671]), 75: array([-5.68942479e-09, -9.99999986e-01]), 76: array([ 0.06279051, -0.99802672]), 77: array([ 0.12533325, -0.99211492]), 78: array([ 0.18738129, -0.98228721]), 79: array([ 0.24868982, -0.96858298]), 80: array([ 0.30901699, -0.95105657]), 81: array([ 0.36812451, -0.92977645]), 82: array([ 0.42577932, -0.90482717]), 83: array([ 0.48175365, -0.87630669]), 84: array([ 0.53582682, -0.84432792]), 85: array([ 0.58778521, -0.80901689]), 86: array([ 0.63742404, -0.77051328]), 87: array([ 0.68454717, -0.72896867]), 88: array([ 0.72896867, -0.68454713]), 89: array([ 0.77051321, -0.63742395]), 90: array([ 0.80901698, -0.58778523]), 91: array([ 0.8443279 , -0.53582677]), 92: array([ 0.87630668, -0.48175367]), 93: array([ 0.9048271 , -0.42577932]), 94: array([ 0.92977651, -0.36812457]), 95: array([ 0.95105659, -0.30901703]), 96: array([ 0.96858306, -0.24868987]), 97: array([ 0.9822874 , -0.18738136]), 98: array([ 0.99211474, -0.12533326]), 99: array([ 0.99802665, -0.06279054])}
不同之处在于 alt_node_pos_dict
包含坐标数组而不是 node_pos_dict
中的元组。
为了在igraph
中获得相同的布局:
import igraph as ig
H = ig.Graph.from_networkx(G)
node_pos_list = [[node_pos_dict[node][0], -node_pos_dict[node][1]] for node in H.vs['_nx_name']]
ig.plot(H_ig, layout=node_pos_list, bbox=(800, 1000)).show()
这给出了下图:
我相信 networkx
的后端绘图库是 matplolib
,它使用大小和 dpi,而 python-igraph
使用像素。这就是为什么您需要设置 bbox=(800, 1000)
(或具有相同比例的其他值)以获得与问题中原始 figsize=(8, 10)
相同的纵横比。另一个需要注意的重要事项是创建时y坐标中的减号 node_pos_list
:
node_pos_list = [[node_pos_dict[node][0], -node_pos_dict[node][1]] for node in H.vs['_nx_name']]
如果减号是不,情节是反转的:
我有一个节点位置字典(布局)node_pos_dict
(定义在此 post 的底部),其中节点 ID 作为键,节点位置作为值。为了简单起见,我省略了边缘。我正在使用它在 networkx
:
G
import networkx as nx
import matplotlib.pyplot as plt
G = nx.Graph()
nodes = [i for i in range(100)]
G.add_nodes_from(nodes)
fig, ax = plt.subplots(figsize=(8, 10))
nx.draw_networkx(G, pos=node_pos_dict, ax=ax, with_labels=False)
plt.axis('off')
plt.tight_layout()
plt.show()
这给出了下图:
我正在尝试在 python-igraph
图中获得相同的布局,以便使用该包中提供的一些社区突出显示功能。
node_pos_dict
字典定义为:
node_pos_dict = {0: (144.3188, 119.44731), 1: (124.09237, -33.596596), 2: (-101.445206, -230.88632), 3: (161.83209, 0.38454914), 4: (-82.14839, -245.6368), 5: (-85.32251, -206.46722), 6: (151.14572, 82.951904), 7: (186.52087, 104.135445), 8: (-72.2828, -222.62256), 9: (180.5292, -25.867607), 10: (113.72072, 83.670166), 11: (175.75494, 134.25246), 12: (-98.248184, 116.63043), 13: (198.58878, 123.65588), 14: (-132.95235, 4.804117), 15: (53.636906, 25.208912), 16: (-96.807945, -118.86241), 17: (-42.95986, -150.97101), 18: (145.22792, -64.54069), 19: (179.72614, 60.22186), 20: (125.6956, -118.42535), 21: (-110.77464, -162.60362), 22: (-117.83106, 26.956175), 23: (-117.83714, -187.87215), 24: (-95.32954, 232.9699), 25: (34.003876, 321.52094), 26: (-68.26795, 295.06512), 27: (-63.048847, 239.11066), 28: (-75.68445, -28.730654), 29: (75.17831, -75.029854), 30: (-28.244192, -19.343128), 31: (-56.09895, -63.656025), 32: (-66.53724, -173.97981), 33: (-91.61079, -144.26376), 34: (-7.710302, 236.83008), 35: (92.75697, -83.03888), 36: (-40.09295, 73.20203), 37: (-142.14711, -26.725447), 38: (3.575774, 17.843548), 39: (-91.95948, 77.86012), 40: (200.68674, 89.53631), 41: (0.8394178, -107.49954), 42: (12.500817, -50.1444), 43: (-127.56198, 149.43623), 44: (-11.264021, -41.274815), 45: (47.784233, -134.48622), 46: (7.4685154, -76.65924), 47: (194.3162, 23.981865), 48: (212.50543, 70.98608), 49: (153.31735, 43.914085), 50: (-133.44196, 114.36704), 51: (5.701025, 85.38443), 52: (13.946121, 153.68181), 53: (-25.266066, 187.4926), 54: (25.329966, 294.0766), 55: (-85.00704, 266.47177), 56: (-61.753925, 168.47987), 57: (-56.519913, 272.79797), 58: (-21.517618, 265.3851), 59: (-48.90309, -5.526082), 60: (-109.32565, -28.847795), 61: (-56.12136, -131.05943), 62: (-19.714733, -123.95303), 63: (10.257481, 316.74423), 64: (-92.10561, 46.171707), 65: (38.559624, 259.36142), 66: (9.978462, 117.79648), 67: (-25.08352, -97.375275), 68: (40.990887, 213.83508), 69: (-14.715101, 145.84436), 70: (11.447578, 271.5689), 71: (64.48909, -109.939255), 72: (94.36185, -137.68431), 73: (9.287598, 172.41864), 74: (20.429993, -143.1729), 75: (133.95541, 18.159035), 76: (-123.929146, -47.133484), 77: (-31.405153, -173.0785), 78: (19.702349, 239.63599), 79: (-120.557686, 240.36055), 80: (-108.39326, 143.99583), 81: (-88.96142, 15.370992), 82: (-159.7047, -13.08283), 83: (-42.595707, 230.62224), 84: (180.81544, -148.1233), 85: (162.917, -181.4351), 86: (-0.9790172, 293.15427), 87: (143.01433, -204.42032), 88: (191.59567, -170.5149), 89: (157.8586, -37.603153), 90: (167.32344, -212.64957), 91: (59.633255, 209.17967), 92: (187.9868, -198.9159), 93: (147.55754, -155.44865), 94: (146.49014, -131.13498), 95: (73.7772, 229.48337), 96: (-53.127087, -105.21127), 97: (-114.917305, 264.62866), 98: (127.29826, -183.27467), 99: (-27.884693, 111.62785)}
该词典与使用 networkx
的任何内置布局算法获得的词典非常相似,例如Kamada-Kawai 布局:
alt_node_pos_dict = nx.kamada_kawai_layout(G)
alt_node_pos_dict = {0: array([ 9.99999996e-01, -2.42300517e-09]), 1: array([0.9980267 , 0.06279052]), 2: array([0.99211487, 0.12533325]), 3: array([0.98228704, 0.18738127]), 4: array([0.96858321, 0.24868989]), 5: array([0.95105666, 0.30901704]), 6: array([0.92977645, 0.36812454]), 7: array([0.90482706, 0.4257793 ]), 8: array([0.87630662, 0.48175364]), 9: array([0.84432796, 0.53582681]), 10: array([0.809017 , 0.58778526]), 11: array([0.77051321, 0.63742396]), 12: array([0.72896867, 0.68454714]), 13: array([0.68454714, 0.72896867]), 14: array([0.63742397, 0.77051322]), 15: array([0.58778529, 0.80901704]), 16: array([0.53582671, 0.84432777]), 17: array([0.48175365, 0.87630665]), 18: array([0.42577934, 0.90482715]), 19: array([0.36812454, 0.92977645]), 20: array([0.30901702, 0.95105659]), 21: array([0.24868991, 0.96858329]), 22: array([0.18738128, 0.98228708]), 23: array([0.12533325, 0.99211486]), 24: array([0.06279052, 0.9980267 ]), 25: array([5.77200179e-09, 1.00000000e+00]), 26: array([-0.06279052, 0.9980267 ]), 27: array([-0.12533326, 0.99211487]), 28: array([-0.18738128, 0.98228709]), 29: array([-0.24868993, 0.96858333]), 30: array([-0.30901695, 0.9510564 ]), 31: array([-0.36812456, 0.92977649]), 32: array([-0.42577926, 0.90482702]), 33: array([-0.48175365, 0.87630662]), 34: array([-0.53582694, 0.84432814]), 35: array([-0.58778513, 0.80901682]), 36: array([-0.63742402, 0.77051328]), 37: array([-0.6845472 , 0.72896873]), 38: array([-0.72896847, 0.68454697]), 39: array([-0.77051329, 0.63742405]), 40: array([-0.80901708, 0.58778534]), 41: array([-0.84432783, 0.53582676]), 42: array([-0.87630683, 0.48175374]), 43: array([-0.90482693, 0.42577922]), 44: array([-0.92977668, 0.36812462]), 45: array([-0.95105635, 0.30901694]), 46: array([-0.96858329, 0.24868992]), 47: array([-0.98228706, 0.18738128]), 48: array([-0.99211486, 0.12533326]), 49: array([-0.99802669, 0.06279053]), 50: array([-9.99999983e-01, 1.60126757e-08]), 51: array([-0.99802675, -0.0627905 ]), 52: array([-0.9921147 , -0.12533324]), 53: array([-0.98228737, -0.18738135]), 54: array([-0.96858307, -0.24868987]), 55: array([-0.95105661, -0.30901703]), 56: array([-0.92977645, -0.36812454]), 57: array([-0.90482715, -0.42577933]), 58: array([-0.87630663, -0.48175364]), 59: array([-0.84432783, -0.53582672]), 60: array([-0.80901714, -0.58778534]), 61: array([-0.77051324, -0.637424 ]), 62: array([-0.72896872, -0.6845472 ]), 63: array([-0.68454696, -0.72896848]), 64: array([-0.63742394, -0.77051313]), 65: array([-0.58778527, -0.80901696]), 66: array([-0.53582677, -0.84432793]), 67: array([-0.48175369, -0.87630674]), 68: array([-0.4257793 , -0.90482711]), 69: array([-0.36812453, -0.92977647]), 70: array([-0.30901697, -0.95105646]), 71: array([-0.24868993, -0.96858336]), 72: array([-0.18738128, -0.98228711]), 73: array([-0.12533326, -0.99211489]), 74: array([-0.06279052, -0.99802671]), 75: array([-5.68942479e-09, -9.99999986e-01]), 76: array([ 0.06279051, -0.99802672]), 77: array([ 0.12533325, -0.99211492]), 78: array([ 0.18738129, -0.98228721]), 79: array([ 0.24868982, -0.96858298]), 80: array([ 0.30901699, -0.95105657]), 81: array([ 0.36812451, -0.92977645]), 82: array([ 0.42577932, -0.90482717]), 83: array([ 0.48175365, -0.87630669]), 84: array([ 0.53582682, -0.84432792]), 85: array([ 0.58778521, -0.80901689]), 86: array([ 0.63742404, -0.77051328]), 87: array([ 0.68454717, -0.72896867]), 88: array([ 0.72896867, -0.68454713]), 89: array([ 0.77051321, -0.63742395]), 90: array([ 0.80901698, -0.58778523]), 91: array([ 0.8443279 , -0.53582677]), 92: array([ 0.87630668, -0.48175367]), 93: array([ 0.9048271 , -0.42577932]), 94: array([ 0.92977651, -0.36812457]), 95: array([ 0.95105659, -0.30901703]), 96: array([ 0.96858306, -0.24868987]), 97: array([ 0.9822874 , -0.18738136]), 98: array([ 0.99211474, -0.12533326]), 99: array([ 0.99802665, -0.06279054])}
不同之处在于 alt_node_pos_dict
包含坐标数组而不是 node_pos_dict
中的元组。
为了在igraph
中获得相同的布局:
import igraph as ig
H = ig.Graph.from_networkx(G)
node_pos_list = [[node_pos_dict[node][0], -node_pos_dict[node][1]] for node in H.vs['_nx_name']]
ig.plot(H_ig, layout=node_pos_list, bbox=(800, 1000)).show()
这给出了下图:
我相信 networkx
的后端绘图库是 matplolib
,它使用大小和 dpi,而 python-igraph
使用像素。这就是为什么您需要设置 bbox=(800, 1000)
(或具有相同比例的其他值)以获得与问题中原始 figsize=(8, 10)
相同的纵横比。另一个需要注意的重要事项是创建时y坐标中的减号 node_pos_list
:
node_pos_list = [[node_pos_dict[node][0], -node_pos_dict[node][1]] for node in H.vs['_nx_name']]
如果减号是不,情节是反转的: