Search code examples
pythonfilenamesnetworkxshapefile

NetworkX: create batch graphs from shapefiles


Say you have the following directory with multiple shapefiles:

MyFolder
|
|---S1.shp
|---S2.shp
|---S3.shp
|---
|---
|---S50.shp

And you want to create one graph for each one of these, and call them the same (e.g., the graph associated with S1.shp is called S1).

I am trying to do this in a for loop:

import networkx as nx
import os

myfolder=r'C:\Users\MyName\MyFolder'
os.chdir(myfolder) 
for root, dirs, filenames in os.walk(myfolder):
    for f in filenames:
        if f.endswith('.shp') and f[0]=='S': #Consider only the files with an "S" in their name
            G=nx.read_shp(f)
            pos={k: v for k,v in enumerate(G.nodes())}
            pos_x = {k:(round(a,4),round(b,4)) for k,(a,b) in pos.items()}
            graph_name=f.split('.', 1)[0]
            GG=nx.Graph(name=graph_name)  
            GG.add_nodes_from(pos_x.keys())

Now the GG=nx.Graph(name=graph_name) line does not do what I want, in that the graph is still called GG, and not S1 and such. The correct graph name is stored in GG.name, but I cannot retrieve the graph by calling its GG.name.

Is there a way I can assign the graph a name that is the filename, without the extension?


Solution

  • You could make GG a dict which maps filenames to graphs:

    import networkx as nx
    import os
    
    myfolder = r'C:\Users\MyName\MyFolder'
    os.chdir(myfolder)
    GG = dict()
    for root, dirs, filenames in os.walk(myfolder):
        for f in filenames:
            if f.endswith('.shp') and f.startswith('S'):
                G = nx.read_shp(f)
                pos_x = {k: (round(a, 4), round(b, 4))
                         for k, (a, b) in enumerate(G.nodes())}
                graph_name, graph_ext = os.path.splitext(f)
                GG[graph_name] = nx.Graph(name=graph_name)
                GG[graph_name].add_nodes_from(pos_x.keys())
    

    Then the graph associated with S1.shp could be accessed by GG['S1'].