Gráfica jerárquica con bordes paralelos.

Necesito crear un gráfico a partir de un conjunto de datos. He examinado innumerables preguntas de SO, pero no he podido encontrar una solución que se ajuste a todos los requisitos indispensables.

Lo que se necesita:

http://sofes.miximages.com/python/hzQHD07.png

Requisitos imprescindibles:

  1. Colocación jerárquica de nodos.
  2. Colocación ordenada de los nodos, es decir, ‘A’ debe estar a la izquierda de ‘B’
  3. Bordes paralelos entre nodos
  4. Longitud mínima del borde (para evitar la invasión de la etiqueta en el nodo, como en D – E)
  5. Solución programática, requiere poca o ninguna edición del archivo de puntos para el resultado deseado
  6. Escala a unos pocos miles de nodos.

Requisitos muy importantes:

  1. Líneas rectas (u orto)
  2. Etiquetas de cabeza y cola
  3. Opción para mostrar puntas de flecha

El gráfico podría no estar dirigido o dirigido, pero debería cumplir con los requisitos anteriores.

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

Lo anterior produce: http://sofes.miximages.com/python/1e9YTnQ.png

Por supuesto, los bordes paralelos no se muestran con el método anterior. Intenté usar un MultiDiGraph que admite bordes paralelos pero no puedo hacerlo funcionar debido al siguiente error, a pesar de definir claves únicas para los bordes paralelos (no se muestra en el código).

 Traceback (most recent call last): File "example3.py", line 31, in  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' 

El uso de graphviz sin networkx, como se muestra a continuación, me da los bordes paralelos, pero la jerarquía y el orden de los nodos han desaparecido. Sé que la jerarquía se puede arreglar agregando rango = igual al archivo de puntos, pero preferiría hacerlo programáticamente.

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

No se puede publicar el enlace de la imagen para la última representación debido a una reputación insuficiente.