5

I am using SPYDER. I have below code. The code produces the graph. But the graph is not clean. I would like to see layers in the graph - my first layer has 'start' node, second layer has 1,2,3 node, third layer has 'a', 'b', 'c' nodes and the last layer has 'end' node. Any idea how could i achieve my objective?

import networkx as nx
import matplotlib.pyplot as plt
import os.path as path

G=nx.DiGraph()
G.add_nodes_from(['start',1,2,3,'a','b','c','end'])

G.nodes(data=True)

G.add_edge('start',2)
G.add_edge('start',3)
G.add_edge(2,'b')
G.add_edge('b','end')
G.add_edge('a','end')
G.add_edge('f','g')
nx.draw(G)

------------------------update------------------

by layer i mean I should see the network like in the attached figure. I want the network drawn that way because a node in layer X will be connected directly ONLY to nodes in layer X+1 or layer X-1

enter image description here

David Duponchel
  • 3,959
  • 3
  • 28
  • 36
user2543622
  • 5,760
  • 25
  • 91
  • 159
  • Can you explain a little more what you mean by 'layer' in the drawing? – Aric Mar 23 '14 at 03:04
  • 1
    This question seems related to (if not a complete duplicate of) http://stackoverflow.com/questions/11479624/is-there-a-way-to-guarantee-hierarchical-output-from-networkx – John Y Mar 28 '14 at 15:32
  • [This one](http://stackoverflow.com/questions/22207802/pygraphviz-networkx-set-node-level-or-layer) I used in my answer may be even closer. I guess this actually is a duplicate. – KobeJohn Mar 28 '14 at 15:42

2 Answers2

5

It [seems that networkx does not provide much for arranging graphs but I have only touched it a few times so I can't say for sure. I couldn't find a way to do what you are asking.

However, I tried using graphviz (which has to be installed first) to accomplish it. Credit for the ranking method goes to this SO answer.

Copy-Paste Example

import networkx as nx

ranked_node_names = [['start'],
                     [1, 2, 3],
                     ['a', 'b', 'c'],
                     ['end']]
node_edges = [('start', 2),
              ('start', 3),
              (2, 'b'),
              ('b', 'end'),
              ('a', 'end')]

# graph and base nodes/edges in networkx
G = nx.DiGraph()
for rank_of_nodes in ranked_node_names:
    G.add_nodes_from(rank_of_nodes)
G.nodes(data=True)
G.add_edges_from(node_edges)
# I don't know a way to automatically arrange in networkx so using graphviz
A = nx.to_agraph(G)
A.graph_attr.update(rankdir='LR')  # change direction of the layout
for rank_of_nodes in ranked_node_names:
    A.add_subgraph(rank_of_nodes, rank='same')
# draw
A.draw('example.png', prog='dot')

Default Output

enter image description here

LR (left-right) Output

enter image description here

Community
  • 1
  • 1
KobeJohn
  • 7,390
  • 6
  • 41
  • 62
  • i have no way to test your solution as i am using windows and having issues installing pygraphviz and graphviz..i have already started a new question..http://stackoverflow.com/questions/22722730/installing-pygraphviz-on-windows-python-2-7-graphviz-2-36 If i succesfully install the graphviz then i will test your solution and give you your bounty... – user2543622 Mar 28 '14 at 20:46
  • @user2543622 I'm also on windows. Installed it and then added the /bin folder to the path. I think that's the only extra step I needed. What problem do you have installing/running the code? – KobeJohn Mar 28 '14 at 23:03
  • i was able to install pygraphviz using the link -http://www.lfd.uci.edu/~gohlke/pythonlibs/#pygraphviz. But now when i run the last line of code, i get an error which says " raise ValueError("Program %s not found in path."%prog) ValueError: Program nop not found in path." – user2543622 Mar 28 '14 at 23:33
  • @user2543622 If you add the bin folder to your path, that should go away. I had to do the same. – KobeJohn Mar 29 '14 at 09:27
  • please provide detailed answer. I am new to Python. what should be my path and where should i add it? – user2543622 Mar 29 '14 at 15:49
  • @user2543622 The path basically tells your computer where to look for things. Currently networkx is trying to use graphviz but can't find `nop` as you wrote. Check out [this tutorial](http://geekswithblogs.net/renso/archive/2009/10/21/how-to-set-the-windows-path-in-windows-7.aspx) about editing your path. You will have to add your graphviz bin folder as it shows you in the tutorial. If you used defaults, you probably need to add this: `C:\Program Files (x86)\Graphviz2.36\bin`. Alternatively, [this](https://patheditor2.codeplex.com/) is a tool you can use to add the folder to your path. – KobeJohn Mar 29 '14 at 16:54
2

You have at least two options: You can create a dictionary with node positions yourself if you like. First assign nodes to layers and then:

position = dict()
for (i, layer) in enumerate(layers):
    for (j, node) in enumerate(layer):
        position[node] = (i, j / float(len(layer))

and then you draw the network with the given node positions nx.draw(G, pos=position).

The other option is to use graphviz and the python AGraph class which can be used to produce hierarchical layouts.

Midnighter
  • 3,771
  • 2
  • 29
  • 43