У меня проблема с визуализацией, связанная с графиком. У меня есть N
узлы, которые принадлежат, скажем, некоторым M
сетям. Узлы могут иметь межсетевые ребра (в пределах одной сети) и внутрисетевые ребра (ребра от узла в одной сети к другой).
Когда я визуализирую график в networkx
, я ищу способ размещения / кластеризации сетей вместе, чтобы я мог легко различать меж / внутри сетевые соединения. Таким образом, в идеале все синие узлы должны быть объединены в сеть (в произвольном порядке). Аналогично для оранжевых или зеленых.
Кстати, я не пытаюсь найти концентраторы / кластеры, я знаю , какие узлы в каких сетях, я просто пытаюсь найти способ визуализировать его более точно. Есть ли простой способ сделать это? Что-то вроде расширенной компоновки пружины, где я могу указать, что некоторые узлы должны отображаться вместе независимо от веса ребер / силы пружины?
Минимальный рабочий генератор
import string, random
import networkx as nx
import matplotlib.pyplot as plt
from scipy.sparse import random as sparse_random
# Random string generator
def rand_string(size=6, chars=string.ascii_uppercase):
return ''.join(random.choice(chars) for _ in range(size))
# Set up a nodes and networks randomly
nodes = [rand_string() for _ in range(30)]
networks = [rand_string() for _ in range(5)]
networks_list = networks*6
random.shuffle(networks_list)
# Define what nodes belong to what network and what their color should be
node_network_map = dict(zip(nodes, networks_list))
colors = ['green', 'royalblue', 'red', 'orange', 'cyan']
color_map = dict(zip(networks, colors))
graph = nx.Graph()
graph.add_nodes_from(nodes)
nodes_by_color = {val: [node for node in graph if color_map[node_network_map[node]] == val]
for val in colors}
# Take random sparse matrix as adjacency matrix
mat = sparse_random(30, 30, density=0.3).todense()
for row, row_val in enumerate(nodes):
for col, col_val in enumerate(nodes):
if col > row and mat[row, col] != 0.0: # Stick to upper half triangle, mat is not symmetric
graph.add_edge(row_val, col_val, weight=mat[row, col])
# Choose a layout to visualize graph
pos = nx.spring_layout(graph)
edges = graph.edges()
# Get the edge weights and normalize them
weights = [abs(graph[u][v]['weight']) for u, v in edges]
weights_n = [5*float(i)/max(weights) for i in weights] # Change 5 to control thickness
# First draw the nodes
plt.figure()
for color, node_names in nodes_by_color.items():
nx.draw_networkx_nodes(graph, pos=pos, nodelist=node_names, node_color=color)
# Then draw edges with thickness defined by weights_n
nx.draw_networkx_edges(graph, pos=pos, width=weights_n)
nx.draw_networkx_labels(graph, pos=pos)
plt.show()