2

I have a graph where my nodes can have multiple edges between them in both directions and I want to set the width between the nodes based on the sum of all edges between them.

import networkx as nx
nodes = [0,1]
edges = [(0,1),(1,0)]
G = nx.Graph()
G.add_nodes_from(nodes)
G.add_edges_from(edges)
weights = [2,3]
nx.draw(G, width = weights)

I would like to have the width between 0 and 1 set to 5 as that is the summed weight.

  • Possible duplicate of [networkx - change color/width according to edge attributes - inconsistent result](https://stackoverflow.com/questions/25639169/networkx-change-color-width-according-to-edge-attributes-inconsistent-result) – Matt Hall Oct 04 '19 at 20:41
  • At the very least, you'll need to change how you create your graphs. A networkx `Graph` is undirected and has at most 1 edge. It simply ignores the second time you add an edge. Try a `MultiGraph` to start. – Joel Oct 04 '19 at 21:16

1 Answers1

4

First you need to create a MultiDiGraph and add all possible edges to it. This is because it supports multiple directed egdes between the same set of nodes including self-loops.

import networkx as nx
nodes = [0, 1, 2, 3, 4, 5]
edges = [(0,1), (1,0), (1, 0),(0, 1), (2, 3), (2, 3), (2, 3), (2, 3),
         (4, 1), (4, 1), (4, 1), (4, 1), (4, 1), (4, 1), (4, 5), (5, 0)]
G = nx.MultiDiGraph()
G.add_nodes_from(nodes)
G.add_edges_from(edges)

Next, create a dictionary containing counts of each edges

from collections import Counter
width_dict = Counter(G.edges())
edge_width = [ (u, v, {'width': value}) 
              for ((u, v), value) in width_dict.items()]

Now create a new DiGraph from the edge_width dictionary created above

G_new = nx.DiGraph()
G_new.add_edges_from(edge_width)

Plotting using thickened edges

This is an extension of answer mentioned here.

edges = G_new.edges()
weights = [G_new[u][v]['width'] for u,v in edges] 
nx.draw(G_new, edges=edges, width=weights)

enter image description here

Add Edge labels

See this answer for more info.

pos = nx.spring_layout(G_new)
nx.draw(G_new, pos)
edge_labels=dict([((u,v,),d['width'])
             for u,v,d in G_new.edges(data=True)])

nx.draw_networkx_edges(G_new, pos=pos)
nx.draw_networkx_edge_labels(G_new, pos, edge_labels=edge_labels,
                             label_pos=0.25, font_size=10)

enter image description here

You can also view this Google Colab Notebook with working code.

References

Gambit1614
  • 8,547
  • 1
  • 25
  • 51