如何移除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
相关产品推荐
相关产品推荐

