#!/usr/bin/env python # coding: utf-8 # --------------- # # **If any part of this notebook is used in your research, please cite with the reference found in** **[README.md](https://github.com/pysal/spaghetti#bibtex-citation).** # # # ---------------- # ## Network spatial weights # ### Plotting demonstration of network arc contiguity in `spaghetti` # # **Author: James D. Gaboardi** **** # # **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 # In[1]: get_ipython().run_line_magic('load_ext', 'watermark') get_ipython().run_line_magic('watermark', '') # In[2]: import geopandas import libpysal from libpysal.cg import Point, Chain import matplotlib import matplotlib.pyplot as plt import spaghetti get_ipython().run_line_magic('matplotlib', 'inline') get_ipython().run_line_magic('watermark', '-w') get_ipython().run_line_magic('watermark', '-iv') # In[3]: try: from IPython.display import set_matplotlib_formats set_matplotlib_formats("retina") except ImportError: pass # ##### Helper function for plotting weights # In[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 # In[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(text=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(text=x.id, xy=_lab_loc(x), **kws), axis=1) # ----------------------- # ### 1. Triangle # # ##### Generate a ``spaghetti.Network`` and plot # In[6]: triangle = [ Chain([Point([0, 0]), Point([0, 3])]), Chain([Point([0, 3]), Point([4, 0])]), Chain([Point([4, 0]), Point([0, 0])]), ] triangle # In[7]: ntw = spaghetti.Network(in_data=triangle) vertices_df, arcs_df = spaghetti.element_as_gdf(ntw, vertices=True, arcs=True) # In[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) # ##### An arc-based [spatial weights](https://pysal.org/libpysal/generated/libpysal.weights.W.html#libpysal.weights.W) attribute is generated with network instantiaton—``w_network``. # In[9]: ntw.w_network # In[10]: print(dir(ntw.w_network)) # ##### The ``plot()`` method in the ``libpysal.weights.W`` class can be used along with a [geopandas.GeoDataFrame](https://geopandas.org/data_structures.html#geodataframe) to visualize contiguity. # In[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) # ----------------------- # ### 2. Regular lattice # # ##### Generate a ``spaghetti.Network`` from a 4x4 regular lattice and plot # In[12]: lattice = spaghetti.regular_lattice((0,0,3,3), 2, exterior=True) ntw = spaghetti.Network(in_data=lattice) # In[13]: vertices_df, arcs_df = spaghetti.element_as_gdf(ntw, vertices=True, arcs=True) # In[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); # ##### Plot only the arc weights # In[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); # ----------------------- # ### 3. Emprical Example — [geodanet/streets.shp](https://github.com/pysal/libpysal/tree/master/libpysal/examples/geodanet) # # ##### Read in a ``libpysal.example`` and create a ``spaghetti.Network``, then plot. # In[16]: ntw = spaghetti.Network(in_data=libpysal.examples.get_path("streets.shp")) # In[17]: vertices_df, arcs_df = spaghetti.element_as_gdf(ntw, vertices=True, arcs=True) # In[18]: base = arcs_df.plot(**base_kws, alpha=.35) vertices_df.plot(ax=base, fc="r", ec="k", markersize=50, zorder=2); # In[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); # In[20]: base = arcs_df.plot(**base_kws, alpha=.0) plot_weights(ntw, arcs_df, base) # ------------------