ACL
ACL

Reputation: 95

Why does networkx redraw my graph different each run?

I'd like to draw a graph with edges representing correlation coefficients between nodes. I have an edge for each unique relationship. The graph is different every time I rerun the following code. Is there a way to force one form of the graph? Also, not sure if this is even generating the graph correctly - please help with anything that looks wrong.

G = nx.Graph()
G.add_edge('A', 'B', weight=0.511012)
G.add_edge('A', 'C', weight=0.553063)
G.add_edge('A', 'D', weight=0.607859)
G.add_edge('A', 'E', weight=0.601554)
G.add_edge('A', 'F', weight=0.641796)

G.add_edge('B', 'C', weight=0.438743)
G.add_edge('B', 'D', weight=0.463087)
G.add_edge('B', 'E', weight=0.615150)
G.add_edge('B', 'F', weight=0.478853)

G.add_edge('C', 'D', weight=0.553063)
G.add_edge('C', 'E', weight=0.438743)
G.add_edge('C', 'F', weight=0.541893)

G.add_edge('D', 'E', weight=0.535331)
G.add_edge('D', 'F', weight=0.556995)

G.add_edge('E', 'F', weight=0.535446)

nx.draw(G, with_labels=True, node_color='orange', node_size=400, edge_color='black', linewidths=1, font_size=15)
plt.show()

Upvotes: 8

Views: 5017

Answers (2)

Joel
Joel

Reputation: 23837

The default of nx.draw uses nx.spring_layout to set the positions of the nodes. Unless a seed is fed into nx.spring_layout, it starts from a random initial condition and then uses movements based on treating the edges as springs and the nodes as masses to reposition the nodes. Because of this random initial condition, the positions will be different each time.

Often however, we may want to use multiple drawing commands to draw the nodes or edges(for example if we want some nodes in one size or style and other nodes in another size or style). For that, nx.draw accepts an optional argument pos which is a dictionary whose keys are the nodes and whose values are 2-tuples giving their (x,y) coordinates. Networkx has several functions that assign positions using different rules, and as I said above, the default uses a random initial condition so will give different outputs each time.

In your case you want to be sure that the network is given the same position each time you run your code. So you should feed a seed to the command that sets the positions.

#code to generate graph G here.
my_pos = nx.spring_layout(G, seed = 100)
nx.draw(G, pos = my_pos, with_labels=True, node_color='orange', node_size=400, edge_color='black', linewidths=1, font_size=15)
plt.show()

It is possible to allow the weights of the edges to cause the spring layout to act as if the higher weights are stronger springs. Check the documentation of spring_layout for more detail.

Upvotes: 11

Dimitrios Mavrommatis
Dimitrios Mavrommatis

Reputation: 321

Your code constructs a complete graph. NetworkX is not responsible for the way it visualizes the graph, but the underline library that you use; matplotlib in this case. You can check if you can define some primitives through that library to somehow keep the same graph for each run.

Also, keep in mind that NetworkX is not a tool for graph visualization as per documentation.

NetworkX provides basic functionality for visualizing graphs, but its main goal is to enable graph analysis rather than perform graph visualization. In the future, graph visualization functionality may be removed from NetworkX or only available as an add-on package.

Upvotes: 0

Related Questions