'Networkx color graph edges based on weight value

I have a dataframe with some columns. I've created a Networkx undirected graph and I want to draw the corresponding network. I need also to change the color of the edges based on the weights of those edges, so I used a LinearColorMap. This is the code:

#my other stuff

cmap = LinearSegmentedColormap.from_list('RwG',['red','white','green'])
nx.draw(G, poss, node_size=1500, node_color='lightgrey', edgelist=edges,edge_color=weights,
width=list(map(lambda number: number * 16 / m, x)), edge_cmap=cmap)

However, I need to normalize my color map so that the white color is centered on a specific value (e.g. -76). The weights are in the [-60,-100] range. How can I achieve that ? Visually:

enter image description here



Solution 1:[1]

If you pass in a matplotlib colormap to networkx, networkx will normalize your numerical color argument linearly between the minimum and maximum value. Personally, I think this is a somewhat shortsighted design decision but it is what it is: your non-linear mapping of weights to color is simply not possible. You can, however, pre-compute the colors and pass those in instead (similarly how you are precomputing edge widths):

#!/usr/bin/env python
import numpy as np
import matplotlib.pyplot as plt
import networkx as nx

def weight_to_color(w, threshold):
    if w < threshold:
        return 'green'
    elif np.isclose(w , threshold):
        return 'white'
    else: # x > threshold
        return 'red'

weight_matrix = 40 * np.random.rand(10, 10) - 100
g = nx.from_numpy_array(weight_matrix)
weights = [g.edges[edge]['weight'] for edge in g.edges]
nx.draw(g, node_color='lightgray', edgelist=g.edges, edge_color=[weight_to_color(w, -76) for w in weights])
plt.show()

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Paul Brodersen