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