If any part of this notebook is used in your research, please cite with the reference found in README.md.
Author: James D. Gaboardi jgaboardi@gmail.com
This notebook is an basic walk-through for:
In [1]:
%load_ext watermark
%watermark
In [2]:
import geopandas
import libpysal
import matplotlib
import matplotlib_scalebar
from matplotlib_scalebar.scalebar import ScaleBar
import numpy
import pandas
import shapely
from shapely.geometry import Point
import spaghetti
%matplotlib inline
%watermark -w
%watermark -iv
In [3]:
try:
from IPython.display import set_matplotlib_formats
set_matplotlib_formats("retina")
except ImportError:
pass
In [4]:
ntw = spaghetti.Network(in_data=libpysal.examples.get_path("streets.shp"))
In [5]:
pp_name = "crimes"
pp_shp = libpysal.examples.get_path("%s.shp" % pp_name)
ntw.snapobservations(pp_shp, pp_name, attribute=True)
ntw.pointpatterns
Out[5]:
In [6]:
ntw.pointpatterns[pp_name].dist_snapped[0]
Out[6]:
dist_to_vertex
dict keyed by pointid with the value being a dict in the form
{node: distance to vertex, node: distance to vertex}
In [7]:
ntw.pointpatterns[pp_name].dist_to_vertex[0]
Out[7]:
npoints
point observations in set
In [8]:
ntw.pointpatterns[pp_name].npoints
Out[8]:
obs_to_arc
dict keyed by arc with the value being a dict in the form
{pointID:(x-coord, y-coord), pointID:(x-coord, y-coord), ... }
In [9]:
ntw.pointpatterns[pp_name].obs_to_arc[(161, 162)]
Out[9]:
obs_to_vertex
list of incident network vertices to snapped observation points
In [10]:
ntw.pointpatterns[pp_name].obs_to_vertex[0]
Out[10]:
points
geojson like representation of the point pattern. Includes properties if read with attributes=True
In [11]:
ntw.pointpatterns[pp_name].points[0]
Out[11]:
snapped_coordinates
dict keyed by pointid with the value being (x-coord, y-coord)
In [12]:
ntw.pointpatterns[pp_name].snapped_coordinates[0]
Out[12]:
In [13]:
def fetch_cpl(net, pp, mean=True):
"""Create a counts per link object and find mean."""
cpl = net.count_per_link(net.pointpatterns[pp].obs_to_arc, graph=False)
if mean:
mean_cpl = sum(list(cpl.values())) / float(len(cpl.keys()))
return cpl, mean_cpl
return cpl
In [14]:
ntw_counts, ntw_ctmean = fetch_cpl(ntw, pp_name)
list(ntw_counts.items())[:4]
Out[14]:
In [15]:
ntw_ctmean
Out[15]:
In [16]:
npts = ntw.pointpatterns[pp_name].npoints
npts
Out[16]:
In [17]:
sim_uniform = ntw.simulate_observations(npts)
sim_uniform
Out[17]:
In [18]:
print(dir(sim_uniform))
In [19]:
def as_gdf(pp):
pp = {idx: Point(coords) for idx, coords in pp.items()}
df = pandas.DataFrame.from_dict(pp, orient="index")
df.index.name, df.columns = "id", ["geometry"]
gdf = geopandas.GeoDataFrame(df, geometry=df.geometry)
return gdf
sim_uniform_gdf = as_gdf(sim_uniform.points)
sim_uniform_gdf.head()
Out[19]:
In [20]:
vertices_df, arcs_df = spaghetti.element_as_gdf(
ntw, vertices=ntw.vertex_coords, arcs=ntw.arcs
)
In [21]:
crimes = spaghetti.element_as_gdf(ntw, pp_name=pp_name)
crimes_snapped = spaghetti.element_as_gdf(ntw, pp_name=pp_name, snapped=True)
In [22]:
def plotter():
"""Generate a spatial plot."""
def _patch(_kws, labinfo):
"""Generate a legend patch."""
label = "%s — %s" % tuple(labinfo)
_kws.update({"lw":0, "label":label, "alpha":.5})
return matplotlib.lines.Line2D([], [], **_kws)
def _legend(handles, anchor=(1., .75)):
"""Generate a legend."""
lkws = {"fancybox":True,"framealpha":0.85, "fontsize":"xx-large"}
lkws.update({"bbox_to_anchor": anchor, "labelspacing": 2.})
lkws.update({"borderpad": 2., "handletextpad":1.5})
lkws.update({"title": "Crime locations & counts", "title_fontsize":25})
matplotlib.pyplot.legend(handles=handles, **lkws)
def carto_elements(b):
"""Add/adjust cartographic elements."""
scalebar = ScaleBar(1, units="m", location="lower left")
b.add_artist(scalebar)
b.set(xticklabels=[], xticks=[], yticklabels=[], yticks=[]);
pkws = {"alpha":0.25}
base = arcs_df.plot(color="k", figsize=(9, 9), zorder=0, **pkws)
patches = []
gdfs = [crimes, crimes_snapped, sim_uniform_gdf]
colors, zo = ["k", "g", "b"], [1 ,2 ,3]
markers, markersizes = ["o", "X", "X"], [150, 150, 150]
labels = [["Empirical"], ["Network-snapped"], ["Simulated"]]
iterinfo = list(zip(gdfs, colors, zo, markers, markersizes, labels))
for gdf, c, z, m, ms, lab in iterinfo:
gdf.plot(ax=base, c=c, marker=m, markersize=ms, zorder=z, **pkws)
patch_args = {"marker":m, "markersize":ms/10,"c":c}, lab+[gdf.shape[0]]
patches.append(_patch(*patch_args))
_legend(patches)
carto_elements(base)
In [23]:
plotter()