Построение многодольного графика с использованием networkx

#python #matplotlib #machine-learning #data-science #networkx

Вопрос:

У меня есть такая структура графика

 graph = thisdict['data']['graph']

dict_edges = graph['edges']

edges = []

for edge in dict_edges:
    edges.append((edge['source']['node_id'], edge['target']['node_id']))

print('Source:ttt     Target:n')
    
for edge in edges:
    print(str(edge))

print('n')

dict_nodes = graph['nodes']

nodes = {}

for node in dict_nodes:
    nodes[node['id']] = node['name']

print('Node ID:tt    Node Name:n')

for key, value in nodes.items():
    print("'%s':'%s'" %(key, value))
 

Вывод:

 Source:                                Target:

('61697b94f74c92a808641ba3', '61697b95f74c92a808641ba4')
('61697b94f74c92a808641ba3', '61697b96f74c92a808641ba5')
('61697b95f74c92a808641ba4', '61697b96f74c92a808641ba6')
('61697b96f74c92a808641ba6', '61697b97f74c92a808641ba7')
('61697b96f74c92a808641ba5', '61697b97f74c92a808641ba7')
('61697b97f74c92a808641ba7', '61697b98f74c92a808641ba8')
('61697b98f74c92a808641ba8', '61697b98f74c92a808641ba9')


Node ID:            Node Name:

'61697b94f74c92a808641ba3':'S3 connector'
'61697b95f74c92a808641ba4':'loader 1'
'61697b96f74c92a808641ba5':'loader 2'   
'61697b96f74c92a808641ba6':'sampler 1'
'61697b97f74c92a808641ba7':'concator'
'61697b98f74c92a808641ba8':'sampler 2'
'61697b98f74c92a808641ba9':'splitter'
 

Я написал этот код, чтобы нарисовать график:

 nx_graph = nx.Graph()
plt.figure(figsize=(3,3))

for key, value in nodes.items():
    nx_graph.add_node(key, layer = nodes.values())
    #I need to put every node name in a single layer, So I should have 6 layers

for edge in edges:
    nx_graph.add_edge(*edge)

pos = nx.multipartite_layout(nx_graph, subset_key="layer")

nx.draw(nx_graph, pos, labels=nodes, with_labels=True)

plt.show()
 

В нем отображается сообщение об ошибке : Ошибка типа: неподдерживаемый тип(ы) операндов для -: ‘dict_values’ и ‘float’

Мне нужно поместить каждое имя узла в один слой, поэтому у меня должно быть 6 слоев. Сортировка слоев должна быть следующей:

 S3 connector --> loader 1 amp; loader 2
                 loader 1 will give sampler 1
                 loader 2 amp; sampler 1 will meet in concator
                 concator will give sampler 2
                 sampler 2 will give splitter
 

Ответ №1:

Ошибка возникает из-за того, что при добавлении узлов в for цикл вы передаете layer = nodes.values() вместо просто layer=value . Однако исправление этого все равно не даст вам нужного макета, потому что на самом деле вам нужно каким-то образом указать слои. Основываясь на вашем описании 6 слоев, я добавил их в качестве атрибутов из отдельного словаря.

Я сделал некоторые предположения о том, что вы на самом деле пытаетесь сделать, перейдя на a DiGraph и решив, где sampler 1 находится кивок.

Вот автономный блок кода и его выходные данные.

 import networkx as nx
import matplotlib.pyplot as plt


nodes = {'61697b94f74c92a808641ba3':'S3 connector',
'61697b95f74c92a808641ba4':'loader 1',
'61697b96f74c92a808641ba5':'loader 2',
'61697b96f74c92a808641ba6':'sampler 1',
'61697b97f74c92a808641ba7':'concator',
'61697b98f74c92a808641ba8':'sampler 2',
'61697b98f74c92a808641ba9':'splitter'}

edges = [('61697b94f74c92a808641ba3', '61697b95f74c92a808641ba4'),
('61697b94f74c92a808641ba3', '61697b96f74c92a808641ba5'),
('61697b95f74c92a808641ba4', '61697b96f74c92a808641ba6'),
('61697b96f74c92a808641ba6', '61697b97f74c92a808641ba7'),
('61697b96f74c92a808641ba5', '61697b97f74c92a808641ba7'),
('61697b97f74c92a808641ba7', '61697b98f74c92a808641ba8'),
('61697b98f74c92a808641ba8', '61697b98f74c92a808641ba9')]

layers = {'61697b94f74c92a808641ba3': 1,
'61697b95f74c92a808641ba4': 2,
'61697b96f74c92a808641ba5':2,
'61697b96f74c92a808641ba6':3,
'61697b97f74c92a808641ba7':4,
'61697b98f74c92a808641ba8':5,
'61697b98f74c92a808641ba9':6}

nx_graph = nx.DiGraph() # Made this a DiGraph (adds arrows to visual)
plt.figure(figsize=(8,8)) # Enlarged figure

for key, value in nodes.items():
    nx_graph.add_node(key, name=value, layer=layers[key])

for edge in edges:
    nx_graph.add_edge(*edge)

pos = nx.multipartite_layout(nx_graph, subset_key="layer")

nx.draw(nx_graph, pos=pos, labels=nodes, with_labels=True)

plt.show()
 

multipartite_layout

Комментарии:

1. Спасибо, сэр! @Фроднар