Как в графе у обратных ребер задать две стрелки, разных цветов? Networkx, Python
Пыталась сделать так, чтобы обратные ребра были разными цветами. Но не смогла =( Сейчас если посмотреть на граф, то ребра A-L и L-A одного цвета:
Как можно сделать чтобы обратные ребра в одном направлении были, например, синими, а в обратном направлении оранжевыми? А толщина ребер чтобы так же зависела от веса ребра. Прямые ребра, которые тоже отличаются цветом и линией, хочется оставить.
Использовала networkx, matplotlib.pyplot, matplotlib.patches, python Мой код:
#Визуальное разделение прямых и обратных ребер
connectionstyle = []
edge_colors=[]
for v,u in G.edges():
if G1.has_edge(v,u):
connectionstyle.append('arc3, rad=0')
edge_colors.append('#000000')
else:
connectionstyle.append('arc3, rad=0.4')
edge_colors.append('#4682B4')
#Выводим основной график
Arrow = mpl.ArrowStyle.CurveB(head_length=0.3, head_width=.4) #стиль стрелки
pos = nx.shell_layout(G) #расположение нодов
fig, ax = plt.subplots(figsize=(8,7))
edges = nx.draw_networkx_edges(G, pos, node_size=200, arrowsize=15, arrowstyle=Arrow, width=width)
#Стиль отображения узлов
for p in pos:
if pos[p][0] < 0:
pos[p][0] -= 0.02
plt.text(pos[p][0],pos[p][1],s=p, bbox=dict(facecolor='#87CEFA', edgecolor='None', alpha=0.5),
horizontalalignment='right', fontsize=11)
else:
pos[p][0] += 0.02
plt.text(pos[p][0],pos[p][1],s=p, bbox=dict(facecolor='#87CEFA', edgecolor='None', alpha=0.5),
horizontalalignment='left', fontsize=11)
#Отображение весов ребер
edge_labels = nx.get_edge_attributes(G2,'weight')
#Задаем параметры отображения линий, т.е. прямых и обратных ребер:
M = G.number_of_edges()
for i in range(M):
edges[i].set_connectionstyle(connectionstyle[i])
edges[i].set_color(edge_colors[i])
edges[i].set_alpha(0.7)
#Выводим текстом инф о прямых ребрах:
xmin, xmax = ax.get_xlim()
ymin, ymax = ax.get_ylim()
s = ' \n'.join([v+'-->'+u+' '+str(w['weight']) for v,u,w in G1.edges.data()])
plt.text(1.4,-0.2, s='Прямые ребра \n\n'+s,
bbox=dict(facecolor='#87CEFA', edgecolor='None', alpha=0.8),
fontsize=11, horizontalalignment='center', color='white')
plt.tight_layout()
plt.axis('off')
plt.savefig('net2.svg')
plt.show()
Ответы (1 шт):
Насколько я поняла:
G
- это рёбра прямого и обратного направления;G1
- это незадействованные рёбра;G2
- что-то там ещё.
Т.е. G
возможно инициализировался с такими аргументами:
G = nx.DiGraph()
G.add_edges_from([('A', 'L'), ('L', 'A'),
('A', 'C'),
('A', 'F'),
('A', 'I'), ('I', 'A'),
('C', 'L'),
('I', 'C'), ('C', 'I'),
('I', 'J'),
('J', 'K')
# какие-то ещё...
]
)
Самым очевидным решением на мой взгляд:
connectionstyle = []
edge_colors = []
check_reverse = []
for v, u in G.edges():
if G1.has_edge(v, u):
connectionstyle.append('arc3, rad=0')
edge_colors.append('#000000')
elif (v, u) not in check_reverse:
connectionstyle.append('arc3, rad=0.4')
edge_colors.append('#4682B4')
if G.has_edge(u, v):
check_reverse.append((u, v))
elif (v, u) in check_reverse:
connectionstyle.append('arc3, rad=0.4')
edge_colors.append('#FFA500')
else:
del check_reverse
# Далее подстраивайте свой код...
Суть в том, что в этой части вашего кода вы создавали два списка одинаковой длины.
И всем рёбрам из G
изначально закладывали синий цвет,
далее по коду пытаясь перенастроить.
Лучше сразу для рёбер указать желаемый цвет.