Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 36 additions & 29 deletions main.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,10 @@
from holoviews.operation.datashader import datashade

# Get renderer and set global display options
width = 1200
height = 600
hv.extension('bokeh')
hv.opts("RGB [width=1200 height=682 xaxis=None yaxis=None show_grid=False]")
hv.opts("RGB [width={width} height={height} xaxis=None yaxis=None show_grid=False]".format(width=width, height=height))
hv.opts("Polygons (fill_color=None line_width=1.5) [apply_ranges=False tools=['tap']]")
hv.opts("Points [apply_ranges=False] WMTS (alpha=0.5)")

Expand All @@ -28,20 +30,13 @@
census_points = gv.Points(df, kdims=['easting', 'northing'], vdims=['race'])

# Declare colormapping
color_key = {'w': 'white', 'b': 'green', 'a': 'red',
color_key = {'w': 'purple', 'b': 'green', 'a': 'red',
'h': 'orange', 'o': 'saddlebrown'}
races = {'w': 'White', 'b': 'Black', 'a': 'Asian',
'h': 'Hispanic', 'o': 'Other'}
color_points = hv.NdOverlay({races[k]: gv.Points([0,0], crs=crs.PlateCarree())(style=dict(color=v))
for k, v in color_key.items()})

# Apply datashading to census data
x_range, y_range = ((-13884029.0, -7453303.5), (2818291.5, 6335972.0)) # Continental USA
shade_defaults = dict(x_range=x_range, y_range=y_range, x_sampling=10,
y_sampling=10, width=1200, height=682,
color_key=color_key, aggregator=ds.count_cat('race'),)
shaded = datashade(census_points, **shade_defaults)

shapefile = {'state_house': 'cb_2016_48_sldl_500k',
'state_senate': 'cb_2016_48_sldu_500k',
'us_house': 'cb_2015_us_cd114_5m'}
Expand All @@ -51,6 +46,11 @@
tile_url = 'https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{Z}/{Y}/{X}.jpg'
tiles = gv.WMTS(WMTSTileSource(url=tile_url))

x_range, y_range = ((-13884029.0, -7453303.5), (2818291.5, 6335972.0)) # Continental USA
shade_defaults = dict(x_range=x_range, y_range=y_range, x_sampling=10,
y_sampling=10, width=width, height=height,
color_key=color_key, aggregator=ds.count_cat('race'),)
shaded = datashade(census_points, **shade_defaults)

DIVISION_ID_RE = {
'state_house': re.compile(r'ocd-division/country:us/state:[a-z]{2}/sldl:([0-9]+)'),
Expand Down Expand Up @@ -91,38 +91,45 @@ def address_district_lookup(address, district_type, api_key):
return district


def load_district_shapefile(district_type, **kwargs):
district_type = '_'.join([part.lower() for part in district_type.split()])
shape_path = 'data/{0}/{0}.shp'.format(shapefile[district_type])
districts = gv.Shape.from_shapefile(shape_path, crs=crs.PlateCarree())
districts = gv.operation.project_shape(districts)
districts = hv.Polygons([gv.util.geom_to_array(dist.data) for dist in districts])
# districts.opts(plot=dict(fill_color=None, line_width=1.5))
return districts


class DistrictExplorer(hv.streams.Stream):
district_type = param.ObjectSelector(objects=('US House',
'State House',
'State Senate'),
default='US House')

def __init__(self, *args, **kwargs):
super(DistrictExplorer, self).__init__(*args, **kwargs)
self.plot = self.make_view()

def load_district_shapefile(self, district_type, **kwargs):
district_type = '_'.join([part.lower() for part in district_type.split()])
shape_path = 'data/{0}/{0}.shp'.format(shapefile[district_type])
districts = gv.Shape.from_shapefile(shape_path, crs=crs.PlateCarree())
self.districts = gv.operation.project_shape(districts)
return hv.Polygons([gv.util.geom_to_array(dist.data) for dist in self.districts])

def make_view(self, **kwargs):
districts = hv.DynamicMap(load_district_shapefile, streams=[self])
options = dict(width=1000, height=600, xaxis=None, yaxis=None,
districts = hv.DynamicMap(self.load_district_shapefile, streams=[self])

options = dict(width=width, height=height, xaxis=None, yaxis=None,
show_grid=False)
tiles.opts(plot=options)
return tiles * shaded * color_points * districts
plot = tiles * shaded * color_points * districts
plot.redim.range(easting=x_range, northing=y_range,
x=x_range, y=y_range)
return plot

# def event(self, **kwargs):
# if not self.output or any(k in kwargs for k in ['District type']):
# self.output = hv.DynamicMap(self.view, streams=[self])
# else:
# super(DistrictExplorer, self).event(**kwargs)
def event(self, **kwargs):
if self.district_type == 'US House':
x_range, y_range = ((-13884029.0, -7453303.5), (2818291.5, 6335972.0)) # Continental USA
else:
x_range, y_range = self.districts.range(1), self.districts.range(2)
self.plot.redim.range(easting=x_range, northing=y_range,
x=x_range, y=y_range)
return super(DistrictExplorer, self).event(**kwargs)


explorer = DistrictExplorer(name="District explorer")
dmap = explorer.make_view()
plot = hv.renderer('bokeh').instance(mode='server').get_plot(dmap)
plot = hv.renderer('bokeh').instance(mode='server').get_plot(explorer.plot)
parambokeh.Widgets(explorer, continuous_update=True, callback=explorer.event,
on_init=True, plots=[plot.state], mode='server')