python networkx - 如何绘制具有不同边宽的图形

python networkx - how to draw graph with varying edge width

基于this code snippet,我尝试创建一个具有不同边宽的图形。我有以下数据表示一个具有 20 个节点且只有上、下、左、右连接的 4x5 网格:

import numpy as np
weights = np.array([1.1817, 1.5336, 1.1325, 0.9202, 1.5881, 1.7083, 0.4012, 0.5972, 0.4937,
        1.1593, 1.2978, 0.0218, 0.1328, 1.9135, 1.2934, 0.2250, 0.5520, 1.3033,
        0.1133, 1.6854, 1.9010, 1.9293, 1.8916, 1.5798, 1.6423, 0.0683, 0.1891,
        0.6299, 0.2556, 0.7484, 1.8622])
edge_index = [[ 0,  1],
        [ 1,  2],
        [ 2,  3],
        [ 3,  4],
        [ 0,  5],
        [ 1,  6],
        [ 2,  7],
        [ 3,  8],
        [ 4,  9],
        [ 5,  6],
        [ 6,  7],
        [ 7,  8],
        [ 8,  9],
        [ 5, 10],
        [ 6, 11],
        [ 7, 12],
        [ 8, 13],
        [ 9, 14],
        [10, 11],
        [11, 12],
        [12, 13],
        [13, 14],
        [10, 15],
        [11, 16],
        [12, 17],
        [13, 18],
        [14, 19],
        [15, 16],
        [16, 17],
        [17, 18],
        [18, 19],
        [ 1,  0],
        [ 2,  1],
        [ 3,  2],
        [ 4,  3],
        [ 5,  0],
        [ 6,  1],
        [ 7,  2],
        [ 8,  3],
        [ 9,  4],
        [ 6,  5],
        [ 7,  6],
        [ 8,  7],
        [ 9,  8],
        [10,  5],
        [11,  6],
        [12,  7],
        [13,  8],
        [14,  9],
        [11, 10],
        [12, 11],
        [13, 12],
        [14, 13],
        [15, 10],
        [16, 11],
        [17, 12],
        [18, 13],
        [19, 14],
        [16, 15],
        [17, 16],
        [18, 17],
        [19, 18]]

权重的顺序与edge_index中提供的边相同。

我编写了以下代码来可视化节点及其连接:

from itertools import product
import networkx as nx
import matplotlib.pyplot as plt

G = nx.Graph()
dx = 4 # spacing
# create nodes
for nidx, (ridx, cidx) in enumerate(product(range(4), range(5))):
    #print(ridx,cidx)
    G.add_node(nidx, pos=(dx*cidx, -dx*ridx) )

# create 31 edges
for gidx, w in zip(edge_index, weights):
    #print(gidx, w)
    G.add_edge(*gidx, weight=w)

    
pos=nx.get_node_attributes(G,'pos')
labels = {k:f"{v:.3f}" for k, v in nx.get_edge_attributes(G, 'weight').items()}
nx.draw(G, pos)
nx.draw_networkx_labels(G, pos=pos, font_color='w')
nx.draw_networkx_edges(G, pos, width=10*weights)
nx.draw_networkx_edge_labels(G, pos, edge_labels=labels)
plt.show()

结果如下:

几乎是我想要的结果,但是我不知道为什么边(7,8)这么大,尽管权重相对较小(即与边(2,3)相比) .相反,边 (6,7) 比边 (5,6) 小得多。这是一个错误吗?还是我做错了什么?我仔细检查了权重数组的顺序,但没有发现错误。 感谢您的帮助!

不确定调用 nx.draw_networkx_edges() 时到底发生了什么,但是根据 docs 可以明确提供 edgelist 参数。因此以与 weights 相同的顺序提供 edgelist 解决了问题:


G = nx.Graph()
dx = 4 # spacing
# create nodes
for nidx, (ridx, cidx) in enumerate(product(range(4), range(5))):
    #print(ridx,cidx)
    G.add_node(nidx, pos=(dx*cidx, -dx*ridx) )

# create edges
nedges = 31
for gidx, w in zip(edge_index, weights):
    #print(gidx, w)
    G.add_edge(*gidx, weight=w)

    
pos=nx.get_node_attributes(G,'pos')
labels = {k:f"{v:.3f}" for k, v in nx.get_edge_attributes(G, 'weight').items()}
nx.draw(G, pos)
nx.draw_networkx_labels(G, pos=pos, font_color='w')
#######################################################################
nx.draw_networkx_edges(G, pos, edgelist=edge_index, width=10*weights) # <--- changed this line 
#######################################################################
nx.draw_networkx_edge_labels(G, pos, edge_labels=labels)
plt.show()

在您的代码中,您直接使用 nparray weights 将宽度分配给边缘。但是原始数组中的权重顺序不一定遵循图中边的顺序(以及它们的呈现方式)。

看看这个老问题。 Link

您可以简单地使用您为宽度生成的 labels 以保持一致