Problems with networkx.layout.spring_layout fixed functionality

524 views
Skip to first unread message

Niclas Böhmer

unread,
Jul 5, 2021, 9:38:23 AM7/5/21
to networkx-discuss
Hi everyone,

given the complete pairwise distances of a set of points, I would like to plot the points such that the distances in the plot respect the true given distances as good as possible.
For this, I am using the networkx implementation of the Fruchterman-Reingold force-directed algorithm (networkx.layout.spring_layout) and it works quite well.
Now, I would like to fix some of my points and I discovered that spring_layout actually offers this functionality (the reason why I want to do it is that I want to visualize different sets of points that partly overlap and I would like to fix the positions of the overlapping points such that the created visualizations are easier to compare).

Unfortunately, there seems to be something wrong either with the implementation of this feature or the way I am using it (simple code example and pictures attached):
I first run spring_layout without any fixed points (fig.png). Afterward, I run spring_layout again (fig2.png) again but now with the coordinate of one point fixed and set to the computed coordinate of the first run of the algorithm. The result of the second run is completely different from the first run and pretty useless for me. The reason why I suspect that there might be a problem with the implementation is because, in principle, fixing the position of a single point should not really change the output (apart from some shifting maybe) and because I have never seen something similar without any fixed points.

I also did some more experiments where I fixed two points to the computed coordinates of a previous run and there the initial result also looks pretty different and much better than the one after fixing the two points (fig 3.png).

 
I would be grateful for any kind of help or advice!
code.zip

Dan Schult

unread,
Jul 5, 2021, 9:44:22 AM7/5/21
to networkx...@googlegroups.com
You should consider the “pos” parameter of the spring_layout.  It provides the initial positions for the algorithm. Without it, the initial positions are set randomly and can change quite a lot from run to run.  So if you are comparing two runs, you could set the initial positions to the final positions obtained in run1, and fix node 1 
To see how the other adjust.  You could also add small random amounts to the pos values and then use that as an initial position.  Your mileage may vary.:}

Niclas Böhmer

unread,
Jul 5, 2021, 9:59:54 AM7/5/21
to networkx-discuss
Hey Dan,

thanks for the answer. If I initialize the positions of all points as the output of the previous run, then it works (after all, if I understand the algorithm correctly, then it converges to some local optimum and if I start already in one, then the algorithm will more or less finish immediately). I guess it also works for small perturbations. However, if something like this is really necessary to get meaningful results, then I do not really get what this feature can be used for. Unfortunately, this fix is also not an option for the actual purpose I want to use the algorithm for, as I would there like to fix the positions of some points independent of the other points and also use the same fixed points for different sets of other points. But maybe this is something that the the algorithm is simply not capable of.

Moreover, I am still surprised how much this fixing on point for a random initialization of all other points changes things. Without a fixed point, I have never seen a similar picture as the outcome.

Dan Schult

unread,
Jul 5, 2021, 10:44:18 AM7/5/21
to networkx...@googlegroups.com
The algorithm finds a local optimum of the positions. 
As it does that, it needs to have some initial positions. You can control that as much as you like.
It also allows you to fix some of the point's positions so the local optimum is constrained by those positions.
That's the interface you can work with.

The most common use I've seen for initial positions is to find new layouts after a change in the graph structure -- like removing an edge.  Most of the network stays in the same position, but the impact of removing that edge makes a local difference that can be quite large. 

I don't understand what you are trying to do, but that's OK... You do. And now you know what is possible and how the algorithm works and what it's parameters are.  Hopefully you can find a way to do what you want.  It should not be too surprising that random initial points can make a huge difference in the resulting layout.  Try a simple graph like nx.path_graph(6) and draw it multiple times. The layouts are very very different. It's all due to different initial positions of the nodes. If you want consistency, you should not use completely random initial positions...  Perhaps randomness can be involved, but you should constrain the positions to ensure consistency -- maybe set the nodes into a circle shape with random tweaks around that shape.  By controlling the input "pos" parameter, you can probably make the algorithm solve whatever you want to do with it.  Set some initial values to random values, and others to fixed values. It is very flexible.

Reply all
Reply to author
Forward
0 new messages