networkx - change color/width according to edge attributes - inconsistent result networkx - change color/width according to edge attributes - inconsistent result python python

networkx - change color/width according to edge attributes - inconsistent result


The order of the edges passed to the drawing functions are important. If you don't specify (using the edges keyword) you'll get the default order of G.edges(). It is safest to explicitly give the parameter like this:

import networkx as nxG = nx.Graph()G.add_edge(1,2,color='r',weight=2)G.add_edge(2,3,color='b',weight=4)G.add_edge(3,4,color='g',weight=6)pos = nx.circular_layout(G)edges = G.edges()colors = [G[u][v]['color'] for u,v in edges]weights = [G[u][v]['weight'] for u,v in edges]nx.draw(G, pos, edges=edges, edge_color=colors, width=weights)

This results in an output like this:enter image description here


Dictionaries are the underlying data structure used for NetworkX graphs, and as of Python 3.7+ they maintain insertion order.This means that we can safely use nx.get_edge_attributes to retrieve edge attributes since we are guaranteed to have the same edge order in every run of Graph.edges() (which is internally called by get_edge_attributes).

So when plotting, we can directly set attributes such as edge_color and width from the result returned by get_edge_attributes. Here's an example:

G = nx.Graph()G.add_edge(0,1,color='r',weight=2)G.add_edge(1,2,color='g',weight=4)G.add_edge(2,3,color='b',weight=6)G.add_edge(3,4,color='y',weight=3)G.add_edge(4,0,color='m',weight=1)colors = nx.get_edge_attributes(G,'color').values()weights = nx.get_edge_attributes(G,'weight').values()pos = nx.circular_layout(G)nx.draw(G, pos,         edge_color=colors,         width=list(weights),        with_labels=True,        node_color='lightgreen')

enter image description here


if you want to avoid adding edge colors and alphas / width manually, you may also find this function helpful:

def rgb_to_hex(rgb):    return '#%02x%02x%02x' % rgbadjacency_matrix = np.array([[0, 0, 0.5], [1, 0, 1], [1, 0.5, 0]]))n_graphs = 5fig, axs = plt.subplots(1, len(n_graphs), figsize=(19,2.5)) for graph in range(n_graphs):       pos = {0: (1, 0.9), 1: (0.9, 1), 2: (1.1, 1)}     # draw DAG graph from adjacency matrix     gr = nx.from_numpy_matrix(adjacency_matrix, create_using=nx.DiGraph)    weights = nx.get_edge_attributes(gr, "weight")      # adding nodes     all_rows = range(0, adjacency_matrix.shape[0])    for n in all_rows:        gr.add_node(n)        # getting edges     edges = gr.edges()          # weight and color of edges     scaling_factor = 4 # to emphasise differences     alphas = [weights[edge] * scaling_factor for edge in edges]    colors = [rgb_to_hex(tuple(np.repeat(int(255 * (1-     weights[edge])),3))) for edge in edges]        # draw graph     nx.draw(gr,             pos,             ax=axs[graph],            edgecolors='black',             node_color='white',             node_size=2000,             labels={0: "A", 1: "B", 2: "C"},            font_weight='bold',            linewidths=2,            with_labels=True,            connectionstyle="arc3,rad=0.15",            edge_color=colors,            width=alphas)  plt.tight_layout()