Home > Mobile >  How to set color for nodes based on normalized random float attribute using Networkx and Matplotlib?
How to set color for nodes based on normalized random float attribute using Networkx and Matplotlib?

Time:10-12

Using Networkx, I have built a tree-like graph whose nodes each have a float attribute 'hc', which varies between 0 and 1, and is attributed at random to each node. For example, node 1 has 'hc' = 0.53 while node 2 has 'hc' = 0.47.

I would like to assign a color to each node based on the value of 'hc', preferentially in a way such that 0 corresponds to red and 1, to deep purple (similar to the jet colormap, see miscellaneous section in here ). Since my code is rather long and confusing I will not copy it here, so please use the code of this random network below as a reference. The part that assigns the 'hc' values is literally the same one I used with my tree.

G = nx.erdos_renyi_graph(20, 0.1)

lower,upper = 0,1 # Parameters to normalize the x-axis of the gaussian
mean_hc = 0.5 # Mean value of hc atribute
devi_hc = 0.1   # Standard Deviation of hc atribute

gaussian_hc = stats.truncnorm((lower - mean_hc) / devi_hc, (upper - mean_hc) / devi_hc, loc=mean_hc, scale=devi_hc)

for i in G:
  G.nodes[i]['hc'] =  gaussian_hc.rvs()
  # The hc atributes have 14 digits. Use G.nodes[i]['hc'] = round(gaussian_hc.rvs(),3) for better performance

colour_aux = nx.get_node_attributes(G, 'hc') # List of values of 'hc' of each node respectively
colour_aux[n] # 'hc' value of n'th node

print(G.nodes.data()) # Print all nodes' data
pos = graphviz_layout(G, prog="dot")
plt.figure(figsize=(30, 30))
nx.draw(G, pos) # Delete the node colour if colour not necessary
plt.show()

CodePudding user response:

NetworkX uses a list of colors (or values) the same length as the number of nodes to assign colors to the nodes with the node_color argument.

If colors are passed in, NetworkX uses those directly. If values are passed in, NetworkX maps those to a colormap defined in the cmap argument. See the documentation here for more information.

The list needs to be in the same order as the nodes, so I find that it's always safest (though probably not always necessary) to generate the list of colors based on the order that NetworkX has the nodes in that can be found by calling G.nodes().

So for your case, I'd do the following that gets the node's hc attribute for every node in the graph and ensures that the order is consistent with what NetworkX has internally:

colorlist = [G.nodes[node]['hc'] for node in G.nodes()]

Then when you actually want to draw your graph, NetworkX will be expecting a Matplotlib colormap. Assuming you have Maplotlib imported as mpl, the following should do the trick:

nx.draw(G, pos = pos, node_color = colorlist, cmap = mpl.colormaps['jet'])

Other colormaps can be found here and plt.cmap.jet would work as well for cmap.

  • Related