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

如何移除NetworkX无向图可视化中的self-loop edges?

移除NetworkX无向图绘图中的自环边

我原本以为这是个显而易见的操作,但始终没能找到解决办法。我尝试将所有self-loop edges的权重设为0,但似乎边的顺序未被保留,导致问题仍存在。

d = {'PRJNA551026-COASSEMBLY__METABAT2__P.1__bin.24': {'PRJNA551026-COASSEMBLY__METABAT2__P.1__bin.24': {'weight': 100.0}, 'SRR9668968__METABAT2__P.1__bin.4': {'weight': 99.5976}}, 'SRR9668968__METABAT2__P.1__bin.4': {'PRJNA551026-COASSEMBLY__METABAT2__P.1__bin.24': {'weight': 99.5976}, 'SRR9668968__METABAT2__P.1__bin.4': {'weight': 100.0}}, 'SRR9668973__MAXBIN2-107__P.1__bin.001': {'SRR9668973__MAXBIN2-107__P.1__bin.001': {'weight': 100.0}, 'PRJNA551026-COASSEMBLY__METABAT2__P.1__bin.27': {'weight': 99.1217}, 'SRR9668959__CONCOCT__P.1__18': {'weight': 99.0443}}, 'PRJNA551026-COASSEMBLY__METABAT2__P.1__bin.27': {'SRR9668973__MAXBIN2-107__P.1__bin.001': {'weight': 99.1217}, 'SRR9668959__CONCOCT__P.1__18': {'weight': 99.9955}, 'PRJNA551026-COASSEMBLY__METABAT2__P.1__bin.27': {'weight': 100.0}}, 'SRR9668959__CONCOCT__P.1__18': {'SRR9668973__MAXBIN2-107__P.1__bin.001': {'weight': 99.0443}, 'SRR9668959__CONCOCT__P.1__18': {'weight': 100.0}, 'PRJNA551026-COASSEMBLY__METABAT2__P.1__bin.27': {'weight': 99.9955}}, 'SRR9668957__CONCOCT__P.1__5': {'SRR9668957__CONCOCT__P.1__5': {'weight': 100.0}}, 'PRJNA551026-COASSEMBLY__METABAT2__P.1__bin.9': {'PRJNA551026-COASSEMBLY__METABAT2__P.1__bin.9': {'weight': 100.0}, 'SRR9668968__CONCOCT__P.1__11': {'weight': 99.9584}}, 'SRR9668968__CONCOCT__P.1__11': {'PRJNA551026-COASSEMBLY__METABAT2__P.1__bin.9': {'weight': 99.9584}, 'SRR9668968__CONCOCT__P.1__11': {'weight': 100.0}}, 'SRR9668967__MAXBIN2-107__P.1__bin.001': {'SRR9668967__MAXBIN2-107__P.1__bin.001': {'weight': 100.0}, 'PRJNA551026-COASSEMBLY__METABAT2__P.2__bin.3': {'weight': 99.9547}}, 'PRJNA551026-COASSEMBLY__METABAT2__P.2__bin.3': {'SRR9668967__MAXBIN2-107__P.1__bin.001': {'weight': 99.9547}, 'PRJNA551026-COASSEMBLY__METABAT2__P.2__bin.3': {'weight': 100.0}}, 'SRR9668973__CONCOCT__P.1__16_sub': {'SRR9668973__CONCOCT__P.1__16_sub': {'weight': 100.0}}, 'SRR9668960__CONCOCT__P.1__21': {'SRR9668960__CONCOCT__P.1__21': {'weight': 100.0}, 'SRR9668957__MAXBIN2-107__P.1__bin.001': {'weight': 99.9627}, 'PRJNA551026-COASSEMBLY__MAXBIN2-40__P.2__bin.002': {'weight': 98.9865}}, 'SRR9668957__MAXBIN2-107__P.1__bin.001': {'SRR9668960__CONCOCT__P.1__21': {'weight': 99.9627}, 'PRJNA551026-COASSEMBLY__MAXBIN2-40__P.2__bin.002': {'weight': 98.2802}, 'SRR9668957__MAXBIN2-107__P.1__bin.001': {'weight': 100.0}}, 'PRJNA551026-COASSEMBLY__MAXBIN2-40__P.2__bin.002': {'SRR9668960__CONCOCT__P.1__21': {'weight': 98.9865}, 'PRJNA551026-COASSEMBLY__MAXBIN2-40__P.2__bin.002': {'weight': 100.0}, 'SRR9668957__MAXBIN2-107__P.1__bin.001': {'weight': 98.2802}}, 'SRR9668965__CONCOCT__P.1__23': {'SRR9668965__CONCOCT__P.1__23': {'weight': 100.0}, 'SRR9668961__METABAT2__P.1__bin.2': {'weight': 96.6062}}, 'SRR9668961__METABAT2__P.1__bin.2': {'SRR9668965__CONCOCT__P.1__23': {'weight': 96.6062}, 'SRR9668961__METABAT2__P.1__bin.2': {'weight': 100.0}}, 'SRR9668960__CONCOCT__P.1__3': {'SRR9668960__CONCOCT__P.1__3': {'weight': 100.0}, 'PRJNA551026-COASSEMBLY__CONCOCT__P.1__5': {'weight': 99.7626}, 'SRR9668957__CONCOCT__P.1__38': {'weight': 99.66}}, 'PRJNA551026-COASSEMBLY__CONCOCT__P.1__5': {'SRR9668960__CONCOCT__P.1__3': {'weight': 99.7626}, 'SRR9668957__CONCOCT__P.1__38': {'weight': 99.7424}, 'PRJNA551026-COASSEMBLY__CONCOCT__P.1__5': {'weight': 100.0}}, 'SRR9668957__CONCOCT__P.1__38': {'SRR9668960__CONCOCT__P.1__3': {'weight': 99.66}, 'SRR9668957__CONCOCT__P.1__38': {'weight': 100.0}, 'PRJNA551026-COASSEMBLY__CONCOCT__P.1__5': {'weight': 99.7424}}, 'SRR9668959__METABAT2__P.1__bin.3': {'SRR9668959__METABAT2__P.1__bin.3': {'weight': 100.0}}, 'PRJNA551026-COASSEMBLY__CONCOCT__P.1__49': {'PRJNA551026-COASSEMBLY__CONCOCT__P.1__49': {'weight': 100.0}}, 'SRR9668973__METABAT2__P.1__bin.6': {'SRR9668973__METABAT2__P.1__bin.6': {'weight': 100.0}}}
graph_prok = nx.from_dict_of_dicts(d)

weights = list()
for (node_a, node_b, w) in graph_prok.edges(data="weight"):
    if node_a == node_b:
        w = 0
    weights.append(w)
weights = np.asarray(weights)*0.01

with plt.style.context("seaborn-white"):
    fig, ax = plt.subplots(figsize=(8,8))
    pos = nx.nx_agraph.graphviz_layout(graph_prok, prog="neato")
    nx.draw_networkx_nodes(graph_prok,pos=pos, ax=ax)
    nx.draw_networkx_edges(graph_prok,pos=pos, ax=ax, width=weights)#, connectionstyle="arc3,rad=0")

存在自环边的网络图

有效解决方案

方法1:从图中彻底删除自环边

直接用NetworkX内置方法筛选并删除所有自环边,后续绘图就不会包含这些边:

# 删除所有自环边
graph_prok.remove_edges_from(nx.selfloop_edges(graph_prok))

# 重新计算权重并绘图
weights = [w for (u, v, w) in graph_prok.edges(data="weight")]
weights = np.asarray(weights)*0.01

with plt.style.context("seaborn-white"):
    fig, ax = plt.subplots(figsize=(8,8))
    pos = nx.nx_agraph.graphviz_layout(graph_prok, prog="neato")
    nx.draw_networkx_nodes(graph_prok,pos=pos, ax=ax)
    nx.draw_networkx_edges(graph_prok,pos=pos, ax=ax, width=weights)

方法2:绘图时仅绘制非自环边

如果不想修改原图,可在绘图时指定只渲染非自环的边:

# 筛选非自环边及其对应权重
non_self_edges = [(u, v) for u, v in graph_prok.edges() if u != v]
non_self_weights = [graph_prok[u][v]['weight'] for u, v in non_self_edges]
non_self_weights = np.asarray(non_self_weights)*0.01

with plt.style.context("seaborn-white"):
    fig, ax = plt.subplots(figsize=(8,8))
    pos = nx.nx_agraph.graphviz_layout(graph_prok, prog="neato")
    nx.draw_networkx_nodes(graph_prok,pos=pos, ax=ax)
    # 仅绘制非自环边
    nx.draw_networkx_edges(graph_prok,pos=pos, ax=ax, edgelist=non_self_edges, width=non_self_weights)

说明

你之前修改权重为0仍有问题,是因为draw_networkx_edges仍会绘制这些边(即使宽度为0,部分渲染环境仍会留下痕迹),直接删除或筛选边才是彻底解决的办法。

内容的提问来源于stack exchange,提问作者O.rka

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 11:40:37