Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

python drawing directed graph in SPYDER

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

like image 851
user2543622 Avatar asked Mar 22 '14 23:03

user2543622


1 Answers

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

like image 120
KobeJohn Avatar answered Oct 11 '22 07:10

KobeJohn