3 Percolation analysis¶
This section will apply percolation clustering analysis to the street network.
Percolation can be used to identify the clusters of areas that are connected within a certain distance threshold. The process consists of a series of thresholdings of the network, in which weak links get disconnected. For each threshold, different subgraphs emerged as the network starts to disconnect. The percolation threshold is the point at which the network transitions from a collection of isolated clusters to a single connected cluster.
***Original code from Arcuate et al, 2024. Tutorial OSSEN Street Network and Accessiblity ***
Step 3 Percolation¶
The process consists of a series of thresholds of the network. Through setting different distance thresholds, different subgraphs emerged as the network starts to disconnect.
Note that the thresholds are NOT universal. Also that the networks from the OMS are incomplete, hence more detail, referring to smaller streets being present, will only be given in cities where the effort to map those streets has been put into it. Hence, different distances will be found for the transitions in different cities.
Percolation theory , which studies how a piece of information (or a disease, or a fire, etc.) spreads in space, reaching a critical point at which a giant cluster appears. In its most general form, the process is defined in an infinite lattice and for a random occupation probability. Relaxing these constraints, the analysis can be extended to finite systems, where the clusters are the outcome of some thresholding process. Some of these systems present a multiplicity of percolation transitions, revealing a hierarchical organization
Percolation theory is classically approached in terms of the probability of a site being occupied in a lattice. It can also be thought of in terms of bond percolation, in which the sites are all occupied, and the probability corresponds to a bond to be open and to connect sites
A distance parameter is used that determines clusters of intersection points in which every point has a neighbour at a distance equal or smaller than the given threshold
First let us define the vector containing the percolation thresholds of interest
rmin = 10 #10 metres as the starting distance threshold
rmax = 1501 #1500 metres as the ending threshod
r0 = np.arange(rmin, rmax, 10)
n_loops = len(r0)
file_clust_size = 'cluster_size.txt'
with open(file_clust_size, 'w') as file:
file.write('threshold\t size\n')
Define the thresholds to plot the 10 largest clusters on maps
jumps_2plot = [90,150,170,200,230,270,280,430,700]
# Define the colors for the top 10 clusters
top10 = ['red', 'green', 'blue', 'orange', 'purple', 'yellow', 'pink', 'cyan', 'magenta', 'brown']
# Visualize the colors
plt.bar(range(1, 11), range(1, 11), color=top10)
plt.show()
# Obtain the node counts of the network
size_net = G2.number_of_nodes()
size_net
36214
#Percolation process & plot
for i_t in r0:
# Find subgraph such that all weights <= threshold r0
edges_1 = [(u, v, d) for u, v, d in G2.edges(data=True) if d['length'] <= i_t]
g = nx.Graph()
g.add_edges_from(edges_1)
g.remove_nodes_from(list(nx.isolates(g)))
# Take subcomponents
membclusters = {node: cid for cid, component in enumerate(nx.connected_components(g)) for node in component}
m = pd.DataFrame(list(membclusters.items()), columns=["id_point", "id_cluster"])
table_data = m['id_cluster'].value_counts()
# Largest connected component
LCC = table_data.max()
LCC_p = LCC / size_net
v_LCC = [i_t, LCC, LCC_p]
if i_t == rmin:
v_LCC_t = np.array([v_LCC])
else:
v_LCC_t = np.vstack([v_LCC_t, v_LCC])
sorted_table = table_data.sort_values(ascending=False)
if i_t in jumps_2plot:
# Assign colours
list_clusts = sorted_table.reset_index()
list_clusts.columns = ["id_cluster", "n_points"]
list_clusts['colour'] = 'grey'
list_clusts.loc[:9, 'colour'] = top10
list_clusts['size'] = 0.1
list_clusts.loc[:9, 'size'] = 0.2
total_list = pd.merge(list_clusts, m, on="id_cluster")
points_coords_cols = pd.merge(total_list, data_coords, on="id_point")
# # Plot the original street network system as background
# fig, ax = plt.subplots(1, 1, figsize=(10, 8),facecolor='black')
# edges.plot(ax=ax, color='grey', edgecolor='black')
# # plt.savefig(file_map, height=850, width=1000)
# plt.figure(figsize=(10, 8), facecolor='black')
# plt.scatter(points_coords_cols['x'], points_coords_cols['y'], s=points_coords_cols['size'] * 50, c=points_coords_cols['colour'], edgecolor='none')
# plt.title(f"Oxford at d={i_t}m", color='white')
# plt.axis('off')
# plt.show()
# # plt.savefig(file_map)
# # plt.close()
# Plot the original street network system as background
fig, ax = plt.subplots(1, 1, figsize=(10, 8), facecolor='black')
# Plot points
ax.scatter(points_coords_cols['x'], points_coords_cols['y'], s=points_coords_cols['size'] * 50, c=points_coords_cols['colour'], edgecolor='none',zorder = 1)
# Plot edges geometry as background
edges.plot(ax=ax, color='grey', linewidth=0.5, zorder = 0)
ax.set_title(f"Nairobi at d={i_t}m", color='white')
ax.axis('off')
plt.show()
/usr/local/lib/python3.10/dist-packages/pandas/core/frame.py:717: DeprecationWarning: Passing a BlockManager to GeoDataFrame is deprecated and will raise in a future version. Use public APIs instead. warnings.warn(
/usr/local/lib/python3.10/dist-packages/pandas/core/frame.py:717: DeprecationWarning: Passing a BlockManager to GeoDataFrame is deprecated and will raise in a future version. Use public APIs instead. warnings.warn(
/usr/local/lib/python3.10/dist-packages/pandas/core/frame.py:717: DeprecationWarning: Passing a BlockManager to GeoDataFrame is deprecated and will raise in a future version. Use public APIs instead. warnings.warn(
/usr/local/lib/python3.10/dist-packages/pandas/core/frame.py:717: DeprecationWarning: Passing a BlockManager to GeoDataFrame is deprecated and will raise in a future version. Use public APIs instead. warnings.warn(
/usr/local/lib/python3.10/dist-packages/pandas/core/frame.py:717: DeprecationWarning: Passing a BlockManager to GeoDataFrame is deprecated and will raise in a future version. Use public APIs instead. warnings.warn(
/usr/local/lib/python3.10/dist-packages/pandas/core/frame.py:717: DeprecationWarning: Passing a BlockManager to GeoDataFrame is deprecated and will raise in a future version. Use public APIs instead. warnings.warn(
/usr/local/lib/python3.10/dist-packages/pandas/core/frame.py:717: DeprecationWarning: Passing a BlockManager to GeoDataFrame is deprecated and will raise in a future version. Use public APIs instead. warnings.warn(
/usr/local/lib/python3.10/dist-packages/pandas/core/frame.py:717: DeprecationWarning: Passing a BlockManager to GeoDataFrame is deprecated and will raise in a future version. Use public APIs instead. warnings.warn(
/usr/local/lib/python3.10/dist-packages/pandas/core/frame.py:717: DeprecationWarning: Passing a BlockManager to GeoDataFrame is deprecated and will raise in a future version. Use public APIs instead. warnings.warn(