如何在networkx中使用matplotlib或graphviz绘制多重图

29 投票
5 回答
32728 浏览
提问于 2025-04-17 16:17

当我把一个多重图的numpy邻接矩阵传给networkx(使用from_numpy_matrix函数),然后试图用matplotlib绘制这个图时,它却忽略了那些多条边。

我该怎么做才能让它也绘制出多条边呢?

5 个回答

2

你可以使用 pyvis 这个工具包。
我只是把我在 Jupyter notebook 中实际项目里的代码复制粘贴过来。

from pyvis import network as pvnet

def plot_g_pyviz(G, name='out.html', height='300px', width='500px'):
    g = G.copy() # some attributes added to nodes
    net = pvnet.Network(notebook=True, directed=True, height=height, width=width)
    opts = '''
        var options = {
          "physics": {
            "forceAtlas2Based": {
              "gravitationalConstant": -100,
              "centralGravity": 0.11,
              "springLength": 100,
              "springConstant": 0.09,
              "avoidOverlap": 1
            },
            "minVelocity": 0.75,
            "solver": "forceAtlas2Based",
            "timestep": 0.22
          }
        }
    '''

    net.set_options(opts)
    # uncomment this to play with layout
    # net.show_buttons(filter_=['physics'])
    net.from_nx(g)
    return net.show(name)

G = nx.MultiDiGraph()
[G.add_node(n) for n in range(5)]
G.add_edge(0, 1, label=1)
G.add_edge(0, 1, label=11)
G.add_edge(0, 2, label=2)
G.add_edge(0, 3, label=3)
G.add_edge(3, 4, label=34)

plot_g_pyviz(G)

结果

17

你可以直接使用你计算出来的节点位置来使用matplotlib这个库。

G=nx.MultiGraph ([(1,2),(1,2),(1,2),(3,1),(3,2)])
pos = nx.random_layout(G)
nx.draw_networkx_nodes(G, pos, node_color = 'r', node_size = 100, alpha = 1)
ax = plt.gca()
for e in G.edges:
    ax.annotate("",
                xy=pos[e[0]], xycoords='data',
                xytext=pos[e[1]], textcoords='data',
                arrowprops=dict(arrowstyle="->", color="0.5",
                                shrinkA=5, shrinkB=5,
                                patchA=None, patchB=None,
                                connectionstyle="arc3,rad=rrr".replace('rrr',str(0.3*e[2])
                                ),
                                ),
                )
plt.axis('off')
plt.show()

在这里输入图片描述

24

Graphviz在绘制平行边方面表现得很好。你可以通过写一个dot文件来和NetworkX一起使用,然后用Graphviz处理这个文件(比如下面的neato布局)。除了NetworkX,你还需要安装pydot或pygraphviz。

In [1]: import networkx as nx

In [2]: G=nx.MultiGraph()

In [3]: G.add_edge(1,2)

In [4]: G.add_edge(1,2)

In [5]: nx.write_dot(G,'multi.dot')

In [6]: !neato -T png multi.dot > multi.png

在这里输入图片描述

在NetworkX 1.11及更新版本中,nx.write_dot这个功能不再有效,具体情况可以查看networkx的GitHub问题。解决这个问题的方法是通过以下方式调用write_dot

from networkx.drawing.nx_pydot import write_dot

或者

from networkx.drawing.nx_agraph import write_dot

撰写回答