.. DO NOT EDIT. .. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. .. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: .. "examples/metro_simulation2.py" .. LINE NUMBERS ARE GIVEN BELOW. .. only:: html .. note:: :class: sphx-glr-download-link-note :ref:`Go to the end ` to download the full example code. .. rst-class:: sphx-glr-example-title .. _sphx_glr_examples_metro_simulation2.py: Metro simulation 2. ================== Example of a simulation of the evolution of a graph signal over the Santiago Metro network. Simulation of the distribution of a signal over the metro network. The starting conditions is a graph signal with only one positive integer value bigger.The plots or animation show how this signal distributes over the network using: .. math:: y = AD^-1x This example adds some constraints to the previous metro simulation example. Some of them are: 1. Eliminates the backward connections on the simulation and substracts 1 to every node degree to avoid dilution of the signal by going backwards. 2. If the 2 wagons arrive at the same metro station, there is no other way but out. All the people in those wagons will exit the sations. 3. In terminal stations, the people will not travel backwards this will also force an exit to everyone that reaches the terminal station. 4. If there are less than the number of people that is set to get out in every station then then wagon is emptyed. The output is a folder with numerated figures. You can use websites such as https://gifmaker.me/ to make an animation with the resulting figures. The initial condition is a graph signal with only one positive integer value bigger.The plots or animation show how this signal distributes over the network using: .. math:: y = AD^-1x To run this example, you need to download three files and place them in the same directory as this script. 1. Download the file `Tablas de subidas y bajadas nov23.zip` from this link: https://www.dtpm.cl/descargas/modelos_y_matrices/Tablas%20de%20subidas%20y%20bajadas%20nov23.zip Then, uncompress the zip file and copy `2023.11 Matriz_baj_SS_MH.xlsb` to the same location as this script. 2. Download the file `santiago_metro_stations_coords.geojson` from this link: https://zenodo.org/records/11637462/files/santiago_metro_stations_coords.geojson 3. Download the file `santiago_metro_stations_connections.txt` from this link: https://zenodo.org/records/11637462/files/santiago_metro_stations_connections.txt .. GENERATED FROM PYTHON SOURCE LINES 57-73 .. code-block:: Python import os import matplotlib.pyplot as plt import networkx as nx import numpy as np from pygsp2.utils_examples import fetch_data, make_metro_graph current_dir = os.getcwd() os.chdir(current_dir) try: os.mkdir('metro_simulation2/') except FileExistsError: print('Warning: It seems like this folder already exists. Overwritting...') .. GENERATED FROM PYTHON SOURCE LINES 74-76 .. code-block:: Python assets_dir = os.path.join(current_dir, 'data') fetch_data(assets_dir, 'metro') .. GENERATED FROM PYTHON SOURCE LINES 77-94 .. code-block:: Python G, pos = make_metro_graph(edgesfile=os.path.join(assets_dir, 'santiago_metro_stations_connections.txt'), coordsfile=os.path.join(assets_dir, 'santiago_metro_stations_coords.geojson')) stations = list(G) W0 = nx.adjacency_matrix(G).toarray() D = np.diag(W0 @ np.ones(len(W0))) # The signal will advance through the graph. In our case # the backwards direction needs to be subtracted. Otherwise # the signal will be "diluted" in each step by half since # there is a backwards connection available. D[D > 1] = D[D > 1] - 1 D_inv = np.linalg.inv(D) # Store terminal stations. Anything that arrives here # will get out of the network. terminal_stations = np.where(np.sum(W0, axis=1) == 1) .. GENERATED FROM PYTHON SOURCE LINES 95-105 .. code-block:: Python NSTEPS = 27 # Arbitrary units, steps INIT_VALUE = 5000 # Initial conditions INIT_STATION = 103 # HOSPITAL DEL PINO # Set constant value that will exit # the network in each step OUT_CONSTANT = 10 signal = np.zeros(len(W0)) signal[INIT_STATION] = INIT_VALUE .. GENERATED FROM PYTHON SOURCE LINES 106-120 .. code-block:: Python normalized_signal = signal / INIT_VALUE nodelist = [list(G)[INIT_STATION]] fig, ax = plt.subplots(figsize=(10, 7)) cmap = plt.get_cmap('viridis') colors = cmap(normalized_signal[signal > 0]) nx.draw_networkx_edges(G, pos, node_size=20, ax=ax) im = nx.draw_networkx_nodes(G, pos, node_color='gray', node_size=20, ax=ax) im = nx.draw_networkx_nodes(G, pos, node_color=colors, nodelist=nodelist, node_size=20, ax=ax) cbar = plt.colorbar(im, ax=ax, label='Number of people', ticks=[0, 0.5, 1]) cbar.set_ticklabels([0, (OUT_CONSTANT * 10) / 2, (OUT_CONSTANT * 10)]) plt.savefig('metro_simulation2/0.png') .. image-sg:: /examples/images/sphx_glr_metro_simulation2_001.png :alt: metro simulation2 :srcset: /examples/images/sphx_glr_metro_simulation2_001.png :class: sphx-glr-single-img .. GENERATED FROM PYTHON SOURCE LINES 121-209 .. code-block:: Python visited_stations = [INIT_STATION] mask = np.ones_like(W0) W = W0 * mask # People that leave the # metro network in each station left = np.zeros_like(signal) for it in np.arange(1, NSTEPS): # Compute signal in new step signal = (W @ D_inv @ signal).astype(int) # Eliminate connections of visited stations mask[visited_stations, :] = 0 mask[:, visited_stations] = 0 W = W0 * mask # Check if people reached a terminal station stations2empty = np.intersect1d(np.where(signal)[0], terminal_stations) # Check if people reached a station that has no connections stations2empty2 = np.intersect1d(np.where(signal > 0)[0], np.where(W.sum(1) == 0)[0]) if stations2empty.size > 0: print(f'It {it}: Emptying terminal stations') for i in stations2empty: print(f'\t{signal[i]} unboarded {stations[i]}') left[i] += signal[i] signal[i] -= signal[i] elif stations2empty2.size > 0: print(f'It {it}: Emptying encountered stations') for i in stations2empty2: print(f'\t{signal[i]} unboarded {stations[i]}') left[i] += signal[i] signal[i] -= signal[i] # Check if there is enough people to get out, otherwise # empty the station if np.all(signal[np.where(signal)[0]] > OUT_CONSTANT): for i in np.where(signal > 0)[0]: left[i] += OUT_CONSTANT signal[i] -= OUT_CONSTANT else: print(f'It {it}: Emptying stations') for i in np.where(np.logical_and(signal > 0, signal < OUT_CONSTANT))[0]: print(f'\t{signal[i]} unboarded {stations[i]}') left[i] += signal[i] signal[i] -= signal[i] for i in np.where(signal > 0)[0]: left[i] += OUT_CONSTANT signal[i] -= OUT_CONSTANT current_station = np.where(signal > 0)[0] nodelist = [list(G)[i] for i in current_station] nodelist2 = [list(G)[i] for i in np.where(left)[0]] normalized_signal = signal / INIT_VALUE colors = cmap(normalized_signal[signal > 0]) normalized_left = left / (OUT_CONSTANT * 10) colors2 = cmap(normalized_left[left > 0]) # Update visited stations list for i in np.where(signal)[0]: visited_stations.append(i) fig, ax = plt.subplots(figsize=(10, 7)) nx.draw_networkx_edges(G, pos, node_size=20, ax=ax) im = nx.draw_networkx_nodes(G, pos, node_color='gray', node_size=20, ax=ax) im = nx.draw_networkx_nodes(G, pos, node_color=colors2, nodelist=nodelist2, node_size=20, ax=ax) im = nx.draw_networkx_nodes(G, pos, node_color=colors, nodelist=nodelist, node_size=20, ax=ax, node_shape='o', edgecolors='red') cbar = plt.colorbar(im, ax=ax, label='Number of people', ticks=[0, 0.5, 1]) cbar.set_ticklabels([0, (OUT_CONSTANT * 10) / 2, (OUT_CONSTANT * 10)]) plt.savefig(f'metro_simulation2/{it}.png') plt.close() # fig.clf() if (np.sum(signal) == 0) or (np.sum(left) == INIT_VALUE): print(f'It {it}: Finished...') break .. rst-class:: sphx-glr-script-out .. code-block:: none It 15: Emptying terminal stations 780 unboarded Cerrillos It 16: Emptying encountered stations 802 unboarded Carlos Valdovinos It 17: Emptying terminal stations 381 unboarded Fernando Castillo Velasco It 18: Emptying encountered stations 371 unboarded Chile España 70 unboarded Villa Frei It 19: Emptying terminal stations 522 unboarded Plaza de Puente Alto It 20: Emptying encountered stations 27 unboarded Manuel Montt 88 unboarded Universidad Católica 7 unboarded Santa Lucía 361 unboarded Cristóbal Colón It 20: Emptying stations It 21: Emptying stations 3 unboarded Cementerios 3 unboarded Conchalí It 24: Emptying stations It 25: Emptying encountered stations 173 unboarded Neptuno It 25: Finished... .. rst-class:: sphx-glr-timing **Total running time of the script:** (0 minutes 2.964 seconds) **Estimated memory usage:** 178 MB .. _sphx_glr_download_examples_metro_simulation2.py: .. only:: html .. container:: sphx-glr-footer sphx-glr-footer-example .. container:: sphx-glr-download sphx-glr-download-jupyter :download:`Download Jupyter notebook: metro_simulation2.ipynb ` .. container:: sphx-glr-download sphx-glr-download-python :download:`Download Python source code: metro_simulation2.py ` .. container:: sphx-glr-download sphx-glr-download-zip :download:`Download zipped: metro_simulation2.zip ` .. only:: html .. rst-class:: sphx-glr-signature `Gallery generated by Sphinx-Gallery `_