Graph from arbitrary data#

In this example, we demonstrate how to create an AequilibraE Graph from an arbitrary network.

We are using Sioux Falls data, from TNTP.

See also

Several functions, methods, classes and modules are used in this example:

# Imports
import numpy as np
import pandas as pd

from aequilibrae.paths import Graph

We start by adding the path to load our arbitrary network.

net_file = "https://raw.githubusercontent.com/bstabler/TransportationNetworks/master/SiouxFalls/SiouxFalls_net.tntp"

Let’s read our data! We’ll be using Sioux Falls transportation network data, but without geometric information. The data will be stored in a Pandas DataFrame containing information about initial and final nodes, link distances, travel times, etc.

net = pd.read_csv(net_file, skiprows=8, sep="\t", lineterminator="\n", usecols=np.arange(1, 11))

The Graph object requires several default fields: link_id, a_node, b_node, and direction.

We need to manipulate the data to add the missing fields (link_id and direction) and rename the node columns accordingly.

net.insert(0, "link_id", np.arange(1, net.shape[0] + 1))
net = net.assign(direction=1)
net.rename(columns={"init_node": "a_node", "term_node": "b_node"}, inplace=True)

Now we can take a look in our network file

net.head()
link_id a_node b_node capacity length free_flow_time b power speed toll link_type direction
0 1 1 2 25900.200640 6 6 0.15 4 0 0 1 1
1 2 1 3 23403.473190 4 4 0.15 4 0 0 1 1
2 3 2 1 25900.200640 6 6 0.15 4 0 0 1 1
3 4 2 6 4958.180928 5 5 0.15 4 0 0 1 1
4 5 3 1 23403.473190 4 4 0.15 4 0 0 1 1


Building an AequilibraE graph from our network is pretty straightforward. We assign our network to be the graph’s network …

graph = Graph()
graph.network = net

… and then set the graph’s configurations.

graph.prepare_graph(np.arange(1, 25))  # sets the centroids for which we will perform computation

graph.set_graph("length")  # sets the cost field for path computation

graph.set_skimming(["length", "free_flow_time"]) # sets the skims to be computed

graph.set_blocked_centroid_flows(False)  # we don't block flows through centroids because all nodes
                                         # in the Sioux Falls network are centroids
Cost field with wrong type. Converting to float64

Two of AequilibraE’s new features consist in directly computing path or skims.

Let’s compute the path between nodes 1 and 17…

res = graph.compute_path(1, 17)

… and print the corresponding nodes…

res.path_nodes
array([ 1,  2,  6,  8, 16, 17])

… and the path links.

res.path
array([ 1,  4, 16, 22, 49])

For path computation, when we call the method graph.compute_path(1, 17), we are calling the class PathComputation and storing its results into a variable.

Notice that other methods related to path computation, such as milepost can also be used with res.

For skim computation, the process is quite similar. When calligng the method graph.compute_skims() we are actually calling the class NetworkSkimming, and storing its results into skm.

skm = graph.compute_skims()
                                                  :   0%|          | 0/24 [00:00<?, ?it/s]
1/24                                              :   4%|▍         | 1/24 [00:00<00:00, 563.98it/s]
2/24                                              :   8%|▊         | 2/24 [00:00<00:00, 1003.42it/s]
3/24                                              :  12%|█▎        | 3/24 [00:00<00:00, 1377.14it/s]
4/24                                              :  17%|█▋        | 4/24 [00:00<00:00, 1695.87it/s]
5/24                                              :  21%|██        | 5/24 [00:00<00:00, 1955.93it/s]
6/24                                              :  25%|██▌       | 6/24 [00:00<00:00, 2195.40it/s]
7/24                                              :  29%|██▉       | 7/24 [00:00<00:00, 2409.13it/s]
8/24                                              :  33%|███▎      | 8/24 [00:00<00:00, 2601.72it/s]
9/24                                              :  38%|███▊      | 9/24 [00:00<00:00, 2776.25it/s]
10/24                                             :  42%|████▏     | 10/24 [00:00<00:00, 2932.05it/s]
11/24                                             :  46%|████▌     | 11/24 [00:00<00:00, 3055.66it/s]
12/24                                             :  50%|█████     | 12/24 [00:00<00:00, 3184.74it/s]
13/24                                             :  54%|█████▍    | 13/24 [00:00<00:00, 3304.00it/s]
14/24                                             :  58%|█████▊    | 14/24 [00:00<00:00, 3414.96it/s]
15/24                                             :  62%|██████▎   | 15/24 [00:00<00:00, 3516.74it/s]
16/24                                             :  67%|██████▋   | 16/24 [00:00<00:00, 3610.14it/s]
17/24                                             :  71%|███████   | 17/24 [00:00<00:00, 3679.59it/s]
18/24                                             :  75%|███████▌  | 18/24 [00:00<00:00, 3760.77it/s]
19/24                                             :  79%|███████▉  | 19/24 [00:00<00:00, 3836.87it/s]
20/24                                             :  83%|████████▎ | 20/24 [00:00<00:00, 3909.13it/s]
21/24                                             :  88%|████████▊ | 21/24 [00:00<00:00, 3977.98it/s]
22/24                                             :  92%|█████████▏| 22/24 [00:00<00:00, 4040.58it/s]
23/24                                             :  96%|█████████▌| 23/24 [00:00<00:00, 4081.27it/s]
24/24                                             : 100%|██████████| 24/24 [00:00<00:00, 4135.54it/s]
Saving Outputs                                    : 100%|██████████| 24/24 [00:00<00:00, 3772.14it/s]

Let’s get the values for ‘free_flow_time’ matrix.

skims = skm.results.skims
skims.get_matrix("free_flow_time")
array([[ 0.,  6.,  4.,  8., 10., 11., 16., 13., 15., 18., 14.,  8., 11.,
        18., 23., 18., 20., 18., 22., 22., 18., 20., 17., 15.],
       [ 6.,  0., 10., 11.,  9.,  5., 10.,  7., 14., 16., 17., 14., 17.,
        21., 19., 12., 14., 12., 16., 16., 22., 21., 23., 21.],
       [ 4., 10.,  0.,  4.,  6., 10., 15., 12., 11., 14., 10.,  4.,  7.,
        14., 19., 17., 19., 17., 21., 20., 14., 16., 13., 11.],
       [ 8., 11.,  4.,  0.,  2.,  6., 11.,  8.,  7., 10.,  6.,  8., 11.,
        10., 15., 13., 15., 13., 17., 17., 18., 18., 14., 15.],
       [10.,  9.,  6.,  2.,  0.,  4.,  9.,  6.,  5.,  8.,  8., 10., 13.,
        12., 14., 11., 13., 11., 15., 15., 19., 17., 16., 17.],
       [11.,  5., 10.,  6.,  4.,  0.,  5.,  2.,  9., 11., 12., 14., 17.,
        16., 14.,  7.,  9.,  7., 11., 11., 17., 16., 20., 20.],
       [16., 10., 15., 11.,  9.,  5.,  0.,  3., 12.,  9., 14., 19., 19.,
        17., 12.,  5.,  7.,  2.,  9.,  6., 12., 11., 15., 15.],
       [13.,  7., 12.,  8.,  6.,  2.,  3.,  0., 10.,  9., 14., 16., 19.,
        17., 12.,  5.,  7.,  5.,  9.,  9., 15., 14., 18., 18.],
       [15., 14., 11.,  7.,  5.,  9., 12., 10.,  0.,  3.,  8., 14., 17.,
        12.,  9.,  7.,  9., 10., 11., 14., 14., 12., 16., 17.],
       [18., 16., 14., 10.,  8., 11.,  9.,  9.,  3.,  0.,  5., 11., 14.,
         9.,  6.,  4.,  6.,  7.,  8., 11., 11.,  9., 13., 14.],
       [14., 17., 10.,  6.,  8., 12., 14., 14.,  8.,  5.,  0.,  6.,  9.,
         4.,  9.,  9., 11., 12., 12., 16., 13., 12.,  8., 10.],
       [ 8., 14.,  4.,  8., 10., 14., 19., 16., 14., 11.,  6.,  0.,  3.,
        10., 15., 15., 17., 18., 18., 16., 10., 12.,  9.,  7.],
       [11., 17.,  7., 11., 13., 17., 19., 19., 17., 14.,  9.,  3.,  0.,
        10., 12., 18., 17., 17., 15., 13.,  7.,  9.,  6.,  4.],
       [18., 21., 14., 10., 12., 16., 17., 17., 12.,  9.,  4., 10., 10.,
         0.,  5., 12., 10., 15.,  8., 12.,  9.,  8.,  4.,  6.],
       [23., 19., 19., 15., 14., 14., 12., 12.,  9.,  6.,  9., 15., 12.,
         5.,  0.,  7.,  5., 10.,  3.,  7.,  5.,  3.,  7.,  8.],
       [18., 12., 17., 13., 11.,  7.,  5.,  5.,  7.,  4.,  9., 15., 18.,
        12.,  7.,  0.,  2.,  3.,  4.,  7., 12., 10., 14., 15.],
       [20., 14., 19., 15., 13.,  9.,  7.,  7.,  9.,  6., 11., 17., 17.,
        10.,  5.,  2.,  0.,  5.,  2.,  6., 10.,  8., 12., 13.],
       [18., 12., 17., 13., 11.,  7.,  2.,  5., 10.,  7., 12., 18., 17.,
        15., 10.,  3.,  5.,  0.,  7.,  4., 10.,  9., 13., 13.],
       [22., 16., 21., 17., 15., 11.,  9.,  9., 11.,  8., 12., 18., 15.,
         8.,  3.,  4.,  2.,  7.,  0.,  4.,  8.,  6., 10., 11.],
       [22., 16., 20., 17., 15., 11.,  6.,  9., 14., 11., 16., 16., 13.,
        12.,  7.,  7.,  6.,  4.,  4.,  0.,  6.,  5.,  9.,  9.],
       [18., 22., 14., 18., 19., 17., 12., 15., 14., 11., 13., 10.,  7.,
         9.,  5., 12., 10., 10.,  8.,  6.,  0.,  2.,  5.,  3.],
       [20., 21., 16., 18., 17., 16., 11., 14., 12.,  9., 12., 12.,  9.,
         8.,  3., 10.,  8.,  9.,  6.,  5.,  2.,  0.,  4.,  5.],
       [17., 23., 13., 14., 16., 20., 15., 18., 16., 13.,  8.,  9.,  6.,
         4.,  7., 14., 12., 13., 10.,  9.,  5.,  4.,  0.,  2.],
       [15., 21., 11., 15., 17., 20., 15., 18., 17., 14., 10.,  7.,  4.,
         6.,  8., 15., 13., 13., 11.,  9.,  3.,  5.,  2.,  0.]])

Now we’re all set!

Graph image credits to Behance-network icons created by Sumitsaengtong - Flaticon

Total running time of the script: (0 minutes 0.375 seconds)

Gallery generated by Sphinx-Gallery