简体   繁体   中英

Plotting multigraphs with NetworkX/PyGraphviz: fine tuning node/edge position

I'd like to use NetworkX to more-or-less reproduce the following figure (from F. Crick, Nature 227, 561 (1970)):

在此处输入图片说明

I can reproduce the underlying graph using 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)

but apparently the built-in matplotlib plotting doesn't support parallel edges, as is needed for proper multigraphs.

On the other hand, I can convert g to a PyGraphviz AGraph and plot that:

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

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

在此处输入图片说明

This is pretty close to what I want, but I'm having trouble figuring out some of the finer details:

  • Using the circo layout, is it possible to center the "DNA" node at the top of the figure? If not, how can I control the absolute position of each node?

  • How do I tweak the positioning of the self-edges (eg the "DNA" -> "DNA" edge) so that they more closely resemble those in the original figure?

A small setup in plain Graphviz / dot syntax (feed it to http://www.webgraphviz.com/ and one can see the result):

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

Basic parts are here:

  • :n place to get the array at (other possibilities are other wind directions including eg :nw ).
  • rank=same; to align the mentioned nodes in one line

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM