0

我需要从一组数据中创建一个图表。我已经筛选了无数 SO 问题,但无法找到适合所有必备要求的解决方案。

需要什么:

http://i.imgur.com/hzQHD07.png

必备要求:

  1. 节点的分层放置
  2. 节点的有序放置,即“A”应该在“B”的左侧
  3. 节点之间的平行边
  4. 边的最小长度(避免标签侵占节点,如 D--E)
  5. 编程解决方案,几乎不需要编辑点文件即可获得所需的结果
  6. 扩展到几千个节点

非常重要的要求:

  1. 直线(或正交)
  2. 头尾标签
  3. 显示箭头的选项

该图可以是无向的或有向的,但应满足上述要求。

import networkx as nx
g = nx.Graph()

g.add_edge(node1,node3,headlabel='label 2', taillabel='label 1',fontsize='10')
g.add_edge(node1,node4,headlabel='label 4', taillabel='label 3',fontsize='10')
g.add_edge(node2,node5,headlabel='label 6', taillabel='label 5',fontsize='10')
g.add_edge(node2,node6,headlabel='label 8', taillabel='label 7',fontsize='10')
g.add_edge(node4,node5,headlabel='really long label', taillabel='really long label',fontsize='10')
g.add_edge(node4,node5)
g.add_edge(node3,node7)
g.add_edge(node7,node8)
g.add_edge(node7,node8)
g.add_edge(node4,node8)
g.add_edge(node5,node8)
g.add_edge(node5,node9,headlabel='label 12', taillabel='label 11',fontsize='10')
g.add_edge(node6,node9,headlabel='label 10', taillabel='label 9',fontsize='10')

A = nx.to_agraph(g)
A.add_subgraph([node1,node2],rank='same')
A.add_subgraph([node3,node4,node5,node6],rank='same')
A.add_subgraph([node7,node8,node9],rank='same')
A.draw('example2.png', prog='dot')

以上产生:http: //i.imgur.com/1e9YTnQ.png

当然,上述方法没有显示平行边缘。我尝试使用支持平行边的 MultiDiGraph,但由于以下错误而无法使其工作,尽管为平行边定义了唯一键(代码中未显示)。

Traceback (most recent call last):
  File "example3.py", line 31, in <module>
    A = nx.to_agraph(g)
  File "C:\python27\lib\site-packages\networkx-1.11rc1-py2.7.egg\networkx\drawing\nx_agraph.py", line 152, in to_agraph
    A.add_edge(u,v,key=str(key),**str_edgedata)
  File "C:\python27\lib\site-packages\pygraphviz\agraph.py", line 481, in add_edge
    eh = gv.agedge(self.handle, uh, vh, key, _Action.find)
KeyError: 'agedge: no key'

如下所示,在没有 networkx 的情况下使用 graphviz,可以得到平行边,但层次结构和节点顺序消失了。我知道可以通过将 rank=same 添加到点文件来修复层次结构,但我更喜欢以编程方式进行。

import graphviz as gv
g = gv.Graph(format='png')

g.edge(node1,node3,headlabel='label 2', taillabel='label 1',fontsize='10')
g.edge(node1,node4,headlabel='label 4', taillabel='label 3',fontsize='10')
g.edge(node2,node5,headlabel='label 6', taillabel='label 5',fontsize='10')
g.edge(node2,node6,headlabel='label 8', taillabel='label 7',fontsize='10')
g.edge(node4,node5,headlabel='really long label', taillabel='really long label',fontsize='10')
g.edge(node4,node5)
g.edge(node3,node7)
g.edge(node7,node8)
g.edge(node7,node8)
g.edge(node4,node8)
g.edge(node5,node8)
g.edge(node5,node9,headlabel='label 12', taillabel='label 11',fontsize='10')
g.edge(node6,node9,headlabel='label 10', taillabel='label 9',fontsize='10')

g.render('example')

由于信誉不足,无法发布最后一次渲染的图片链接。

4

0 回答 0