技术问询:如何实现边宽与权重成正比的双向有向图绘制
解决有向图边宽随权重变化的问题
嘿,我完全懂你的需求——你现在的有向图所有边宽度都一样,没法区分不同权重的边对吧?其实用NetworkX和Matplotlib很容易实现,咱们直接改代码就行:
核心思路
- 从图的边数据里提取每条边的权重值
- (可选)对权重做缩放,让宽度差异更直观(避免权重太小时边太细看不清)
- 将权重列表传给绘图函数的
width参数,实现每条边对应不同宽度
修改后的完整代码
from itertools import combinations import networkx as nx import matplotlib.pyplot as plt import numpy as np fig2 = plt.figure(figsize=(15.0, 10.0)) node_names = ['A', 'B', 'C', 'D'] G = nx.DiGraph() G.add_nodes_from(node_names) # 添加带随机权重的双向边 for var in combinations(node_names,2): G.add_edge(var[0], var[1], weight = np.random.uniform(0, 4)) G.add_edge(var[1], var[0], weight = np.random.uniform(0, 4)) pos = nx.spring_layout(G) # 节点位置 # 绘制节点 nx.draw_networkx_nodes(G, pos, node_size=2000) # 调大节点,和边的比例更协调 # 提取每条边的权重,做缩放让宽度差异更明显 edge_weights = [d['weight'] for (u, v, d) in G.edges(data=True)] scaled_weights = [w * 1.5 for w in edge_weights] # 缩放系数可自行调整 # 绘制边,用缩放后的权重作为宽度 nx.draw_networkx_edges(G, pos, edgelist=G.edges(), width=scaled_weights, arrowstyle='->', arrowsize=10) # 绘制节点标签和边权重标签(可选,方便查看对应关系) nx.draw_networkx_labels(G, pos, font_size=20, font_family='sans-serif') nx.draw_networkx_edge_labels(G, pos, edge_labels={(u,v): round(d['weight'],2) for u,v,d in G.edges(data=True)}, font_size=12) plt.axis('off') # 关闭坐标轴 plt.show()
关键改动说明
- 把节点大小从200改成了2000,和边的比例更协调,你可以根据需求自行调整
- 新增
edge_weights列表,专门提取每条边的权重值 - 加了
scaled_weights做缩放,比如权重0.5的边宽度是0.75,权重2的边宽度是3,视觉差异更明显 - 绘制边时把固定的
width=2换成了width=scaled_weights,让每条边宽度和权重直接挂钩 - 额外添加了边权重标签,方便你直观看到权重和宽度的对应关系,不需要的话可以删掉这一行
这样运行后,你就能看到像A→B和B→A这类双向边,会因为权重不同呈现出不同的宽度啦!
内容的提问来源于stack exchange,提问作者Thomuf
相关产品推荐
相关产品推荐

