Добавьте легенду к сетевому графику, чтобы объяснить окраску узлов
У меня есть график графа networkx, в котором цвет ребер зависит от Весов, присвоенных соответствующим ребрам, используя следующий код (с a_netw
nx.График):
a_netw_edges = a_netw.edges()
a_netw_weights = [a_netw[source][dest]['weight'] for source, dest in a_netw_edges]
a_netw_colors = [plt.cm.Blues(weight*15) for weight in a_netw_weights]
nx.draw_networkx(a_netw, edges=a_netw_edges, width=1, edge_color=a_netw_colors)
К этому графику я хотел бы добавить легенду, которая делает связь между Весами и цветами явной; как в тепловой карте, которая использует pcolor
.
Хотя у меня есть примерное представление о том, как начать:
fig, axes = plt.subplots(nrows=2)
nx.draw_networkx(a_netw, edges=a_netw_edges, width=1, edge_color=a_netw_colors, ax=axes[0])
axes[0].get_xaxis().set_visible(False)
axes[0].get_yaxis().set_visible(False)
gradient = np.linspace(0, 1, 256)
gradient = np.vstack((gradient, gradient))
axes[1].imshow(gradient, aspect=3, cmap=plt.cm.Blues)
axes[1].get_yaxis().set_visible(False)
plt.tight_layout()
Я понятия не имею, как сделать следующие шаги:
- добавьте правильные галочки на соответствующей оси получить связь с грузами.
- нарисовать его вертикально, а не горизонтально.
2 ответа:
Я предлагаю вам использовать команду colorbar (), как показано ниже. Я привожу пример графика, смотрите, имеет ли он смысл?
import networkx as nx import matplotlib.pyplot as plt #generate a graph with weights a_netw=nx.Graph() a_netw.add_edge('a','b',weight=6) a_netw.add_edge('a','c',weight=2) a_netw.add_edge('c','d',weight=1) a_netw.add_edge('c','e',weight=7) a_netw.add_edge('c','f',weight=9) a_netw.add_edge('a','d',weight=3) #creating a color list for each edge based on weight a_netw_edges = a_netw.edges() a_netw_weights = [a_netw[source][dest]['weight'] for source, dest in a_netw_edges] #scale weights in range 0-1 before assigning color maxWeight=float(max(a_netw_weights)) a_netw_colors = [plt.cm.Blues(weight/maxWeight) for weight in a_netw_weights] #suppress plotting for the following dummy heatmap plt.ioff() #multiply all tuples in color list by scale factor colors_unscaled=[tuple(map(lambda x: maxWeight*x, y)) for y in a_netw_colors] #generate a 'dummy' heatmap using the edgeColors as substrate for colormap heatmap = plt.pcolor(colors_unscaled,cmap=plt.cm.Blues) #re-enable plotting plt.ion() fig,axes = plt.subplots() nx.draw_networkx(a_netw, edges=a_netw_edges, width=10, edge_color=a_netw_colors, ax=axes) axes.get_xaxis().set_visible(False) axes.get_yaxis().set_visible(False) #add colorbar cbar = plt.colorbar(heatmap) cbar.ax.set_ylabel('edge weight',labelpad=15,rotation=270)
Этот ответ позволяет избежать рисования фиктивной тепловой карты для цветовой панели. Вместо этого он передает возвращаемое значение
nx.draw_networkx_edges
вplt.colorbar
для создания цветовой панели.import networkx as nx import matplotlib import matplotlib.pyplot as plt from matplotlib import cm %matplotlib inline print('networkx version: {}'.format(nx.__version__)) print('matplotlib version: {}'.format(matplotlib.__version__)) # create a graph using code from @jlarsch's answer graph = nx.Graph() graph.add_edge('a','b',weight=6) graph.add_edge('a','c',weight=2) graph.add_edge('c','d',weight=1) graph.add_edge('c','e',weight=7) graph.add_edge('c','f',weight=9) graph.add_edge('a','d',weight=3) # compute spring layout positions for the graph pos = nx.spring_layout(graph, random_state=123) # nx.draw_networkx_edges returns an instance of # `matplotlib.collections.LineCollection`, which # could be passed to plt.colorbar to generate # color bar # the list comprehension to obtain edge weights is from @Aric's answer at # https://stackoverflow.com/a/25651827/4638182 mcl = nx.draw_networkx_edges( graph, pos, edge_cmap=cm.Blues, width=10, edge_color=[graph[u][v]['weight'] for u, v in graph.edges]) nx.draw_networkx_nodes(graph, pos) nx.draw_networkx_labels(graph, pos) plt.colorbar(mcl) plt.show()
Аналогичная процедура также работает для генерации цветовой панели для узлов.
import networkx as nx import matplotlib import matplotlib.pyplot as plt %matplotlib inline print("networkx version: {}".format(nx.__version__)) print("matplotlib version: {}".format(matplotlib.__version__)) # create a graph using code from @jlarsch's answer graph = nx.Graph() graph.add_edge('a','b',weight=6) graph.add_edge('a','c',weight=2) graph.add_edge('c','d',weight=1) graph.add_edge('c','e',weight=7) graph.add_edge('c','f',weight=9) graph.add_edge('a','d',weight=3) n_nodes = graph.number_of_nodes() pos = nx.spring_layout(graph, random_state=123) nx.draw_networkx_edges(graph, pos) nx.draw_networkx_labels(graph, pos) mcp = nx.draw_networkx_nodes(graph, pos, node_color=list(range(n_nodes)), cmap='Blues') plt.colorbar(mcp) plt.show()