I’m trying to use weights to define the distance between the nodes but it’s not working. I even tried to use normalized values without success.

import networkx as nx import matplotlib.pyplot as plt G = nx.Graph() raw_values = [(1,2, {'weight':70000000000}), (2,3,{'weight':700000}), (1,4,{'weight':1000000}), (2,4,{'weight':50000000000})] normalized_values = [] for l in list1: norm_value = np.log10(l[2]['weight']) normalized_values.append((l[0], l[1], {'weight': norm_value})) G.add_edges_from(raw_values) pos = nx.spring_layout(G) nx.draw_networkx(G,pos) edge_labels = nx.draw_networkx_edge_labels(G, pos) plt.show()

Here is the result I get, as you can see the nodes are very close even though the values are very different:

## Answer

`spring_layout`

implements the Fruchterman-Reingold algorithm, which models the graph as a system in which nodes repel each other. The repulsion is counteracted by springs that are placed between connected nodes.

The implementation in networkx has some issues, specifically with the repulsion term. This is evident in your example figure, where node 3 should never be at the center given that it is the least connected node.

However, your main grievance is with the attraction term. Basically, you defined extremely strong springs that are overcoming any repulsion term. As a consequence, the nodes are all bunched onto one point. When networkx returns these essentially random positions, the positions are rescaled to the bounding box implied by the `scale`

and `center`

parameters.

Your problem can be somewhat ameliorated by normalizing weights by their mean:

Note, however, that the small weight for edge (1, 4) (i.e. repulsion > attraction between 1 and 4) prevents nodes 1 and 4 being close to node 2, even though the weights for (2, 4) and (1, 2) are very large. In other words, the resulting layout is also constrained by the triangle inequality, and no normalization could possibly change that. Therefor, `spring_layout`

will, in general, not be able to reflect all weights (the exception being trees and graphs where weights are actual geometric distances).

#!/usr/bin/env python """ https://stackoverflow.com/q/67116565/2912349 """ import numpy as np import matplotlib.pyplot as plt import networkx as nx if __name__ == '__main__': edge_weights = { (1, 2) : 7_000_000_000, (2, 3) : 700_000, (1, 4) : 1_000_000, (2, 4) : 5_000_000_000, } G1 = nx.Graph([(source, target, {'weight' : w}) for (source, target), w in edge_weights.items()]) pos1 = nx.spring_layout(G1) mean = np.mean(list(edge_weights.values())) G2 = nx.Graph([(source, target, {'weight' : w / mean}) for (source, target), w in edge_weights.items()]) pos2 = nx.spring_layout(G2) fig, (ax1, ax2) = plt.subplots(1, 2) nx.draw_networkx(G1, pos1, ax=ax1) nx.draw_networkx(G2, pos2, ax=ax2) ax1.set_title('Raw') ax2.set_title('Normalized') ax1.axis('off') ax2.axis('off') plt.show()