绘制 networkx 图,节点标签默认为节点名称

2025-04-01 09:56:00
admin
原创
11
摘要:问题描述:NetworkX 功能强大,但我尝试绘制一个默认显示节点标签的图表,令我惊讶的是,对于刚接触 Networkx 的人来说,这个看似简单的任务竟然如此繁琐。这里有一个示例,展示了如何向图表中添加标签。https://networkx.github.io/documentation/latest/exa...

问题描述:

NetworkX 功能强大,但我尝试绘制一个默认显示节点标签的图表,令我惊讶的是,对于刚接触 Networkx 的人来说,这个看似简单的任务竟然如此繁琐。这里有一个示例,展示了如何向图表中添加标签。

https://networkx.github.io/documentation/latest/examples/drawing/labels_and_colors.html

这个例子的问题在于,它使用了太多的步骤和方法,而我想要做的只是在绘制图形时显示与节点名称相同的标签。

# Add nodes and edges
G.add_node("Node1")
G.add_node("Node2")
G.add_edge("Node1", "Node2")
nx.draw(G)    # Doesn't draw labels. How to make it show labels Node1, Node2 along?

有没有办法nx.draw(G)在图表中内联显示默认标签(在本例中为 Node1、Node2)?


解决方案 1:

tl/dr:只需添加with_labels=Truenx.draw呼叫即可。

您正在查看的页面有些复杂,因为它展示了如何设置许多不同的东西作为标签,如何为不同的节点赋予不同的颜色,以及如何提供精确控制节点位置的功能。所以有很多事情要做。

但是,您似乎只是希望每个节点使用自己的名称,并且对默认颜色和默认位置感到满意。因此

import networkx as nx
import pylab as plt

G=nx.Graph()
# Add nodes and edges
G.add_edge("Node1", "Node2")
nx.draw(G, with_labels = True)
plt.savefig('labels.png')

在此处输入图片描述

如果你想让节点标签不同,你可以发送一个字典作为参数。例如,

labeldict = {}
labeldict["Node1"] = "shopkeeper"
labeldict["Node2"] = "angry man with parrot"

nx.draw(G, labels=labeldict, with_labels = True)

在此处输入图片描述

解决方案 2:

我觉得更好的答案是不要使用 networkx 进行绘制。他们明确警告您图形可视化很难,而 networkx 主要用于图形分析(来自https://networkx.org/documentation/stable/reference/drawing.html#module-networkx.drawing.layout):

绘图 NetworkX 提供了可视化图形的基本功能,但其主要目标是实现图形分析,而不是执行图形可视化。将来,图形可视化功能可能会从 NetworkX 中删除或仅作为附加包提供。

正确的图形可视化很难,我们强烈建议人们使用专门用于该任务的工具来可视化他们的图形。专用且功能齐全的图形可视化工具的著名示例是 Cytoscape、Gephi、Graphviz 以及用于 LaTeX 排版的 PGF/TikZ。要使用这些工具和其他此类工具,您应该将 NetworkX 图形导出为这些工具可以读取的格式。例如,Cytoscape 可以读取 GraphML 格式,因此 networkx.write_graphml(G, path) 可能是一个合适的选择。

因此,我的建议是将图形转换为某种格式,该格式具有专用于图形可视化的软件,然后绘制(例如 pydot、pygraphviz、graphviz 等)。我怀疑 pydot 和 pygraphviz 是最好的,因为 networkx 仅支持这两个。从 pygraphviz 中的文档来看,它具有类似的 api,因此如果您已经想使用 networkx(https://pygraphviz.github.io/documentation/stable/tutorial.html),它可能是最容易使用的:

该 API 与 NetworkX 非常相似。https ://networkx.org/documentation/latest/tutorial.html上的大部分 NetworkX 教程适用于 PyGraphviz。有关主要差异,请参阅http://pygraphviz.github.io/documentation/latest/reference/api_notes.html

此外,pydot 目前实际上并没有文档(这让我个人感到困扰。我不知道它在我的浏览器上看起来是否好看,或者它是否让我觉得该项目没有得到开发人员的认真对待,我不知道有些事情就是感觉不对劲,即使它拥有更高的用户群 pydot 15k vs pygraphviz 4k)参考:https://github.com/pydot/pydot/pull/241

此外,似乎 pygraphviz 比常规 graphviz 具有更精细的控制:Graphviz vs PyGraphViz。另外,我不知道如何将 networkx 直接转换为 graphviz obj(因为 graphviz 拥有最好的文档和最高的用户群 ~19k 所以我更喜欢它),所以出于这些原因我会选择 pygraphviz。Pygravix 也有文档,虽然很小但却让我很满意(虽然不如 graphviz 好,但我不知道如何从 networkx 制作 graphviz 图表)。做出这些决定很难,但我不能永远停留在这个上面,这似乎足够用心。此外,networkx 很棒,因为我也可以将 dgl 图表转换为 networkx(并且重新标记很简单)。

考虑到这些原因,让我给你我编写的示例代码,该代码使用 pygraphviz 完成你想要的操作(但如果你知道如何操作,你可以用 pydot 来完成,使用 networkx 转换为 pydot obj 很简单,请参阅我之前的链接):

# https://stackoverflow.com/questions/28533111/plotting-networkx-graph-with-node-labels-defaulting-to-node-name

import dgl
import numpy as np
import torch

import networkx as nx

import matplotlib.pyplot as plt
import matplotlib.image as mpimg

from pathlib import Path

g = dgl.graph(([0, 0, 0, 0, 0], [1, 2, 3, 4, 5]), num_nodes=6)
print(f'{g=}')
print(f'{g.edges()=}')

# Since the actual graph is undirected, we convert it for visualization purpose.
g = g.to_networkx().to_undirected()
print(f'{g=}')

# relabel
int2label = {0: "app", 1: "cons", 2: "with", 3: "app3", 4: "app4", 5: "app5"}
g = nx.relabel_nodes(g, int2label)

# https://networkx.org/documentation/stable/reference/drawing.html#module-networkx.drawing.layout
g = nx.nx_agraph.to_agraph(g)
print(f'{g=}')
print(f'{g.string()=}')

# draw
g.layout()
g.draw("file.png")

# https://stackoverflow.com/questions/20597088/display-a-png-image-from-python-on-mint-15-linux
img = mpimg.imread('file.png')
plt.imshow(img)
plt.show()

# remove file https://stackoverflow.com/questions/6996603/how-to-delete-a-file-or-folder
Path('./file.png').expanduser().unlink()
# import os
# os.remove('./file.png')

输出:

g=Graph(num_nodes=6, num_edges=5,
      ndata_schemes={}
      edata_schemes={})
g.edges()=(tensor([0, 0, 0, 0, 0]), tensor([1, 2, 3, 4, 5]))
g=<networkx.classes.multigraph.MultiGraph object at 0x7f8443e94250>
g=<AGraph <Swig Object of type 'Agraph_t *' at 0x7f846117a930>>
g.string()='graph "" {
    app -- cons [key=0,
    id=0];
app -- with [key=0,
id=1];
app -- app3 [key=0,
id=2];
app -- app4 [key=0,
id=3];
app -- app5 [key=0,
id=4];
}
'

不过我想保留这个关于 pydot 可视化的链接,因为它总体上看起来非常有用:使用 pydot 显示图形而不保存,并且可能为其他人提供 pydot 答案(如果他们需要的话)。不过,我很乐意看到支持 pydot 的论据。


编辑1:如果您想按属性而不是按标签进行绘图,请参阅此答案:NetworkX 节点属性绘图注意,按照我建议的方式重新标记并不总是具有预期的语义(例如,它可能会连接两个不打算连接的节点)。


编辑2:如果你想绘制属性,而不是意外发生自循环,请参见以下答案:使用 PyGraphviz 在 graph\nodes 上绘制更多信息

相关推荐
  政府信创国产化的10大政策解读一、信创国产化的背景与意义信创国产化,即信息技术应用创新国产化,是当前中国信息技术领域的一个重要发展方向。其核心在于通过自主研发和创新,实现信息技术应用的自主可控,减少对外部技术的依赖,并规避潜在的技术制裁和风险。随着全球信息技术竞争的加剧,以及某些国家对中国在科技领域的打压,信创国产化显...
工程项目管理   2059  
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   1456  
  PLM(产品生命周期管理)软件在汽车行业正发挥着日益重要的作用,它贯穿于汽车从概念设计到退役处理的整个生命周期,为汽车企业提升效率、降低成本、提高产品质量提供了强大的支持。通过实际应用案例的解析,能更直观地了解PLM软件在汽车行业的价值与影响。PLM软件助力汽车设计创新在汽车设计阶段,PLM软件为设计师提供了一个协同的...
plm项目管理系统   0  
  企业数字化转型已成为当今众多企业寻求突破与发展的关键战略。在这一进程中,产品生命周期管理(PLM)系统发挥着至关重要的作用。PLM系统涵盖了从产品概念设计到产品退役的全生命周期管理,通过整合数据、流程和人员,为企业数字化转型提供了强大的支持。它不仅能提升企业内部的协同效率,还能优化产品创新流程,增强企业对市场变化的响应...
plm软件   2  
  产品生命周期管理(PLM)系统旨在整合产品从概念设计到退役的全生命周期数据与流程,助力企业提升创新能力、缩短产品上市时间、降低成本。然而,在PLM系统实施过程中,企业往往会遭遇诸多挑战。这些挑战若得不到妥善解决,将严重影响系统的实施效果与企业的业务发展。接下来,我们深入探讨PLM系统实施过程中常见的三大挑战。业务流程与...
plm系统主要干什么的   0  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用