cityseer.metrics.networks

Cityseer network module for creating networks and calculating network centralities.

There are two network centrality methods available depending on whether you’re using a node-based or segment-based approach:

These methods wrap the underlying numba optimised functions for computing centralities, and provides access to all of the underlying node-based or segment-based centrality methods. Multiple selected measures and distances are computed simultaneously to reduce the amount of time required for multi-variable and multi-scalar strategies.

See the accompanying paper on arXiv for additional information about methods for computing centrality measures.

The reasons for picking one approach over another are varied:

  • Node based centralities compute the measures relative to each reachable node within the threshold distances. For this reason, they can be susceptible to distortions caused by messy graph topologies such redundant and varied concentrations of degree=2 nodes (e.g. to describe roadway geometry) or needlessly complex representations of street intersections. In these cases, the network should first be cleaned using methods such as those available in the graph module (see the graph cleaning guide for examples/). If a network topology has varied intensities of nodes but the street segments are less spurious, then segmentised methods can be preferable because they are based on segment distances: segment aggregations remain the same regardless of the number of intervening nodes, however, are not immune from situations such as needlessly complex representations of roadway intersections or a proliferation of walking paths in greenspaces;
  • Node-based harmonic centrality can be problematic on graphs where nodes are erroneously placed too close together or where impedances otherwise approach zero, as may be the case for simplest-path measures or small distance thesholds. This happens because the outcome of the division step can balloon towards \infty once impedances decrease below 1.
  • Note that cityseer’s implementation of simplest (angular) measures work on both primal (node or segment based) and dual graphs (node only).
  • Measures should only be directly compared on the same topology because different topologies can otherwise affect the expression of a measure. Accordingly, measures computed on dual graphs cannot be compared to measures computed on primal graphs because this does not account for the impact of differing topologies. Dual graph representations can have substantially greater numbers of nodes and edges for the same underlying street network; for example, a four-way intersection consisting of one node with four edges translates to four nodes and six edges on the dual. This effect is amplified for denser regions of the network.
  • Segmentised versions of centrality measures should not be computed on dual graph topologies because street segment lengths would be duplicated for each permutation of dual edge spanning street intersections. By way of example, the contribution of a single edge segment at a four-way intersection would be duplicated three times.
  • Global closeness is strongly discouraged because it does not behave suitably for localised graphs. Harmonic closeness or improved closeness should be used instead. Note that Global closeness (nodesfarness\frac{nodes}{farness}) and improved closeness (nodesfarness/nodes\frac{nodes}{farness / nodes}) can be recovered from the available metrics, if so desired, through additional (manual) steps.
  • Network decomposition can be a useful strategy when working at small distance thresholds, and confers advantages such as more regularly spaced snapshots and fewer artefacts at small distance thresholds where street edges intersect distance thresholds. However, the regular spacing of the decomposed segments will introduce spikes in the distributions of node-based centrality measures when working at very small distance thresholds. Segmentised versions may therefore be preferable when working at small thresholds on decomposed networks.

distance_from_beta

distance_from_beta(
beta,
min_threshold_wt=0.01831563888873418)

Map decay parameters β\beta to equivalent distance thresholds dmaxd_{max} at the specified cutoff weight wminw_{min}.

It is generally not necessary to utilise this function directly.

Parameters

beta
float | ndarray[float]

β\beta value/s to convert to distance thresholds dmaxd_{max}.

min_threshold_wt
float

An optional cutoff weight wminw_{min} at which to set the distance threshold dmaxd_{max}, default of 0.01831563888873418.

Returns

betas
ndarray[float]

A numpy array of distance thresholds dmaxd_{max}.

Notes

from cityseer.metrics import networks
# a list of betas
betas = [0.01, 0.02]
# convert to distance thresholds
d_max = networks.distance_from_beta(betas)
print(d_max)
# prints: array([400., 200.])

Weighted measures such as the gravity index, weighted betweenness, and weighted land-use accessibilities are computed using a negative exponential decay function in the form of:

weight=exp(βdistance)weight = exp(-\beta \cdot distance)

The strength of the decay is controlled by the β\beta parameter, which reflects a decreasing willingness to walk correspondingly farther distances. For example, if β=0.005\beta=0.005 were to represent a person’s willingness to walk to a bus stop, then a location 100m distant would be weighted at 60% and a location 400m away would be weighted at 13.5%. After an initially rapid decrease, the weightings decay ever more gradually in perpetuity; thus, once a sufficiently small weight is encountered it becomes computationally expensive to consider locations any farther away. The minimum weight at which this cutoff occurs is represented by wminw_{min}, and the corresponding maximum distance threshold by dmaxd_{max}.

Example beta decays

Most networks module methods can be invoked with either distances or betas parameters, but not both. If using the betas parameter, then this function will be called in order to extrapolate the distance thresholds implicitly, using:

dmax=log(wmin)βd_{max} = \frac{log(w_{min})}{-\beta}

The default min_threshold_wt of wmin=0.01831563888873418w_{min}=0.01831563888873418 yields conveniently rounded dmaxd_{max} walking thresholds, for example:

β\betadmaxd_{max}
0.02200m
0.01400m
0.005800m
0.00251600m

Overriding the default wminw_{min} will adjust the dmaxd_{max} accordingly, for example:

β\betawminw_{min}dmaxd_{max}
0.020.01230m
0.010.01461m
0.0050.01921m
0.00250.011842m

beta_from_distance

beta_from_distance(
distance,
min_threshold_wt=0.01831563888873418)

Map distance thresholds dmaxd_{max} to equivalent decay parameters β\beta at the specified cutoff weight wminw_{min}. See distance_from_beta for additional discussion.

It is generally not necessary to utilise this function directly.

Parameters

distance
int | ndarray[int]

dmaxd_{max} value/s to convert to decay parameters β\beta.

min_threshold_wt
float

The cutoff weight wminw_{min} on which to model the decay parameters β\beta, default of 0.01831563888873418.

Returns

ndarray[float]

A numpy array of decay parameters β\beta.

Notes

from cityseer.metrics import networks
# a list of betas
distances = [400, 200]
# convert to betas
betas = networks.beta_from_distance(distances)
print(betas)  # prints: array([0.01, 0.02])

Most networks module methods can be invoked with either distances or betas parameters, but not both. If using the distances parameter, then this function will be called in order to extrapolate the decay parameters implicitly, using:

β=log(wmin)dmax\beta = -\frac{log(w_{min})}{d_{max}}

The default min_threshold_wt of wmin=0.01831563888873418w_{min}=0.01831563888873418 yields conveniently rounded β\beta parameters, for example:

dmaxd_{max}β\beta
200m0.02
400m0.01
800m0.005
1600m0.0025

avg_distance_for_beta

avg_distance_for_beta(
beta,
min_threshold_wt=0.01831563888873418)

Calculate the mean distance for a given β\beta parameter.

Parameters

beta
float | ndarray[float]

β\beta representing a spatial impedance / distance decay for which to compute the average walking distance.

min_threshold_wt
float

The cutoff weight wminw_{min} on which to model the decay parameters β\beta, default of 0.01831563888873418.

Returns

ndarray[float]

The average walking distance for a given β\beta.

Notes

from cityseer.metrics import networks
import numpy as np

distances = np.array([100, 200, 400, 800, 1600])
print('distances', distances)
# distances [ 100  200  400  800 1600]

betas = networks.beta_from_distance(distances)
print('betas', betas)
# betas [0.04   0.02   0.01   0.005  0.0025]

print('avg', networks.avg_distance_for_beta(betas))
# avg [ 35.11949  70.23898 140.47797 280.95593 561.91187]

pair_distances_betas

pair_distances_betas(
distances,
betas,
min_threshold_wt=0.01831563888873418)

Pair distances and betas, where one or the other parameter is provided.

Parameters

distances
list[int] | tuple[int]

Distances corresponding to the local dmaxd_{max} thresholds to be used for calculations. The β\beta parameters (for distance-weighted metrics) will be determined implicitly. If the distances parameter is not provided, then the beta parameter must be provided instead. By default None.

betas
float | ndarray[float]

A β\beta, or array of β\beta to be used for the exponential decay function for weighted metrics. The distance parameters for unweighted metrics will be determined implicitly. If the betas parameter is not provided, then the distance parameter must be provided instead. By default None.

min_threshold_wt
float

The default min_threshold_wt parameter can be overridden to generate custom mappings between the distance and beta parameters. See distance_from_beta for more information.

Returns

distances
list[int] | tuple[int]

Distances corresponding to the local dmaxd_{max} thresholds to be used for calculations. The β\beta parameters (for distance-weighted metrics) will be determined implicitly. If the distances parameter is not provided, then the beta parameter must be provided instead. By default None.

betas
float | ndarray[float]

A β\beta, or array of β\beta to be used for the exponential decay function for weighted metrics. The distance parameters for unweighted metrics will be determined implicitly. If the betas parameter is not provided, then the distance parameter must be provided instead. By default None.

Notes

It is possible to represent unlimited dmaxd_{max} distance thresholds by setting one of the specified distance parameter values to np.inf. Note that this may substantially increase the computational time required for the completion of the algorithms on large networks.

Networks should be buffered according to the largest distance threshold that will be used for analysis. This protects nodes near network boundaries from edge falloffs. Nodes outside the area of interest but within these buffered extents should be set to ‘dead’ so that centralities or other forms of measures are not calculated. Whereas metrics are not calculated for ‘dead’ nodes, they can still be traversed by network analysis algorithms when calculating shortest paths and landuse accessibilities.

node_centrality

node_centrality(
measures,
network_structure,
nodes_gdf,
distances,
betas,
jitter_scale=0.0,
angular=False,
min_threshold_wt=0.01831563888873418)

Compute node-based network centrality.

Parameters

measures
tuple[str]

A tuple of centrality measures to compute. Centrality keys can be selected from the available centrality measure key values in the table beneath. Each centrality measure will be computed for all distance thresholds dmaxd_{max}.

network_structure
None
nodes_gdf
None

A GeoDataFrame representing nodes. Best generated with the graphs.network_structure_from_nx method. The outputs of calculations will be written to this GeoDataFrame, which is then returned from the method.

distances
list[int] | tuple[int]

Distances corresponding to the local dmaxd_{max} thresholds to be used for calculations. The β\beta parameters (for distance-weighted metrics) will be determined implicitly. If the distances parameter is not provided, then the beta parameter must be provided instead. By default None.

betas
float | ndarray[float]

A β\beta, or array of β\beta to be used for the exponential decay function for weighted metrics. The distance parameters for unweighted metrics will be determined implicitly. If the betas parameter is not provided, then the distance parameter must be provided instead. By default None.

jitter_scale
float

The scale of random jitter to add to shortest path calculations, useful for situations with highly rectilinear grids. jitter_scale is passed to the scale parameter of np.random.normal. Default of zero.

angular
bool

Whether to use a simplest-path heuristic in-lieu of a shortest-path heuristic when calculating aggregations and distances. By default False.

min_threshold_wt
float

The default min_threshold_wt parameter can be overridden to generate custom mappings between the distance and beta parameters. See distance_from_beta for more information.

Returns

nodes_gdf
GeoDataFrame

The input node_gdf parameter is returned with additional columns populated with the calcualted metrics.

Notes

The following keys use the shortest-path heuristic, and are available when the angular parameter is set to the default value of False:

keyformulanotes
node_densityjin1\sum_{j\neq{i}}^{n}1A summation of nodes.
node_farnessjind(i,j)\sum_{j\neq{i}}^{n}d_{(i,j)}A summation of distances in metres.
node_cyclesjij=cyclen1\sum_{j\neq{i}j=cycle}^{n}1A summation of network cycles.
node_harmonicjin1Z(i,j)\sum_{j\neq{i}}^{n}\frac{1}{Z_{(i,j)}}Harmonic closeness is an appropriate form of closeness centrality for localised implementations constrained by the threshold dmaxd_{max}.
node_betajinexp(βd[i,j])\sum_{j\neq{i}}^{n}\exp(-\beta\cdot d[i,j])Also known as the gravity index. This is a spatial impedance metric differentiated from other closeness centralities by the use of an explicit β\beta parameter, which can be used to model the decay in walking tolerance as distances increase.
node_betweennessjinkjin1\sum_{j\neq{i}}^{n}\sum_{k\neq{j}\neq{i}}^{n}1Betweenness centrality summing all shortest-paths traversing each node ii.
node_betweenness_betajinkjinexp(βd[j,k])\sum_{j\neq{i}}^{n}\sum_{k\neq{j}\neq{i}}^{n}\exp(-\beta\cdot d[j,k])Applies a spatial impedance decay function to betweenness centrality. dd represents the full distance from any jj to kk node pair passing through node ii.

The following keys use the simplest-path (shortest-angular-path) heuristic, and are available when the angular parameter is explicitly set to True:

keyformulanotes
node_harmonic_angularjin1Z(i,j)\sum_{j\neq{i}}^{n}\frac{1}{Z_{(i,j)}}The simplest-path implementation of harmonic closeness uses angular-distances for the impedance parameter. Angular-distances are normalised by 180 and added to 1 to avoid division by zero: Z=1+(angularchange/180){Z = 1 + (angularchange/180)}.
node_betweenness_angularjinkjin1\sum_{j\neq{i}}^{n}\sum_{k\neq{j}\neq{i}}^{n}1The simplest-path version of betweenness centrality. This is distinguished from the shortest-path version by use of a simplest-path heuristic (shortest angular distance).

segment_centrality

segment_centrality(
measures,
network_structure,
nodes_gdf,
distances,
betas,
jitter_scale=0.0,
angular=False,
min_threshold_wt=0.01831563888873418)

Compute segment-based network centrality.

Parameters

measures
tuple[str]

A tuple of centrality measures to compute. Centrality keys can be selected from the available centrality measure key values in the table beneath. Each centrality measure will be computed for all distance thresholds dmaxd_{max}.

network_structure
None
nodes_gdf
None

A GeoDataFrame representing nodes. Best generated with the graphs.network_structure_from_nx method. The outputs of calculations will be written to this GeoDataFrame, which is then returned from the method.

distances
list[int] | tuple[int]

Distances corresponding to the local dmaxd_{max} thresholds to be used for calculations. The β\beta parameters (for distance-weighted metrics) will be determined implicitly. If the distances parameter is not provided, then the beta parameter must be provided instead. By default None.

betas
float | ndarray[float]

A β\beta, or array of β\beta to be used for the exponential decay function for weighted metrics. The distance parameters for unweighted metrics will be determined implicitly. If the betas parameter is not provided, then the distance parameter must be provided instead. By default None.

jitter_scale
float

The scale of random jitter to add to shortest path calculations, useful for situations with highly rectilinear grids. jitter_scale is passed to the scale parameter of np.random.normal. Default of zero.

angular
bool

Whether to use a simplest-path heuristic in-lieu of a shortest-path heuristic when calculating aggregations and distances. By default False.

min_threshold_wt
float

The default min_threshold_wt parameter can be overridden to generate custom mappings between the distance and beta parameters. See distance_from_beta for more information.

Returns

nodes_gdf
GeoDataFrame

The input node_gdf parameter is returned with additional columns populated with the calcualted metrics.

Notes

The following keys use the shortest-path heuristic, and are available when the angular parameter is set to the default value of False:

keyformulanotes
segment_density(a,b)edgesdbda\sum_{(a, b)}^{edges}d_{b} - d_{a}A summation of edge lengths.
segment_harmonic(a,b)edgesabln(b)ln(a)\sum_{(a, b)}^{edges}\int_{a}^{b}\ln(b) -\ln(a)A continuous form of harmonic closeness centrality applied to edge lengths.
segment_beta(a,b)edgesabexp(βb)exp(βa)β\sum_{(a, b)}^{edges}\int_{a}^{b}\frac{\exp(-\beta\cdot b) -\exp(-\beta\cdot a)}{-\beta}A # pylint: disable=line-too-long continuous form of beta-weighted (gravity index) centrality applied to edge lengths.
segment_betweennessA continuous form of betweenness: Resembles segment_beta applied to edges situated on shortest paths between all nodes jj and kk passing through ii.

The following keys use the simplest-path (shortest-angular-path) heuristic, and are available when the angular parameter is explicitly set to True.

keyformulanotes
segment_harmonic_hybrid(a,b)edgesdbdaZ\sum_{(a, b)}^{edges}\frac{d_{b} - d_{a}}{Z}Weights angular harmonic centrality by the lengths of the edges. See node_harmonic_angular.
segment_betweeness_hybridA continuous form of angular betweenness: Resembles segment_harmonic_hybrid applied to edges situated on shortest paths between all nodes jj and kk passing through ii.