Note
Go to the end to download the full example code.
Network skimming#
In this example, we show how to perform network skimming for Coquimbo, a city in La Serena Metropolitan Area in Chile.
See also
Several functions, methods, classes and modules are used in this example:
# Imports
from uuid import uuid4
from tempfile import gettempdir
from os.path import join
from aequilibrae.utils.create_example import create_example
# We create the example project inside our temp folder
fldr = join(gettempdir(), uuid4().hex)
project = create_example(fldr, "coquimbo")
import logging
import sys
When the project opens, we can tell the logger to direct all messages to the terminal as well
logger = project.logger
stdout_handler = logging.StreamHandler(sys.stdout)
formatter = logging.Formatter("%(asctime)s;%(levelname)s ; %(message)s")
stdout_handler.setFormatter(formatter)
logger.addHandler(stdout_handler)
Network Skimming#
import numpy as np
Let’s build all graphs
project.network.build_graphs()
# We get warnings that several fields in the project are filled with ``NaN``s.
# This is true, but we won't use those fields.
2025-01-15 19:54:25,030;WARNING ; Field(s) speed, travel_time, capacity, osm_id, lanes has(ve) at least one NaN value. Check your computations
2025-01-15 19:54:25,114;WARNING ; Field(s) speed, travel_time, capacity, osm_id, lanes has(ve) at least one NaN value. Check your computations
2025-01-15 19:54:25,218;WARNING ; Field(s) speed, travel_time, capacity, osm_id, lanes has(ve) at least one NaN value. Check your computations
2025-01-15 19:54:25,320;WARNING ; Field(s) speed, travel_time, capacity, osm_id, lanes has(ve) at least one NaN value. Check your computations
We grab the graph for cars
graph = project.network.graphs["c"]
# we also see what graphs are available
project.network.graphs.keys()
# let's say we want to minimize the distance
graph.set_graph("distance")
# And will skim distance while we are at it, other fields like ``free_flow_time`` or ``travel_time``
# can be added here as well
graph.set_skimming(["distance"])
# But let's say we only want a skim matrix for nodes 28-40, and 49-60 (inclusive),
# these happen to be a selection of western centroids.
graph.prepare_graph(np.array(list(range(28, 41)) + list(range(49, 91))))
2025-01-15 19:54:25,405;WARNING ; Field(s) speed, travel_time, capacity, osm_id, lanes has(ve) at least one NaN value. Check your computations
And run the skimming
skm = graph.compute_skims()
: 0%| | 0/55 [00:00<?, ?it/s]
1/55 : 2%|▏ | 1/55 [00:00<00:00, 296.84it/s]
2/55 : 4%|▎ | 2/55 [00:00<00:00, 545.57it/s]
3/55 : 5%|▌ | 3/55 [00:00<00:00, 761.68it/s]
4/55 : 7%|▋ | 4/55 [00:00<00:00, 957.33it/s]
5/55 : 9%|▉ | 5/55 [00:00<00:00, 1104.81it/s]
6/55 : 11%|█ | 6/55 [00:00<00:00, 1253.84it/s]
7/55 : 13%|█▎ | 7/55 [00:00<00:00, 1375.63it/s]
8/55 : 15%|█▍ | 8/55 [00:00<00:00, 1501.79it/s]
9/55 : 16%|█▋ | 9/55 [00:00<00:00, 1594.66it/s]
10/55 : 18%|█▊ | 10/55 [00:00<00:00, 1698.44it/s]
11/55 : 20%|██ | 11/55 [00:00<00:00, 1778.82it/s]
12/55 : 22%|██▏ | 12/55 [00:00<00:00, 1858.63it/s]
13/55 : 24%|██▎ | 13/55 [00:00<00:00, 1925.22it/s]
14/55 : 25%|██▌ | 14/55 [00:00<00:00, 2000.62it/s]
15/55 : 27%|██▋ | 15/55 [00:00<00:00, 2057.85it/s]
16/55 : 29%|██▉ | 16/55 [00:00<00:00, 2114.13it/s]
17/55 : 31%|███ | 17/55 [00:00<00:00, 2136.74it/s]
18/55 : 33%|███▎ | 18/55 [00:00<00:00, 2197.57it/s]
19/55 : 35%|███▍ | 19/55 [00:00<00:00, 2231.95it/s]
20/55 : 36%|███▋ | 20/55 [00:00<00:00, 2283.61it/s]
21/55 : 38%|███▊ | 21/55 [00:00<00:00, 2321.14it/s]
22/55 : 40%|████ | 22/55 [00:00<00:00, 2365.47it/s]
23/55 : 42%|████▏ | 23/55 [00:00<00:00, 2390.69it/s]
24/55 : 44%|████▎ | 24/55 [00:00<00:00, 2433.42it/s]
25/55 : 45%|████▌ | 25/55 [00:00<00:00, 2461.73it/s]
26/55 : 47%|████▋ | 26/55 [00:00<00:00, 2490.79it/s]
27/55 : 49%|████▉ | 27/55 [00:00<00:00, 2523.70it/s]
28/55 : 51%|█████ | 28/55 [00:00<00:00, 2559.01it/s]
29/55 : 53%|█████▎ | 29/55 [00:00<00:00, 2590.01it/s]
30/55 : 55%|█████▍ | 30/55 [00:00<00:00, 2615.12it/s]
31/55 : 56%|█████▋ | 31/55 [00:00<00:00, 2639.05it/s]
32/55 : 58%|█████▊ | 32/55 [00:00<00:00, 2658.72it/s]
33/55 : 60%|██████ | 33/55 [00:00<00:00, 2680.27it/s]
34/55 : 62%|██████▏ | 34/55 [00:00<00:00, 2693.99it/s]
35/55 : 64%|██████▎ | 35/55 [00:00<00:00, 2714.66it/s]
36/55 : 65%|██████▌ | 36/55 [00:00<00:00, 2731.56it/s]
37/55 : 67%|██████▋ | 37/55 [00:00<00:00, 2740.02it/s]
38/55 : 69%|██████▉ | 38/55 [00:00<00:00, 2754.97it/s]
39/55 : 71%|███████ | 39/55 [00:00<00:00, 2772.37it/s]
40/55 : 73%|███████▎ | 40/55 [00:00<00:00, 2789.65it/s]
41/55 : 75%|███████▍ | 41/55 [00:00<00:00, 2801.90it/s]
42/55 : 76%|███████▋ | 42/55 [00:00<00:00, 2815.15it/s]
43/55 : 78%|███████▊ | 43/55 [00:00<00:00, 2830.39it/s]
44/55 : 80%|████████ | 44/55 [00:00<00:00, 2839.31it/s]
45/55 : 82%|████████▏ | 45/55 [00:00<00:00, 2854.30it/s]
46/55 : 84%|████████▎ | 46/55 [00:00<00:00, 2865.39it/s]
47/55 : 85%|████████▌ | 47/55 [00:00<00:00, 2879.23it/s]
48/55 : 87%|████████▋ | 48/55 [00:00<00:00, 2890.21it/s]
49/55 : 89%|████████▉ | 49/55 [00:00<00:00, 2903.37it/s]
50/55 : 91%|█████████ | 50/55 [00:00<00:00, 2914.25it/s]
51/55 : 93%|█████████▎| 51/55 [00:00<00:00, 2923.02it/s]
52/55 : 95%|█████████▍| 52/55 [00:00<00:00, 2932.45it/s]
53/55 : 96%|█████████▋| 53/55 [00:00<00:00, 2950.76it/s]
54/55 : 98%|█████████▊| 54/55 [00:00<00:00, 2970.12it/s]
55/55 : 100%|██████████| 55/55 [00:00<00:00, 2994.03it/s]
Saving Outputs : 100%|██████████| 55/55 [00:00<00:00, 2898.51it/s]
Building network skims directly from the graph is more straightforward, though
we could alternatively use the class NetworkSkimming
to achieve the same result.
# from aequilibrae.paths import NetworkSkimming
# skm = NetworkSkimming(graph)
# skm.execute()
The result is an AequilibraEMatrix object
skims = skm.results.skims
# Which we can manipulate directly from its temp file, if we wish
skims.matrices[:3, :3, :]
array([[[ 0. ],
[4166.92919206],
[5532.32681478]],
[[3733.4499255 ],
[ 0. ],
[3311.30654014]],
[[5446.26074416],
[3596.12274848],
[ 0. ]]])
Or access each matrix, lets just look at the first 3x3
skims.distance[:3, :3]
array([[ 0. , 4166.92919206, 5532.32681478],
[3733.4499255 , 0. , 3311.30654014],
[5446.26074416, 3596.12274848, 0. ]])
We can save it to the project if we want
skm.save_to_project("base_skims")
2025-01-15 19:54:25,512;WARNING ; Matrix Record has been saved to the database
We can also retrieve this skim record to write something to its description
matrices = project.matrices
mat_record = matrices.get_record("base_skims")
mat_record.description = "minimized distance while also skimming distance for just a few nodes"
mat_record.save()
project.close()
Total running time of the script: (0 minutes 0.858 seconds)