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
以保持一致
基于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
以保持一致