Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a way to guarantee hierarchical output from NetworkX?

I'm trying to produce a flow diagram of a tree structure. I've been able to create representative graphs with networkx, but I need a way to show the tree structure when I output a plot. I'm using matplotlib.pylab to plot the graph.

I need to show the data in a structure similar to what is shown here. Although I don't have sub-graphs.

How can I guarantee a structure like that?

Examples for the unbelievers:

Various NetworkX layouts

I've been able to show the graphs with pylab and graphviz, but neither offer the tree structure I'm looking for. I've tried every layout networkx has to offer, but none of them show a hierarchy. I've just not sure what options/mode to give it OR if I need to use weights. Any suggestions would help a bunch.

@jterrace:

Here's a rough outline of what I used to produce the plots above. I've added some labels, but other than that it's the same.

import networkx as nx import matplotlib.pyplot as plt G = nx.Graph()  G.add_node("ROOT")  for i in xrange(5):     G.add_node("Child_%i" % i)     G.add_node("Grandchild_%i" % i)     G.add_node("Greatgrandchild_%i" % i)      G.add_edge("ROOT", "Child_%i" % i)     G.add_edge("Child_%i" % i, "Grandchild_%i" % i)     G.add_edge("Grandchild_%i" % i, "Greatgrandchild_%i" % i)  plt.title("draw_networkx") nx.draw_networkx(G)  plt.show() 
like image 919
max Avatar asked Jul 13 '12 23:07

max


People also ask

Can one get hierarchical graphs from NetworkX with Python 3?

With networkx you should be able to use DIGraph with the dot layout. This should display a tree graph. The development version of pygraphviz does work with Python 3.

Can NetworkX handle large graphs?

NX is certainly capable of handling graphs that large, however, performance will largely be a function of your hardware setup. Aric will likely give a better answer, but NX loads graphs into memory at once, so in the ranges your are describing you will need a substantial amount of free memory for it to work.

Is Igraph faster than NetworkX?

On the pokec dataset it takes just 0.2s to run the page rank algorithm (graph-tool: 1.7s, igraph: 59.6s, snap: 19.5s). For the k-core decomposition it is also 10 times faster than all other competitors or 2000 times networkx.

Is NetworkX scalable?

The fact that networkX is mostly written in python does not mean that it is not scalable, nor claims perfection. There is always a trade-off. If you throw more money on your "machines", you'll have as much scalability as you want plus the benefits of using a pythonic graph library.


2 Answers

If you use a directed graph then the Graphviz dot layout will do something like you want with the tree. Here is some code similar to the above solutions that shows how to do that

import networkx as nx from networkx.drawing.nx_agraph import graphviz_layout import matplotlib.pyplot as plt G = nx.DiGraph()  G.add_node("ROOT")  for i in range(5):     G.add_node("Child_%i" % i)     G.add_node("Grandchild_%i" % i)     G.add_node("Greatgrandchild_%i" % i)      G.add_edge("ROOT", "Child_%i" % i)     G.add_edge("Child_%i" % i, "Grandchild_%i" % i)     G.add_edge("Grandchild_%i" % i, "Greatgrandchild_%i" % i)  # write dot file to use with graphviz # run "dot -Tpng test.dot >test.png" nx.nx_agraph.write_dot(G,'test.dot')  # same layout using matplotlib with no labels plt.title('draw_networkx') pos=graphviz_layout(G, prog='dot') nx.draw(G, pos, with_labels=False, arrows=False) plt.savefig('nx_test.png') 

Graphviz output

NetworkX/Matplotlib output

UPDATED

Here is a version updated for networkx-2.0 (and with upcoming networkx-2.1 draws arrows too).

import networkx as nx from networkx.drawing.nx_agraph import write_dot, graphviz_layout import matplotlib.pyplot as plt G = nx.DiGraph()  G.add_node("ROOT")  for i in range(5):     G.add_node("Child_%i" % i)     G.add_node("Grandchild_%i" % i)     G.add_node("Greatgrandchild_%i" % i)      G.add_edge("ROOT", "Child_%i" % i)     G.add_edge("Child_%i" % i, "Grandchild_%i" % i)     G.add_edge("Grandchild_%i" % i, "Greatgrandchild_%i" % i)  # write dot file to use with graphviz # run "dot -Tpng test.dot >test.png" write_dot(G,'test.dot')  # same layout using matplotlib with no labels plt.title('draw_networkx') pos =graphviz_layout(G, prog='dot') nx.draw(G, pos, with_labels=False, arrows=True) plt.savefig('nx_test.png') 

enter image description here

like image 122
Aric Avatar answered Sep 29 '22 15:09

Aric


You can use pygraphviz to get close:

>>> import pygraphviz >>> import networkx >>> import networkx as nx >>> G = nx.Graph() >>> G.add_node("ROOT") >>> for i in xrange(5): ...     G.add_node("Child_%i" % i) ...     G.add_node("Grandchild_%i" % i) ...     G.add_node("Greatgrandchild_%i" % i) ...     G.add_edge("ROOT", "Child_%i" % i) ...     G.add_edge("Child_%i" % i, "Grandchild_%i" % i) ...     G.add_edge("Grandchild_%i" % i, "Greatgrandchild_%i" % i)  >>> A = nx.to_agraph(G) >>> A.layout('dot', args='-Nfontsize=10 -Nwidth=".2" -Nheight=".2" -Nmargin=0 -Gfontsize=8') >>> A.draw('test.png') 

Result: enter image description here

Note I copied the graphviz options from the link you posted above. I'm not sure why the 4th child is drawn on top instead of in strictly vertical format. Maybe someone who knows more about the Graphviz options can help with that.

like image 28
jterrace Avatar answered Sep 29 '22 17:09

jterrace