This is a simplified version of this SO question (link) with some program output.
Using Python and networkX under macOS, I am not able to assign a value to an edge attribute as follows:
import networkx as nx
import matplotlib.pyplot as plt
import pandas as pd
import matplotlib.pyplot as plt
from pyvis.network import Network
from io import StringIO
csv_cities= """City,Location,Lon,Lat,x,y,,LonDat,LatDat
Los Angeles,"Los Angeles, California, United States",-118.254190,34.048050,140,328,q,-123.114980,25.761681
New York,"New York, New York, United States",-74.005994,40.712749,1415,591,q,-71.056800,51.045700
Atlanta,"Atlanta, Georgia, United States",-84.389854,33.750800,1116,316,q,-94.971032,39.002842
Chicago,"Chicago, Illinois, United States",-87.632360,41.881954,1022,638,q,52.05818,25.284019 """
csv_connections= """City1,City2,numTracks,NumCarSpots,Colors,SegmentTotalCarSpots
Chicago,Los Angeles,1,4,Blue,4
New York,Chicago,2,2,"Orange, Black",4
Atlanta,Chicago,1,3,Blue,3"""
cities = pd.read_csv(StringIO(csv_cities))
interCityConnections = pd.read_csv(StringIO(csv_connections))
G = nx.Graph()
#Add cities to graph
coords={}
for index, row in cities.iterrows():
print(f"{row['City']:<17} {int(row['x']):<6} {int(row['y']):<6}")
G.add_node(row['City'],city=True, x=row['x'], y=row['y'], physics=False,
label=row['City'], title=f'{row['x']},{row['y']}')
coords[row['City']]=int(row['x']),int(row['y'])
print("- 1 - ")
#Add intercity connections
for index, row in interCityConnections.iterrows():
print(f"{row['City1']:>17} <-{row['NumCarSpots']} {row['Colors']}-> {row['City2']:<17} ")
G.add_edge(row['City1'],row['City2'],interCity=True,numTracks=row['numTracks'])
G[row['City1']][row['City2']]['taxes']="Major" # This works
shortPaths=nx.all_shortest_paths(G,row['City1'], row['City2'])
G[row['City1']][row['City2']]['shortPaths']=shortPaths #some assignment happens here
# but value not usable outside loop?
for p in shortPaths: #This works
print(f"Path:{p}") #This works
print("- 2 - ")
print(G['Atlanta']['Chicago'])
print(f"type:{type(G['Atlanta']['Chicago']['shortPaths'])}")
for p in G['Atlanta']['Chicago']['shortPaths']:
print("For looping...") # This never executes
print(f"Path:{p}") # This never executes
print("Done. There should be a path displayed above this line.")
This is the output:
q@q-mbp ttr % py simplebug.py
Los Angeles 140 328
New York 1415 591
Atlanta 1116 316
Chicago 1022 638
- 1 -
Chicago <-4 Blue-> Los Angeles
Path:['Chicago', 'Los Angeles']
New York <-2 Orange, Black-> Chicago
Path:['New York', 'Chicago']
Atlanta <-3 Blue-> Chicago
Path:['Atlanta', 'Chicago']
- 2 -
{'interCity': True, 'numTracks': 1, 'taxes': 'Major', 'shortPaths': <generator object _build_paths_from_predecessors at 0x10d107480>}
type:<class 'generator'>
Done. There should be a path displayed above this line.
So, how can I modify an edge attribute from inside that for loop and have the change persist outside the scope of the loop?
How can I access the result of this assignment:
G[row['City1']][row['City2']]['shortPaths']=shortPaths
outside the for loop?
This feels like some kind of scope bug, but I admittedly am quite new to both Python and networkX. I wonder if I should be passing G into the for loop somehow, but I am at a loss.
4