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

如何在NetworkX中根据边的出现频次设置边的厚度

解决NetworkX边厚度随出现频次调整的问题

问题背景

现有如下Pandas数据框:

student_id  0   1   2   3   4   5   6   7   8   9  10  11  12
0   131X1319  1  14   6  16   1  10   8  15  15  17  15  18  16
1   13212YX3  1   1   4   8  11   9  14   7   0   3   0  17  13
2   13216131  1   1  13   9  15  17   0   9   3  15  11   8  10
3   132921W6  1  14  10   4  18   7   8  15  15  17  15  18  16

需要用NetworkX构建有向图,要求边的厚度随该边在数据框中的出现频次增加(比如路径15->15->17->15->18->16出现两次,对应边厚度设为2)。当前已实现基础图绘制,但无法设置边厚度,代码如下:

columns=list(pattern_df.columns.values)
pattern_g = nx.empty_graph(0, nx.DiGraph())
for i in range(len(columns)-1):
     pattern_g.add_edges_from(zip(pattern_df[columns[i]], 
pattern_df[columns[i+1]]))
sum_val=pattern_df.sum(numeric_only=True, axis=0)
values = [sum_val.get(node, 0.25) for node in pattern_g.nodes()]
nx.draw(pattern_g, with_labels=True, font_color='black')
plt.show()

解决方案

核心逻辑是先统计每条边的出现频次,再将频次映射为边的宽度参数传入绘图函数。

1. 统计边的出现频次

遍历数据框的每一行,提取连续列的节点对(即边),用collections.Counter统计每条边的出现次数:

from collections import Counter

edge_counts = Counter()
# 遍历每一行,提取连续节点对
for idx, row in pattern_df.iterrows():
    # 跳过student_id列,提取数值节点序列
    nodes = row.iloc[1:].tolist()
    # 生成连续边对
    edges = list(zip(nodes[:-1], nodes[1:]))
    edge_counts.update(edges)

2. 构建带权重的有向图

基于统计结果构建图,给每条边添加weight属性存储频次:

pattern_g = nx.DiGraph()
for edge, count in edge_counts.items():
    pattern_g.add_edge(edge[0], edge[1], weight=count)

3. 绘制带厚度的图

使用nx.draw_networkx_edges单独绘制边,通过width参数传入边的频次(可乘以系数调整厚度比例),同时保留节点和标签的绘制逻辑:

# 节点大小沿用原有逻辑,乘以系数放大显示
sum_val = pattern_df.sum(numeric_only=True, axis=0)
node_sizes = [sum_val.get(node, 0.25)*100 for node in pattern_g.nodes()]

# 固定布局让图结构稳定
pos = nx.spring_layout(pattern_g, seed=42)

# 绘制节点
nx.draw_networkx_nodes(pattern_g, pos, node_size=node_sizes, node_color='lightblue')
# 绘制节点标签
nx.draw_networkx_labels(pattern_g, pos, font_color='black', font_weight='bold')
# 绘制边,宽度设为频次的0.5倍(可按需调整)
edge_widths = [pattern_g[u][v]['weight'] * 0.5 for u, v in pattern_g.edges()]
nx.draw_networkx_edges(pattern_g, pos, width=edge_widths, arrowstyle='->', arrowsize=15)

plt.axis('off')
plt.show()

完整整合代码

from collections import Counter
import pandas as pd
import networkx as nx
import matplotlib.pyplot as plt

# 构造示例数据框
data = {
    'student_id': ['131X1319', '13212YX3', '13216131', '132921W6'],
    0: [1,1,1,1],
    1: [14,1,1,14],
    2: [6,4,13,10],
    3: [16,8,9,4],
    4: [1,11,15,18],
    5: [10,9,17,7],
    6: [8,14,0,8],
    7: [15,7,9,15],
    8: [15,0,3,15],
    9: [17,3,15,17],
    10: [15,0,11,15],
    11: [18,17,8,18],
    12: [16,13,10,16]
}
pattern_df = pd.DataFrame(data)

# 统计边频次
edge_counts = Counter()
for idx, row in pattern_df.iterrows():
    nodes = row.iloc[1:].tolist()
    edges = list(zip(nodes[:-1], nodes[1:]))
    edge_counts.update(edges)

# 构建带权重的图
pattern_g = nx.DiGraph()
for edge, count in edge_counts.items():
    pattern_g.add_edge(edge[0], edge[1], weight=count)

# 计算节点大小
sum_val = pattern_df.sum(numeric_only=True, axis=0)
node_sizes = [sum_val.get(node, 0.25)*100 for node in pattern_g.nodes()]

# 绘图
pos = nx.spring_layout(pattern_g, seed=42)
nx.draw_networkx_nodes(pattern_g, pos, node_size=node_sizes, node_color='lightblue')
nx.draw_networkx_labels(pattern_g, pos, font_color='black', font_weight='bold')
edge_widths = [pattern_g[u][v]['weight'] * 0.5 for u, v in pattern_g.edges()]
nx.draw_networkx_edges(pattern_g, pos, width=edge_widths, arrowstyle='->', arrowsize=15)

plt.axis('off')
plt.show()

内容的提问来源于stack exchange,提问作者black street boy

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 05:01:02