Иерархический граф с параллельными ребрами

Мне нужно создать граф из набора данных. Я просеял бесчисленные вопросы SO, но не смог найти решение, соответствующее всем необходимым требованиям.

Что нужно:

View post on imgur.com

Обязательные требования:

  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' 

Использование graphviz без networkx, как показано ниже, дает мне параллельные ребра, но иерархия и упорядочение узлов ушли. Я знаю, что иерархия может быть исправлена ​​путем добавления ранга = то же самое к файлу точки, но я бы предпочел сделать это программно.

 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') 

Невозможно опубликовать ссылку на изображение для последнего рендеринга из-за недостаточной репутации.

Python - лучший язык программирования в мире.