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

Networkx中DiGraph的边标注优化及边重叠避免问题求助

解决Networkx有向图可视化的三个问题

现有代码

import networkx as nx
import matplotlib.pyplot as plt
import pandas as pd

# 假设data是已加载的DataFrame
G = nx.from_pandas_edgelist(data, source='grad',
                            target='to', edge_attr='count',
                            create_using=nx.DiGraph())
weight = nx.get_edge_attributes(G, 'count')
pos = nx.shell_layout(G, scale=1)
nx.draw_networkx_nodes(G, pos, node_size=300, node_color='lightblue')
nx.draw_networkx_labels(G, pos=pos, font_color='red')
nx.draw_networkx_edges(G, pos=pos, edgelist=G.edges(), edge_color='black',
                       connectionstyle='arc3, rad = 0.1')
nx.draw_networkx_edge_labels(G, pos=pos, edge_labels=weight)
plt.show()

当前可视化存在的问题

  • 边标注未完全显示,部分边没有标注
  • 弧形边的标注位于弧线上,显示效果不佳
  • 非双向边无需使用弧形,整体显示不够整洁

附数据(前50行,字典格式)

data_dict = {
    'grad': {0: 'CUHK', 1: 'CUHK', 2: 'CUHK', 3: 'CUHK', 4: 'CUHK', 5: 'CUHK', 6: 'CUHK', 7: 'CUHK', 8: 'CityU', 9: 'CityU', 10: 'CityU', 11: 'CityU', 12: 'CityU', 13: 'CityU', 14: 'CityU', 15: 'HKBU', 16: 'HKU', 17: 'HKU', 18: 'HKU', 19: 'HKU', 20: 'HKU', 21: 'HKU', 22: 'HKU', 23: 'HKUST', 24: 'HKUST', 25: 'HKUST', 26: 'HKUST', 27: 'HKUST', 28: 'HKUST', 29: 'HKUST', 30: 'HKUST', 31: 'Low Frequency', 32: 'Low Frequency', 33: 'Low Frequency', 34: 'Low Frequency', 35: 'Low Frequency', 36: 'Low Frequency', 37: 'Low Frequency', 38: 'Low Frequency', 39: 'PolyU', 40: 'PolyU', 41: 'PolyU', 42: 'PolyU', 43: 'PolyU', 44: 'PolyU'},
    'to': {0: 'CUHK', 1: 'CityU', 2: 'EduHK', 3: 'HKBU', 4: 'HKU', 5: 'HKUST', 6: 'LingU', 7: 'PolyU', 8: 'CityU', 9: 'EduHK', 10: 'HKBU', 11: 'HKU', 12: 'HKUST', 13: 'LingU', 14: 'PolyU', 15: 'HKBU', 16: 'CUHK', 17: 'CityU', 18: 'EduHK', 19: 'HKBU', 20: 'HKU', 21: 'HKUST', 22: 'PolyU', 23: 'CUHK', 24: 'CityU', 25: 'EduHK', 26: 'HKBU', 27: 'HKU', 28: 'HKUST', 29: 'LingU', 30: 'PolyU', 31: 'CUHK', 32: 'CityU', 33: 'EduHK', 34: 'HKBU', 35: 'HKU', 36: 'HKUST', 37: 'LingU', 38: 'PolyU', 39: 'CityU', 40: 'EduHK', 41: 'HKBU', 42: 'HKU', 43: 'LingU', 44: 'PolyU'},
    'count': {0: 13, 1: 6, 2: 3, 3: 6, 4: 5, 5: 3, 6: 2, 7: 6, 8: 4, 9: 1, 10: 5, 11: 2, 12: 1, 13: 2, 14: 7, 15: 2, 16: 2, 17: 4, 18: 3, 19: 1, 20: 17, 21: 3, 22: 9, 23: 4, 24: 2, 25: 2, 26: 4, 27: 2, 28: 4, 29: 4, 30: 6, 31: 76, 32: 73, 33: 1, 34: 16, 35: 57, 36: 46, 37: 3, 38: 69, 39: 1, 40: 2, 41: 3, 42: 1, 43: 1, 44: 23}
}
# 转换为DataFrame
data = pd.DataFrame(data_dict)

针对性解决方案

1. 修复边标注缺失问题

边标注缺失多因标签重叠、字体过大或被节点遮挡,调整以下参数即可解决:

  • 缩小字体:font_size=8
  • 偏移标签位置:label_pos=0.3(让标签靠近起点,避开节点遮挡)
  • 添加背景框:bbox=dict(facecolor='white', edgecolor='none', alpha=0.7),避免标签被边或其他元素覆盖

2. 优化弧形边的标注显示

弧形边的标签不要放在弧线上,改为水平显示并偏移位置:

  • 关闭标签旋转:rotate=False
  • 调整标签位置到弧线外侧:label_pos=0.2或0.8

3. 区分双向边与单向边的显示

先筛选出双向边(同时存在(u,v)和(v,u)的边),单向边用直线绘制,双向边用正反弧形区分:

# 筛选双向/单向边
bidirectional_edges = set()
unidirectional_edges = set()
seen = set()

for u, v in G.edges():
    if (v, u) in G.edges() and (u, v) not in seen and (v, u) not in seen:
        bidirectional_edges.add((u, v))
        bidirectional_edges.add((v, u))
        seen.add((u, v))
        seen.add((v, u))
    elif (u, v) not in seen:
        unidirectional_edges.add((u, v))
        seen.add((u, v))

修改后的完整代码

import networkx as nx
import matplotlib.pyplot as plt
import pandas as pd

# 加载数据
data_dict = {
    'grad': {0: 'CUHK', 1: 'CUHK', 2: 'CUHK', 3: 'CUHK', 4: 'CUHK', 5: 'CUHK', 6: 'CUHK', 7: 'CUHK', 8: 'CityU', 9: 'CityU', 10: 'CityU', 11: 'CityU', 12: 'CityU', 13: 'CityU', 14: 'CityU', 15: 'HKBU', 16: 'HKU', 17: 'HKU', 18: 'HKU', 19: 'HKU', 20: 'HKU', 21: 'HKU', 22: 'HKU', 23: 'HKUST', 24: 'HKUST', 25: 'HKUST', 26: 'HKUST', 27: 'HKUST', 28: 'HKUST', 29: 'HKUST', 30: 'HKUST', 31: 'Low Frequency', 32: 'Low Frequency', 33: 'Low Frequency', 34: 'Low Frequency', 35: 'Low Frequency', 36: 'Low Frequency', 37: 'Low Frequency', 38: 'Low Frequency', 39: 'PolyU', 40: 'PolyU', 41: 'PolyU', 42: 'PolyU', 43: 'PolyU', 44: 'PolyU'},
    'to': {0: 'CUHK', 1: 'CityU', 2: 'EduHK', 3: 'HKBU', 4: 'HKU', 5: 'HKUST', 6: 'LingU', 7: 'PolyU', 8: 'CityU', 9: 'EduHK', 10: 'HKBU', 11: 'HKU', 12: 'HKUST', 13: 'LingU', 14: 'PolyU', 15: 'HKBU', 16: 'CUHK', 17: 'CityU', 18: 'EduHK', 19: 'HKBU', 20: 'HKU', 21: 'HKUST', 22: 'PolyU', 23: 'CUHK', 24: 'CityU', 25: 'EduHK', 26: 'HKBU', 27: 'HKU', 28: 'HKUST', 29: 'LingU', 30: 'PolyU', 31: 'CUHK', 32: 'CityU', 33: 'EduHK', 34: 'HKBU', 35: 'HKU', 36: 'HKUST', 37: 'LingU', 38: 'PolyU', 39: 'CityU', 40: 'EduHK', 41: 'HKBU', 42: 'HKU', 43: 'LingU', 44: 'PolyU'},
    'count': {0: 13, 1: 6, 2: 3, 3: 6, 4: 5, 5: 3, 6: 2, 7: 6, 8: 4, 9: 1, 10: 5, 11: 2, 12: 1, 13: 2, 14: 7, 15: 2, 16: 2, 17: 4, 18: 3, 19: 1, 20: 17, 21: 3, 22: 9, 23: 4, 24: 2, 25: 2, 26: 4, 27: 2, 28: 4, 29: 4, 30: 6, 31: 76, 32: 73, 33: 1, 34: 16, 35: 57, 36: 46, 37: 3, 38: 69, 39: 1, 40: 2, 41: 3, 42: 1, 43: 1, 44: 23}
}
data = pd.DataFrame(data_dict)

# 创建图
G = nx.from_pandas_edgelist(data, source='grad',
                            target='to', edge_attr='count',
                            create_using=nx.DiGraph())
weight = nx.get_edge_attributes(G, 'count')
pos = nx.shell_layout(G, scale=1)

# 筛选双向/单向边
bidirectional_edges = set()
unidirectional_edges = set()
seen = set()

for u, v in G.edges():
    if (v, u) in G.edges() and (u, v) not in seen and (v, u) not in seen:
        bidirectional_edges.add((u, v))
        bidirectional_edges.add((v, u))
        seen.add((u, v))
        seen.add((v, u))
    elif (u, v) not in seen:
        unidirectional_edges.add((u, v))
        seen.add((u, v))

# 绘制节点和标签
nx.draw_networkx_nodes(G, pos, node_size=300, node_color='lightblue')
nx.draw_networkx_labels(G, pos=pos, font_color='red', font_size=9)

# 绘制单向边(直线)
nx.draw_networkx_edges(G, pos=pos, edgelist=unidirectional_edges, 
                       edge_color='black', arrowstyle='->')

# 绘制双向边(不同方向弧形)
seen_edges = set(bidirectional_edges)
for u, v in bidirectional_edges:
    if (u, v) not in seen_edges:
        continue
    # 正向边用右弧形,反向边用左弧形
    nx.draw_networkx_edges(G, pos=pos, edgelist=[(u, v)], 
                           edge_color='black', arrowstyle='->',
                           connectionstyle=f'arc3, rad={0.1 if u < v else -0.1}')
    seen_edges.remove((u, v))
    seen_edges.remove((v, u))

# 绘制边标签,优化显示
nx.draw_networkx_edge_labels(G, pos=pos, edge_labels=weight,
                             font_size=8, label_pos=0.3, rotate=False,
                             bbox=dict(facecolor='white', edgecolor='none', alpha=0.7))

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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 06:46:06