在SPYDER中用Python绘制有向图
我正在使用SPYDER,下面是我的代码。这个代码可以生成图形,但图形看起来不太清晰。我希望在图中看到不同的层次——第一层有一个“开始”节点,第二层有1、2、3这几个节点,第三层有“a”、“b”、“c”这几个节点,最后一层有一个“结束”节点。有没有什么办法可以实现我的目标呢?
import networkx as nx
import matplotlib.pyplot as plt
import os.path as path
G=nx.DiGraph()
G.add_nodes_from(['start',1,2,3,'a','b','c','end'])
G.nodes(data=True)
G.add_edge('start',2)
G.add_edge('start',3)
G.add_edge(2,'b')
G.add_edge('b','end')
G.add_edge('a','end')
G.add_edge('f','g')
nx.draw(G)
------------------------更新------------------
我所说的层次是指我希望网络的展示方式像附图那样。我想要这样的网络图,因为在某一层的节点只会直接连接到上一层或下一层的节点。
2 个回答
2
你至少有两个选择:如果你愿意,可以自己创建一个字典来保存节点的位置。首先,把节点分配到不同的层级,然后:
position = dict()
for (i, layer) in enumerate(layers):
for (j, node) in enumerate(layer):
position[node] = (i, j / float(len(layer))
接着,你可以用给定的节点位置来绘制网络,使用的代码是 nx.draw(G, pos=position)
。
另一个选择是使用 graphviz
和 Python 的 AGraph
类,这样可以生成分层的布局。
5
看起来 networkx 对于图的排列功能支持得不多,不过我只用过几次,所以不能确定。我找不到实现你所要求功能的方法。
不过,我尝试使用 graphviz
(这个需要先安装)来实现这个功能。关于排名方法的来源可以参考 这个StackOverflow的回答。
复制粘贴示例
import networkx as nx
ranked_node_names = [['start'],
[1, 2, 3],
['a', 'b', 'c'],
['end']]
node_edges = [('start', 2),
('start', 3),
(2, 'b'),
('b', 'end'),
('a', 'end')]
# graph and base nodes/edges in networkx
G = nx.DiGraph()
for rank_of_nodes in ranked_node_names:
G.add_nodes_from(rank_of_nodes)
G.nodes(data=True)
G.add_edges_from(node_edges)
# I don't know a way to automatically arrange in networkx so using graphviz
A = nx.to_agraph(G)
A.graph_attr.update(rankdir='LR') # change direction of the layout
for rank_of_nodes in ranked_node_names:
A.add_subgraph(rank_of_nodes, rank='same')
# draw
A.draw('example.png', prog='dot')