如何在NetworkX中绘制平行边并添加权重标签(Jupyter Notebook环境)
在Jupyter Notebook中用NetworkX绘制带权重标签的平行边
嘿,这问题我之前也碰到过!要实现带权重标签的有向平行边,关键在于选对图的类型,再调整几个绘图参数就行,我给你一步步拆解:
核心要点
首先,普通的DiGraph不支持同一对节点之间的多条有向边,所以必须用MultiDiGraph——这是支持平行有向边的专用图类型。然后绘图时要让平行边错开显示,同时正确渲染权重标签。
完整代码示例
直接上可运行的代码,每一步都有注释:
import networkx as nx import matplotlib.pyplot as plt # 1. 创建支持有向平行边的图结构 G = nx.MultiDiGraph() # 2. 添加带权重的平行边 # 1→2的两条平行边,权重不同 G.add_edge(1, 2, weight=3.5) G.add_edge(1, 2, weight=1.2) # 2→1的一条边 G.add_edge(2, 1, weight=2.8) # 3. 固定布局(seed参数保证每次绘图位置一致,方便调试) pos = nx.spring_layout(G, seed=42) # 4. 绘制节点 nx.draw_networkx_nodes(G, pos, node_size=700, node_color="#a8d1ff") # 5. 绘制节点标签 nx.draw_networkx_labels(G, pos, font_size=14, font_weight="bold") # 6. 绘制边:用connectionstyle让平行边以弧形错开,避免重叠 nx.draw_networkx_edges( G, pos, edgelist=G.edges(), connectionstyle="arc3,rad=0.2", # rad值越大,弧度越明显 arrowstyle="->", arrowsize=20, edge_color="#333333" ) # 7. 准备并绘制边的权重标签 # MultiDiGraph的边是(u, v, key)三元组,所以标签字典要包含key edge_labels = {(u, v, k): f"{d['weight']}" for u, v, k, d in G.edges(data=True)} nx.draw_networkx_edge_labels( G, pos, edge_labels=edge_labels, font_size=12, label_pos=0.3, # 标签位置:0是起点,1是终点,0.3靠近起点,避免重叠 bbox=dict(facecolor="white", edgecolor="none", pad=1) # 给标签加白背景,更清晰 ) # 8. 隐藏坐标轴,显示图形 plt.axis("off") plt.show()
关键细节解释
- MultiDiGraph的必要性:如果用普通
DiGraph,重复添加1→2的边会覆盖之前的,而MultiDiGraph会保留所有平行边,用唯一的key来区分每条边。 - connectionstyle参数:这个参数是让平行边以弧形展示的核心,
arc3,rad=0.2表示用三阶贝塞尔曲线,弧度为0.2,你可以根据图的大小调整rad值,让边的错开效果更舒服。 - 边标签的处理:因为
MultiDiGraph的边是三元组(u, v, key),所以构建标签字典时必须包含key,否则同方向的平行边标签会重复显示在同一条边上。 - label_pos参数:调整标签在边的位置,比如0.3靠近起点,0.7靠近终点,这样同方向的平行边标签不会挤在一起。
在Jupyter Notebook里直接运行这段代码,就能看到带权重标签的平行边图啦!
内容的提问来源于stack exchange,提问作者qfd
相关产品推荐
相关产品推荐

