为了账号安全,请及时绑定邮箱和手机立即绑定

如何以可读的方式绘制复杂的networkx DiGraph?

如何以可读的方式绘制复杂的networkx DiGraph?

有只小跳蛙 2022-10-05 17:54:30
我想使用 networkx 来研究一个相当大的项目的架构,但是到目前为止我所做的测试并不是那么好,这是我所有研究的一个最小示例:import matplotlib.pyplot as pltimport networkx as nxfrom networkx.readwrite import node_link_graphnx.draw(G, with_labels=True)plt.show()如您所见,以这种幼稚的方式绘制图形将产生完全无用且不可读的输出,例如:问题是,在我阅读了 networkx 教程/文档之后,检查了一些谷歌参考资料后,我一直无法找到完成任务的正确方法。我已经安装了graphviz,但是无论如何我尝试在windows上构建和运行pygraphivz/pydot都失败了……问题:如何使用 networkx 以某种层次和干净的方式绘制复杂的图形,其中节点均匀分布在它们之间?下面你可以看到我想在这里实现的输出类型:如您所见,节点分散,循环显示正确,层次结构的不同级别自上而下完全清晰......如果可以使用networkx实现类似(或类似)的事情,那就太好了。事实上,本文所描述的正是我想在这里实现的输出类型NS。从这个网站借来的图片示例
查看完整描述

1 回答

?
慕桂英3389331

TA贡献2036条经验 获得超8个赞

drawnetworkx的各种函数都带有一个pos参数,该参数是一个字典,其中节点名称为键,x,y 坐标为值。


你可以自己生成这个。如果您知道要强加的层次结构,则可以将层次结构转换为 y 位置,然后随时添加填充 x 位置:


# exctracting nodes from dictionary into list:

nodes = [{'id': 'build'}, {'id': 'root'}, {'id': 'utils'}, {'id': 'codegen'}, {'id': 'codegen.templates'}, {'id': 'nodes.shapes'}, {'id': 'codegen.c_types'}, {'id': 'nodes'}, {'id': 'containers'}, {'id': 'distutils'}, {'id': 'wheel'}, {'id': 'tools.testing'}, {'id': 'finalizations'}, {'id': 'importing'}, {'id': 'plugins'}, {'id': 'freezer'}, {'id': 'tree'}, {'id': 'specs'}, {'id': 'optimizations'}, {'id': 'plugins.standard'}, {'id': 'tools.general.dll_report'}, {'id': 'tools.specialize'}, {'id': 'tools.testing.compare_with_cpython'}, {'id': 'tools.testing.find_sxs_modules'}, {'id': 'tools.testing.measure_construct_performance'}, {'id': 'tools.testing.run_root_tests'}, {'id': 'tools'}]


nodelist = []

for n in nodes:

    for k, v in n.items():

        nodelist.append(v)


# hierarchy here is arbitrarily defined based on the index of hte node in nodelist. 

# {hierarchy_level : number_of_nodes_at_that_level}

hierarchy = {

    0:4,

    1:10,

    2:5,

    3:5,

    4:3

}


coords = []

for y, v in hierarchy.items():

    coords += [[x, y] for x in list(range(v))]


# map node names to positions 

# this is based on index of node in nodelist.

# can and should be tailored to your actual hierarchy    

positions = {}

for n, c in zip(nodelist, coords):

    positions[n] = c


fig = plt.figure(figsize=(15,5))

nx.draw_networkx_nodes(G, pos=positions, node_size=50)

nx.draw_networkx_edges(G, pos=positions, alpha=0.2)


# generate y-offset for the labels, s.t. they don't lie on the nodes

label_positions = {k:[v0, v1-.25] for k, (v0,v1) in positions.items()}

nx.draw_networkx_labels(G, pos=label_positions, font_size=8)

plt.show()

//img1.sycdn.imooc.com//633d5a3a0001d58f08460282.jpg

节点标签有些重叠,但这可以通过字体大小进行调整,通过图形尺寸进行额外偏移


编辑:

旋转节点标签以避免文本重叠:


text = nx.draw_networkx_labels(G, pos=label_positions, font_size=8)

for _, t in text.items():

    t.set_rotation(20)

//img1.sycdn.imooc.com//633d5a470001a4eb08480282.jpg

查看完整回答
反对 回复 2022-10-05
  • 1 回答
  • 0 关注
  • 187 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信