Как в графе у обратных ребер задать две стрелки, разных цветов? 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 шт):

Автор решения: AnnaBazueva

Насколько я поняла:

  • 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 изначально закладывали синий цвет,
далее по коду пытаясь перенастроить.

Лучше сразу для рёбер указать желаемый цвет.

→ Ссылка