Networkx Spring Layout with Different Edge Values

10,890

Solution 1

You can accomplish what you're after (almost).

1) You can predefine some weights that will affect the node distances. (but you can't specify the distance directly)

2) You can feed an initial position into the spring_layout algorithm, which will result in a consistent final output. (You can even specify certain nodes that aren't allowed to change position if you want that as well). Or you can assign a seed to the random number generator used by nx.spring_layout using the optional argument seed.

import networkx as nx

G = nx.Graph()
G.add_edges_from([(1,2, {'myweight':20}), (2,3,{'myweight':0.1}), 
                  (1,4,{'myweight':1}), (2,4,{'myweight':50})])
initialpos = {1:(0,0), 2:(0,3), 3:(0,-1), 4:(5,5)}
pos = nx.spring_layout(G,weight='myweight', pos = initialpos)

nx.draw_networkx(G,pos)

import pylab as plt
plt.savefig('test.png')

enter image description here

Documentation is available here. The source code can be found here.

Look at nx.draw if you want rid of axes.

Note that there are other ways to add weighted edges than just what I've done.

Solution 2

According to the documentation spring_layout takes a weight-keyword which is the name of the edge attribute to use as weight when applying the layout. An example:

import networkx as nx
import random
G = nx.path_graph(5)

# Add some random weights (as dictonary with edges as key and weight as value).
nx.set_edge_attributes(G, 'my_weight', dict(zip(G.edges(), [random.random()*10 for edge in G.edges()])))

# Apply layout using weights.
pos = nx.spring_layout(G, weight='my_weight')
nx.draw(G, pos)
Share:
10,890
slaw
Author by

slaw

Scientist, Data Wrangler, and Python Lover

Updated on June 13, 2022

Comments

  • slaw
    slaw about 2 years

    I am new to Networkx and trying to figure out how to use the spring layout but applying different edge values (i.e., different distances between nodes) between nodes rather than the same edge value.

    Essentially, I want a graph that tries to maintain a predefined set of node-node distances (likely using a spring layout to find some local minimum) with certain edges having a higher weight than others. However, the Networkx documentation suggests that all of the edges will have the same weight.

    Additionally, on a simple case of drawing the spring_layout graph, I noticed that the resulting graph changes conformation each time I run it. Is there a way to get the same graph back (i.e., setting some random seed)?

    import networkx as nx
    G = nx.path_graph(5)
    nx.draw(G) 
    
  • slaw
    slaw about 9 years
    Is the weight inversely proportional to the potential and is it equivalent to the force constant in Hooke's law? I see a "length" attribute for an edge and would want to be as close to my preset lengths as possible (i.e., find the local minimum that allows me to have nodes positioned to resemble the preset lengths).
  • Joel
    Joel about 9 years
    There's a bit of an explanation of what's going on in this answer. These are basically the spring constants, but there's no guarantee that it's at a local minimum when it gives the positions. The exact algorithm used is Fruchterman-Reingold. If you spend a bit of time reading about it, you'll quickly know more than I do.
  • h-rai
    h-rai over 5 years
    Is there a way to minimise edge crossings?