Note

This page was generated from user_guide/graph/convert.ipynb.
Interactive online version: Binder badge

Converting from GeoDataFrame to Graph and backΒΆ

The model situation expects to have all input data for analysis in GeoDataFrames, including street network (e.g. from shapefile).

[1]:
import momepy
import geopandas as gpd
import matplotlib.pyplot as plt
import networkx as nx
[2]:
streets = gpd.read_file(momepy.datasets.get_path('bubenec'), layer='streets')
[3]:
f, ax = plt.subplots(figsize=(10, 10))
streets.plot(ax=ax)
ax.set_axis_off()
plt.show()
../../_images/user_guide_graph_convert_3_0.png

We have to convert this LineString GeoDataFrame to networkx.Graph. We use momepy.gdf_to_nx and later momepy.nx_to_gdf as pair of interconnected functions. gdf_to_nx supports both primal and dual graphs. Primal approach will save length of each segment to be used as a weight later, while dual will save the angle between segments (allowing angular centrality).

[4]:
graph = momepy.gdf_to_nx(streets, approach='primal')
[5]:
nx.draw(graph)
../../_images/user_guide_graph_convert_6_0.png
[6]:
dual = momepy.gdf_to_nx(streets, approach='dual')
nx.draw(dual)
../../_images/user_guide_graph_convert_7_0.png

At this moment (almost) any networkx method can be used. For illustration, we will measure the node degree. Using networkx, we can do:

[7]:
degree = dict(nx.degree(graph))
nx.set_node_attributes(graph, degree, 'degree')

However, node degree is implemented in momepy so we can use directly:

[8]:
graph = momepy.node_degree(graph, name='degree')

Once we have finished our network-based analysis, we want to convert the graph back to geodataframe. For that, we will use momepy.nx_to_gdf, which gives us several options what to export.

  • lines

    • original LineString geodataframe

  • points

    • point geometry representing street network intersections (nodes of primal graph)

  • spatial_weights

    • spatial weights for nodes capturing their relationship within a network

Moreover, edges will contain node_start and node_end columns capturing the ID of both nodes at its ends.

[9]:
nodes, edges, sw = momepy.nx_to_gdf(graph, points=True, lines=True,
                                    spatial_weights=True)
[10]:
f, ax = plt.subplots(figsize=(10, 10))
nodes.plot(ax=ax, column='degree', cmap='tab20b', markersize=(nodes['degree'] * 100), zorder=2)
edges.plot(ax=ax, color='lightgrey', zorder=1)
ax.set_axis_off()
plt.show()

../../_images/user_guide_graph_convert_14_0.png
[11]:
nodes.head(3)
[11]:
degree nodeID geometry
0 3 1 POINT (1603585.640 6464428.774)
1 5 2 POINT (1603413.206 6464228.730)
2 3 3 POINT (1603268.502 6464060.781)
[12]:
edges.head(3)
[12]:
geometry mm_len node_start node_end
0 LINESTRING (1603585.640 6464428.774, 1603413.2... 264.103950 1 2
1 LINESTRING (1603561.740 6464494.467, 1603564.6... 70.020202 1 9
2 LINESTRING (1603585.640 6464428.774, 1603603.0... 88.924305 1 7