Networkx 两条边而不是一条边来显示一个环

Networkx Two Edges Instead of One to Show a Loop

在下面代码生成的图表中, B->DD->B

我希望这个“循环”由两条线表示(其中一条线可能需要弯曲),而不是两端带有箭头的单线。请问我该如何实现?

import networkx as nx
import matplotlib.pyplot as plt

G = nx.DiGraph()
G.add_edges_from(
    [('A', 'B'), ('A', 'C'), ('D', 'B'), ('E', 'C'), ('E', 'F'),
     ('B', 'H'), ('B', 'G'), ('B', 'D'), ('C', 'G')])

pos = nx.spring_layout(G)
nx.draw_networkx_nodes(G, pos, node_size = 500)
nx.draw_networkx_labels(G, pos)
nx.draw_networkx_edges(G, pos, arrows=True)
plt.show()

您可以使用 PyGraphviz

>>> A = nx.nx_agraph.to_agraph(G)
>>> A.draw("G.ps",prog='circo')

你可以直接在nx.draw_edges中指定连接样式来完成,尽管边缘不会在一条直线上:

import networkx as nx
import matplotlib.pyplot as plt

plt.figure(1,figsize=(12,12)) 

G = nx.MultiDiGraph()
G.add_edges_from(
    [('A', 'B'), ('A', 'C'), ('D', 'B'), ('E', 'C'), ('E', 'F'),
     ('B', 'H'), ('B', 'G'), ('B', 'D'), ('C', 'G')])

pos = nx.spring_layout(G)
nx.draw_networkx_nodes(G, pos, node_size = 500)
nx.draw_networkx_labels(G, pos)
nx.draw_networkx_edges(G, pos, connectionstyle='arc3, rad = 0.1', width = 2, arrows=True)
plt.show()

参考资料:

如果您不介意使用替代库 igraph 可以自动完成:

import igraph as ig
g = ig.Graph(directed=True)
nodes = list('ABCDEFGH')
edges = [('A', 'B'), ('A', 'C'), ('D', 'B'), ('E', 'C'), ('E', 'F'),
     ('B', 'H'), ('B', 'G'), ('B', 'D'), ('C', 'G')]

g.add_vertices(g_nodes)
g.add_edges(g_edges)

ig.plot(g,  
        bbox = (400, 200), # bounding box of plot
        vertex_color='lightblue',
        vertex_label=nodes,
        vertex_frame_width=3)

但有些差异可能很重要:

  • 只有从0开始的连续整数才能作为顶点索引,所以需要手动添加映射:

     idx = dict(zip(nodes, range(len(nodes))))
     g_nodes = [idx[A] for A in nodes]
     g_edges = [(idx[A], idx[B]) for A, B in edges]
    
  • 它使用非常有限的内表面而不是 matplotlib。请注意,您需要自己定义图的大小。

  • 需要安装igraphpycairo