This page was generated from docsrc/notebooks/network-spatial-weights.ipynb. Interactive online version: Binder badge


If any part of this notebook is used in your research, please cite with the reference found in README.md.


Network spatial weights

Plotting demonstration of network arc contiguity in spaghetti

Author: James D. Gaboardi jgaboardi@gmail.com

This notebook demonstrates plotting for the following:

  1. A basic geometric object (triangle) represented as a network

  2. A regular lattice

  3. An empirical example

[1]:
%load_ext watermark
%watermark
2020-05-02T21:44:39-04:00

CPython 3.7.3
IPython 7.10.2

compiler   : Clang 9.0.0 (tags/RELEASE_900/final)
system     : Darwin
release    : 19.4.0
machine    : x86_64
processor  : i386
CPU cores  : 4
interpreter: 64bit
[2]:
import geopandas
import libpysal
from libpysal.cg import Point, Chain
import matplotlib
import matplotlib.pyplot as plt
import spaghetti
%matplotlib inline
%watermark -w
%watermark -iv
watermark 2.0.2
matplotlib 3.1.2
geopandas  0.7.0
libpysal   4.2.2
spaghetti  1.5.0.rc0

[3]:
try:
    from IPython.display import set_matplotlib_formats
    set_matplotlib_formats("retina")
except ImportError:
    pass

Helper function for plotting weights

[4]:
def plot_weights(_ntw, _arcs_df, _base):
    """Plot network arc spatial weights."""
    node_kws, edge_kws = {"s":100, "zorder":2}, {"zorder":1}
    w_kws = {"edge_kws":edge_kws, "node_kws":node_kws}
    _ntw.w_network.plot(_arcs_df, indexed_on="id", ax=_base, **w_kws)

Helper functions for arc and vertex labeling

[5]:
def arc_labels(a, b, s, offset=[0.035, 0.0]):
    """Label each network arc."""
    def _lab_loc(_x):
        """Helper for labeling network arcs."""
        xy = _x.geometry.interpolate(0.5, normalized=True).coords[0]
        xy = tuple([_xy+o for (_xy,o) in zip(xy,offset)])
        return xy
    kws = {"ha":"left", "va":"bottom","weight":"bold","color":"k","size":s}
    a.apply(lambda x: b.annotate(s=x.id, xy=_lab_loc(x), **kws), axis=1)

def vert_labels(v, b, s, offset=[0.025, 0.025]):
    """Label each network vertex."""
    def _lab_loc(_x):
        """Internal helper for labeling vertices."""
        xy = _x.geometry.coords[0]
        xy = tuple([_xy+o for (_xy,o) in zip(xy,offset)])
        return xy
    kws = {"ha":"left", "va":"bottom","weight":"bold","color":"r","size":s}
    v.apply(lambda x: b.annotate(s=x.id, xy=_lab_loc(x), **kws), axis=1)

1. Triangle

Generate a spaghetti.Network and plot

[6]:
triangle = [
    Chain([Point([0, 0]), Point([0, 3])]),
    Chain([Point([0, 3]), Point([4, 0])]),
    Chain([Point([4, 0]), Point([0, 0])]),
]
triangle
[6]:
[<libpysal.cg.shapes.Chain at 0x12724c1d0>,
 <libpysal.cg.shapes.Chain at 0x12724c278>,
 <libpysal.cg.shapes.Chain at 0x12724c400>]
[7]:
ntw = spaghetti.Network(in_data=triangle)
vertices_df, arcs_df = spaghetti.element_as_gdf(ntw, vertices=True, arcs=True)
[8]:
base_kws = {"figsize":(12, 12), "lw":5, "color":"k", "zorder":0}
base = arcs_df.plot(**base_kws, alpha=.35)
vertices_df.plot(ax=base, fc="r", ec="k", markersize=50, zorder=2)
# arc labels
arc_labels(arcs_df, base, 12)
# vertex labels
vert_labels(vertices_df, base, 14)
../_images/notebooks_network-spatial-weights_11_0.png

An arc-based spatial weights attribute is generated with network instantiaton—w_network.

[9]:
ntw.w_network
[9]:
<libpysal.weights.weights.W at 0x12722a438>
[10]:
print(dir(ntw.w_network))
['_W__get_id_order', '_W__neighbors_0', '_W__set_id_order', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_build_sparse', '_cache', '_cardinalities', '_component_labels', '_id2i', '_id_order', '_id_order_set', '_n', '_n_components', '_reset', '_sparse', '_transform', 'asymmetries', 'asymmetry', 'cardinalities', 'component_labels', 'diagW2', 'diagWtW', 'diagWtW_WW', 'from_WSP', 'from_adjlist', 'from_file', 'from_networkx', 'from_shapefile', 'full', 'get_transform', 'histogram', 'id2i', 'id_order', 'id_order_set', 'islands', 'max_neighbors', 'mean_neighbors', 'min_neighbors', 'n', 'n_components', 'neighbor_offsets', 'neighbors', 'nonzero', 'pct_nonzero', 'plot', 'remap_ids', 's0', 's1', 's2', 's2array', 'sd', 'set_shapefile', 'set_transform', 'silence_warnings', 'sparse', 'symmetrize', 'to_WSP', 'to_adjlist', 'to_networkx', 'transform', 'transformations', 'trcW2', 'trcWtW', 'trcWtW_WW', 'weights']

The plot() method in the libpysal.weights.W class can be used along with a geopandas.GeoDataFrame to visualize contiguity.

[11]:
base = arcs_df.plot(**base_kws, alpha=.35)
plot_weights(ntw, arcs_df, base)
vertices_df.plot(ax=base, fc="r", ec="k", markersize=50, zorder=2)
# arc labels
arc_labels(arcs_df, base, 12)
# vertex labels
vert_labels(vertices_df, base, 14)
../_images/notebooks_network-spatial-weights_16_0.png

2. Regular lattice

Generate a spaghetti.Network from a 4x4 regular lattice and plot

[12]:
lattice = spaghetti.regular_lattice((0,0,3,3), 2, exterior=True)
ntw = spaghetti.Network(in_data=lattice)
[13]:
vertices_df, arcs_df = spaghetti.element_as_gdf(ntw, vertices=True, arcs=True)
[14]:
base = arcs_df.plot(**base_kws, alpha=.35)
plot_weights(ntw, arcs_df, base)
vertices_df.plot(ax=base, fc="r", ec="k", markersize=50, zorder=2)
# arc labels
arc_labels(arcs_df, base, 12)
# vertex labels
vert_labels(vertices_df, base, 14)
plt.xlim(-0.25, 3.5);
../_images/notebooks_network-spatial-weights_20_0.png

Plot only the arc weights

[15]:
base = arcs_df.plot(**base_kws, alpha=.0)
plot_weights(ntw, arcs_df, base)
arc_labels(arcs_df, base, 12)
plt.xlim(-0.25, 3.5);
../_images/notebooks_network-spatial-weights_22_0.png

3. Emprical Example — geodanet/streets.shp

Read in a libpysal.example and create a spaghetti.Network, then plot.

[16]:
ntw = spaghetti.Network(in_data=libpysal.examples.get_path("streets.shp"))
[17]:
vertices_df, arcs_df = spaghetti.element_as_gdf(ntw, vertices=True, arcs=True)
[18]:
base = arcs_df.plot(**base_kws, alpha=.35)
vertices_df.plot(ax=base, fc="r", ec="k", markersize=50, zorder=2);
../_images/notebooks_network-spatial-weights_26_0.png
[19]:
base = arcs_df.plot(**base_kws, alpha=.35)
plot_weights(ntw, arcs_df, base)
vertices_df.plot(ax=base, fc="r", ec="k", markersize=50, zorder=2);
../_images/notebooks_network-spatial-weights_27_0.png
[20]:
base = arcs_df.plot(**base_kws, alpha=.0)
plot_weights(ntw, arcs_df, base)
../_images/notebooks_network-spatial-weights_28_0.png