Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python NetworkX - Why are graphs always randomly rotated?

If I generate the same graph multiple times using NetworkX and Matplotlib it's rotated randomly on every generation:

Run 1: Run 1

Run 2: enter image description here

Without changing the script or input data, the graph is randomly rotated every time it is generated. Is it possible to specify an orientation?

As the graph becomes more densely populated (above are just samples but ultimately I will have thousands of nodes and edges), it will be difficult to see the newly added nodes or edges if they are moved because the graph picture is rotated.

import networkx as nx
import matplotlib.pyplot as plt
from networkx.readwrite import json_graph
#
# The graph data is loaded from JSON
#
graph = json_graph.node_link_graph(input_json)
    pos = nx.spring_layout(graph)
    nx.draw(graph, pos, with_labels=True, node_size=300)
    edge_labels=dict([((u,v,),d['weight']) for u,v,d in graph.edges(data=True)])
    nx.draw_networkx_edge_labels(graph, pos, edge_labels=edge_labels)
    plt.savefig("test.png")

A second less important question is why are the edges/lines from R1 to R2 and R1 to R5 so much longer? Update: I hadn't set the "length" attribute in the JSON data source.

like image 868
jwbensley Avatar asked Sep 21 '18 13:09

jwbensley


3 Answers

I just found out that you can fix the initial state of the random generated graph: just seed the generator so it will always produce the same set of random positions.

random_pos = nx.random_layout(graph, seed=42)
pos = nx.spring_layout(graph, pos=random_pos)
like image 68
fabrizioM Avatar answered Nov 15 '22 00:11

fabrizioM


From the docs:

spring_layout(G, dim=2, k=None, pos=None, fixed=None, iterations=50, weight='weight', scale=1.0)

pos : dict or None optional (default=None)

Initial positions for nodes as a dictionary with node as keys and values as a list or tuple. If None, then use random initial positions.

So if you don't specify initial positions of your nodes, NetworkX will do so at random.

https://networkx.github.io/documentation/networkx-1.9/reference/generated/networkx.drawing.layout.spring_layout.html

like image 42
Andy Avatar answered Nov 14 '22 23:11

Andy


The algorithm has a random initialization - this is quite standard for network layouts. You will have the same issue with any graph library. You can replicate the same layout in NetworkX in two ways: save the node position dictionary (for example as a json) and reload it every time you want to visualize, or pass a seed to the layout algorithm:

seed (int, RandomState instance or None optional (default=None)) – Set the random state for deterministic node layouts. If int, seed is the seed used by the random number generator, if numpy.random.RandomState instance, seed is the random number generator, if None, the random number generator is the RandomState instance used by numpy.random.

hope that helps!

like image 35
Johannes Wachs Avatar answered Nov 15 '22 00:11

Johannes Wachs