Unable to assign random node attributes in networkx

Viewed 52

I want to generate 10 random graphs with different node attributes but with the same underlying configuration (4 nodes and the same edge arrangements). Randomness is associated with the values of the node attributes only.

Each node has two attributes: expertise_level and innovation_level. The objective is to have 10 graphs, each with a random set of values (High/Medium/Low) for these two attributes.


import numpy as np
import networkx as nx

masterG = [] #to store generated graphs in a list
G = nx.path_graph(4) #creating a specific 4-node graph configuration

def randompicking(levels = ["High", "Medium", "Low"]):
    abc = np.random.choice(levels, len(list(G)), replace = True, p=[0.33, 0.33, 0.34])
    return abc.tolist()

def initializeG():
    expertise_level  = dict(list(enumerate(randompicking())))
    innovation_level = dict(list(enumerate(randompicking())))
    
    nx.set_node_attributes(G, expertise_level,  'expertise_level')
    nx.set_node_attributes(G, innovation_level, 'innovation_level')

for i in range(10):
    initializeG()
    masterG.append(G)

masterG

The problem: When I am running the code manually for generating each graph by unpacking the code inside intializeG() and moving the code outside of this function (i.e., not creating this function but using the inside code in the global environment), the node attributes generated are random (unique) in each graph as desired. However, when I am running the code using the function initializeG() as above, the node attributes generated for each node in each graph (stored in masterG) are exactly the same.

Can anyone explain where the code is going wrong?

1 Answers

You have a unique graph here as you're reusing your graph. See how the ID is the same:

[<networkx.classes.graph.Graph at 0x7f3500c7e9d0>,
 <networkx.classes.graph.Graph at 0x7f3500c7e9d0>,
...
 <networkx.classes.graph.Graph at 0x7f3500c7e9d0>,
 <networkx.classes.graph.Graph at 0x7f3500c7e9d0>]

You need to create a new graph each time you call initializeG:

import numpy as np
import networkx as nx

masterG = [] #to store generated graphs in a list

def randompicking(levels = ["High", "Medium", "Low"]):
    abc = np.random.choice(levels, len(list(G)), replace = True, p=[0.33, 0.33, 0.34])
    return abc.tolist()

def initializeG():
    G = nx.path_graph(4) #creating a specific 4-node graph configuration
    expertise_level  = dict(list(enumerate(randompicking())))
    innovation_level = dict(list(enumerate(randompicking())))
    
    nx.set_node_attributes(G, expertise_level,  'expertise_level')
    nx.set_node_attributes(G, innovation_level, 'innovation_level')
    return G

for i in range(10):
    G = initializeG()
    masterG.append(G)

output (now IDs are different, each graph is a different object):

[<networkx.classes.graph.Graph at 0x7f3500ab4b80>,
 <networkx.classes.graph.Graph at 0x7f3500ab47c0>,
 <networkx.classes.graph.Graph at 0x7f3500ab4970>,
 <networkx.classes.graph.Graph at 0x7f3500c45160>,
 <networkx.classes.graph.Graph at 0x7f3500c452b0>,
 <networkx.classes.graph.Graph at 0x7f3500c45040>,
 <networkx.classes.graph.Graph at 0x7f35009536d0>,
 <networkx.classes.graph.Graph at 0x7f3500c45220>,
 <networkx.classes.graph.Graph at 0x7f3500c45430>,
 <networkx.classes.graph.Graph at 0x7f3500c45400>]
Related