You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于NetworkX绘制带权边图的技术问题(含Pandas权重矩阵)

嘿,我懂你现在的困扰——你想基于姓名节点的权重矩阵,让NetworkX画出的边粗细对应权重大小,但之前的代码没达到预期对吧?问题主要出在权重矩阵的格式转换和边属性的正确传递上,咱们一步步来修正:


问题根源

你之前的代码用了nx.from_pandas_edgelist(),但输入的bin_nom是宽格式的权重矩阵(姓名作为行/列),而这个函数需要的是长格式的边列表(每条边一行,包含源节点、目标节点、权重)。另外,edge_attr参数的用法也不对,你之前传了列名列表,应该指定权重列的名称。


修正步骤

1. 把权重矩阵转成边列表

首先需要将宽格式的权重矩阵转换为NetworkX能识别的长格式边列表,同时过滤掉无效边(比如权重为0、自环):

# 假设你的权重矩阵名为 name_weight_matrix,行和列都是姓名
edge_df = name_weight_matrix.stack().reset_index()
# 重命名列,明确源节点、目标节点、权重
edge_df.columns = ["source", "target", "weight"]
# 过滤掉自环和权重为0的边(按需调整)
edge_df = edge_df[(edge_df["source"] != edge_df["target"]) & (edge_df["weight"] > 0)]

2. 正确构建带权重的图

现在用转换后的边列表构建图,确保权重被正确作为边属性存入:

G = nx.from_pandas_edgelist(
    edge_df,
    source="source",
    target="target",
    edge_attr="weight",  # 明确指定权重列,让边携带权重信息
    create_using=nx.Graph()
)

3. 按权重绘制边

绘制时,从图的边属性中提取权重,缩放后作为边的宽度参数,这样就能实现“权重越大边越粗”的效果:

import matplotlib.pyplot as plt
import networkx as nx

plt.figure(figsize=(35, 35))

# 提取所有边的权重,并缩放(这里乘以5是为了让粗细差异更明显,可按需调整)
edge_weights = [G[u][v]["weight"] for u, v in G.edges()]
scaled_widths = [w * 5 for w in edge_weights]

# 调整绘图选项,把width设为缩放后的权重
options = {
    'edge_color': '#eebcbc',
    'width': scaled_widths,
    'with_labels': True,
    'font_weight': 'regular',
}

# 节点大小逻辑和你之前保持一致
node_degrees = dict(G.degree)
layout_pos = nx.spring_layout(G, k=0.85, iterations=100)

nx.draw(
    G,
    pos=layout_pos,
    node_color='blue',
    nodelist=node_degrees.keys(),
    node_size=[v * 100 for v in node_degrees.values()],
    **options
)

# 设置节点边框颜色
ax = plt.gca()
ax.collections[0].set_edgecolor("#000007")

plt.show()

额外小技巧

  • 如果权重值范围过大(比如从1到100),可以用标准化处理避免边太粗或太细:
    from sklearn.preprocessing import MinMaxScaler
    scaler = MinMaxScaler(feature_range=(1, 10))  # 把权重缩放到1-10的范围作为边宽
    scaled_widths = scaler.fit_transform([[w] for w in edge_weights]).flatten()
    
  • 如果想给边添加权重标签,可以用nx.draw_networkx_edge_labels():
    nx.draw_networkx_edge_labels(G, pos=layout_pos, edge_labels={(u, v): G[u][v]["weight"] for u, v in G.edges()})
    

内容的提问来源于stack exchange,提问作者user9176398

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 07:33:56