0

I'm trying to create a visualization for a tree graph using networkx.
How can I choose the root node? i.e. the first one from the top.
Running this code:

import networkx as nx
import pydot
import matplotlib.pyplot as plt
from networkx.drawing.nx_pydot import *

G = nx.Graph()
G.add_edge(1,2)
G.add_edge(2,3)
G.add_edge(2,4)
G.add_edge(4,5)
G.add_edge(4,6)
G.add_edge(5,7)

pos = pydot_layout(G, prog="dot", root=4)
nx.draw(G, pos, with_labels=True)
plt.show()

Gives this output:

output

Note that I used root=4 to create the layout but still the root in the picture is node 1.
How can I decide which node is chosen as first/top one?
With other prog options such as "twopi" it does react to what I set as root.

motrix
  • 348
  • 1
  • 9

2 Answers2

3

I found a solution if G is a tree. Create an auxiliary (directed / nx.DiGraph) graph where the direction of each edge (v,w) is determined by the order in wich v and w are explored in a BFS starting at the root.
Then get the layout pos out of the directed graph aux_G and plot G with it

aux_G = my_func_directed_bfs(G, root=4)

pos = pydot_layout(aux_G , prog="dot")
nx.draw(G, pos, with_labels=True)
plt.show()
motrix
  • 348
  • 1
  • 9
  • 1
    Great!! I was looking at some programs where you can indeed add the position where you want to insert the node but `nx.draw()` draws anywhere on the x and y axis. Even if we restrict the axes using x_lim() and y_lim(), the nodes were getting disappeared!. I'm still not convinced about the fact no one has made any function to visualize the nodes according to their preference. Maybe it's due to the nature of graphs showing just the relationship between nodes, that's why they are visualized on any space map. – Raghav Gupta Nov 17 '20 at 19:43
1

NOTE: Networkx visualization always returns a plot random to the nodes.

Just because node 1 is appearing on the top of chart DOESN'T MEAN it is the root node! Since you may be using PyCharm (or whatever editor), the case may be every time you run your script, it stores some cache so you can get same output but I assure you the node visualization is created on the go.

Since you want to differentiate betweeen root node and other nodes, I recommend you to use node_color parameter of nx.draw().

Create a list of colors for each node and pass it to node_color

Here the full modified code you can use :-

G = nx.Graph()
G.add_edge(1,2)
G.add_edge(2,3)
G.add_edge(2,4)
G.add_edge(4,5)
G.add_edge(4,6)
G.add_edge(5,7)    

pos = pydot_layout(G, prog="dot", root=4)

colors = []
for node in G:
    if node == 4:
        colors.append('red')
    else: 
        colors.append('blue')
  
pos = pydot_layout(G, prog="dot", root=4)
nx.draw(G, pos,node_color=colos,with_labels=True)
plt.show()

Unfortunately, since the networkx visualization is integrated with highly denser visualization libraries like seaborn and matplotlib, it is not possible to decide the orientation of each node.

Raghav Gupta
  • 454
  • 3
  • 12
  • Thank you very much, but precisely my intention was to decide the orientation, as with a bigger graph it wont suffice with coloring the root. Are you aware of any other library/tool that allows me to do so? – motrix Nov 17 '20 at 17:07