Построение мультиграфов с NetworkX / PyGraphviz: точная настройка узла / края - PullRequest
0 голосов
/ 10 ноября 2018

Я хотел бы использовать NetworkX, чтобы более или менее воспроизвести следующую фигуру (из F. Crick, Nature 227, 561 (1970)):

enter image description here

Я могу воспроизвести базовый граф, используя MultiDiGraph:

import networkx as nx

g = nx.MultiDiGraph()
weakEdges = [('RNA', 'DNA'), ('RNA', 'RNA'), ('RNA', 'protein')]
strongEdges = [('DNA', 'DNA'), ('DNA', 'RNA'), ('DNA', 'protein')]
g.add_edges_from(weakEdges)
g.add_edges_from(strongEdges)

, но, очевидно, встроенное построение matplotlib не поддерживает параллельные ребра, как это необходимо для правильных мультиграфов.

С другой стороны, я могу преобразовать g в PyGraphviz AGraph и построить график:

a = nx.nx_agraph.to_agraph(g)
for etup in weakEdges:
    a.get_edge(*etup).attr['style'] = 'dashed'

a.draw('test2.png', prog='circo')

enter image description here

Это довольно близко к тому, что я хочу, но у меня возникают проблемы с выяснением некоторых более мелких деталей:

  • Используя макет circo, возможно центрировать "ДНК "узел в верхней части фигуры?Если нет, то как я могу контролировать абсолютную позицию каждого узла?

  • Как настроить позиционирование самоограничений (например, «ДНК» -> «ДНК» ребра)чтобы они больше походили на исходные цифры?

1 Ответ

0 голосов
/ 10 ноября 2018

Небольшая настройка в простом синтаксисе Graphviz / точка (введите http://www.webgraphviz.com/, и вы увидите результат):

digraph X {
{rank=same; RNA Protein}
DNA -> RNA
DNA -> Protein
Protein -> RNA
DNA:n -> DNA:n
}

Основные части здесь:

  • :n место для размещения массива (другие возможности - другие направления ветра, включая, например, :nw).
  • rank=same; для выравнивания упомянутых узлов в одну строку
...