11

Given any graph G created in NetworkX, I want to be able to assign some weights to G.edges() after the graph is created. The graphs involved are grids, erdos-reyni, barabasi-albert, and so forth.

Given my G.edges():

[(0, 1), (0, 10), (1, 11), (1, 2), (2, 3), (2, 12), ...]

And my weights:

{(0,1):1.0, (0,10):1.0, (1,2):1.0, (1,11):1.0, (2,3):1.0, (2,12):1.0, ...}

How can I assign each edge the relevant weight? In this trivial case all weights are 1.

I've tried to add the weights to G.edges() directly like this

for i, edge in enumerate(G.edges()):
    G.edges[i]['weight']=weights[edge]

But I get this error:

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-48-6119dc6b7af0> in <module>()
     10 
     11 for i, edge in enumerate(G.edges()):
---> 12     G.edges[i]['weight']=weights[edge]

TypeError: 'instancemethod' object has no attribute '__getitem__'

What's wrong? Since G.edges() is a list, why can't I access its elements as with any other list?

FaCoffee
  • 7,609
  • 28
  • 99
  • 174

3 Answers3

17

It fails because edges is a method.

The documentation says to do this like:

G[source][target]['weight'] = weight

For example, the following works for me:

import networkx as nx

G = nx.Graph()

G.add_path([0, 1, 2, 3])

G[0][1]['weight'] = 3

>>> G.get_edge_data(0, 1)
{'weight': 3}

However, your type of code indeed fails:

G.edges[0][1]['weight'] = 3
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-14-97b10ad2279a> in <module>()
----> 1 G.edges[0][1]['weight'] = 3

TypeError: 'instancemethod' object has no attribute '__getitem__'

In your case, I'd suggest

for e in G.edges():
    G[e[0]][e[1]] = weights[e]
Ami Tavory
  • 74,578
  • 11
  • 141
  • 185
  • Thanks. Since I later need to access the edge data key associated with the weight (I need to compute the incidence matrix), what would that be in your example? I can't find it so I assume there isn't any. How to add it? – FaCoffee Oct 19 '16 at 11:15
  • @CF84 Not really sure what "edge data key associated with the weight" means. – Ami Tavory Oct 19 '16 at 11:23
  • When you call `nx.incidence_matrix(G, nodelist=None, edgelist=None, oriented=False, weight=None)`, if you leave `weight=None` then all weights will be set at 1. Instead, to take advantage of your answer above, I need weights to be different. So the docs say that `weight` is a string that represents "the edge data key used to provide each value in the matrix". Now I've posted a trivial case where all weights are 1, but this was just a proof of principle. – FaCoffee Oct 19 '16 at 11:26
  • @CF84 Still not sure I understand your question, but are you looking for an external `dict` mapping weights to edges? – Ami Tavory Oct 19 '16 at 11:35
  • Yes, this is what would be useful – FaCoffee Oct 19 '16 at 11:36
  • 1
    @CF84 So in your loop, as you update the edge weights in the graph, also update this dictionary. Everything will then be cross-referenced. – Ami Tavory Oct 19 '16 at 11:57
  • The documentation link is broken. Might want to be https://networkx.org/documentation/stable/reference/classes/generated/networkx.Graph.get_edge_data.html – Stef Jan 05 '22 at 11:27
  • Link of the Documentation needs to be updated. I don't know which specific page it should land on. – Rys Jan 07 '23 at 18:16
8

From the docs:

  • You can set all the edge weights at once to the same value with
nx.set_edge_attributes(G, values = 1, name = 'weight')
  • Given a dictionary with keys corresponding to edge tuples (your weights), you can assign edge weights to values from that dictionary with
nx.set_edge_attributes(G, values = weights, name = 'weight')
  • To view and verify that these edge attributes have been set
G.edges(data = True)
rlchqrd
  • 519
  • 4
  • 11
1

Add edges like this:

g1.add_edge('Mark', 'Edward', weight = 3) g1.add_edge('Joseph', 'Michael', weight = 3) g1.add_edge('Joseph', 'Jason', weight = 4)

And then check whether the graph is weighted:

nx.is_weighted(g1)

True

Categorize weights by their magnitude:

elarge = [(u, v) for (u, v, d) in g1.edges(data=True) if d['weight'] > 4]
esmall = [(u, v) for (u, v, d) in g1.edges(data=True) if d['weight'] <= 4]

Next to display the weighted graph:

pos = nx.spring_layout(g1)  # positions for all nodes

nodes

nx.draw_networkx_nodes(g1, pos, node_size=100)

edges

nx.draw_networkx_edges(g1, pos, edgelist=elarge,
                   width=5)
nx.draw_networkx_edges(g1, pos, edgelist=esmall,
                   width=5, alpha=0.5, edge_color='g', style='dashed')
dega
  • 27
  • 1