import plotly.graph_objs as go
import ipywidgets as ipw
import numpy as np
import json
Read the geojson file that records geo and election data for Illinois state. This file is created from the second table listed here https://www.nytimes.com/elections/results/illinois, and the topojson file https://github.com/deldersveld/topojson/blob/master/countries/us-states/IL-17-illinois-counties.json for Illinois counties.
with open("illinois-election.geojson") as json_file:#https://gist.github.com/empet/5e35f2aba6df23011c7192edfa97ca0a
jdata = json_file.read()
geoJSON = json.loads(jdata)
geoJSON['features'][0]['properties']#party=1 if Trump nr votes > Clinton nr votes; party=0 otherwise
{'Clinton_Trump': [1789.0, 3785.0], 'center_lon_lat': [-89.34355051659558, 41.03517190637024], 'county_name': 'Marshall', 'party': 1}
votes_Clinton_Trump=[geo['properties']['Clinton_Trump'] for geo in geoJSON['features']]
pts=[]#list of points defining boundaries of county polygons
for feature in geoJSON['features']:
if feature['geometry']['type']=='Polygon':
pts.extend(feature['geometry']['coordinates'][0])
pts.append([None, None])#mark the end of a polygon
elif feature['geometry']['type']=='MultiPolygon':
for polyg in feature['geometry']['coordinates']:
pts.extend(polyg[0])
pts.append([None, None])#end of polygon
else: raise ValueError("geometry type irrelevant for map")
line_lons=[pt[0] for pt in pts]
line_lats=[pt[1] for pt in pts]
sources=[]
for feat in geoJSON['features']:
sources.append({"type": "FeatureCollection", 'features': [feat]})
lons=[]
lats=[]
color_vals=[]
county_name=[]
for geo in geoJSON['features']:
lons.append(geo['properties']['center_lon_lat'][0])
lats.append(geo['properties']['center_lon_lat'][1])
color_vals.append(int(geo['properties']['party']))
county_name.append(geo['properties']['county_name'])
county_name=[name+' County' for name in county_name]
mapbox_access_token = ''
party_color=['rgba(97,117,193, 0.8)', 'rgba(176,18,44, 0.8)']#converted from '#6175c1' and '#B0122C'
county_color=['#6175c1' if cval==0 else '#B0122C' for cval in color_vals]
Illinois0 = dict(type='scattermapbox',#the scattermapbox of center points in each county
lat=lats,
lon=lons,
mode='markers',
text=county_name,
marker=dict(size=2, color='white'),
hoverinfo='text',
showlegend=False
)
Illinois1 = dict(type='scattermapbox',#county boundaries
lat=line_lats,
lon=line_lons,
mode='lines',
line=dict(width=0.5, color='rgb(220,220,220)'),
hoverinfo='none',
showlegend=False
)
layers=[dict(sourcetype = 'geojson',#the county shapes colored according to the party that won there (0 dem, 1 rep)
source =sources[k],
below="water",
type = 'fill',
color = county_color[k],
opacity=0.8
) for k in range(len(sources))]
layout = dict(title='Presidential Election in Illinois, 2016',
font=dict(family='Balto'),
autosize=False,
width=600,
height=700,
hovermode='closest',
mapbox=dict(accesstoken=mapbox_access_token,
layers=layers,
bearing=0,
center=dict(
lat=lats[79], #Macon County center
lon=lons[79]),
pitch=0,
zoom=5.61,
)
)
fig = go.FigureWidget(data=[Illinois0, Illinois1], layout=layout)
fig
FigureWidget({ 'data': [{'hoverinfo': 'text', 'lat': [41.03517190637024, 39.27502107215389, …
def get_bar_fig(y_vals, bar_colors, width=300, height=500, left=50, top=100, right=50, bottom=50):
#Defines the bar chart of (Clinton, Trump) vote numbers and returns the corresponding FigureWidget
vote_bar = dict(type='bar',#The bar char pointing out the vote number for each candidate
x=['Clinton', 'Trump'],
y=y_vals,
marker=dict(color=bar_colors),
hoverinfo='y')
bar_layout = dict(title=county_name[0],
width=width, height=height,
font=dict(family='Balto'),
xaxis=dict(showline=True, zeroline=False, showgrid=False, showticklabels=True),
yaxis=dict(showline=False, gridcolor='white', ticklen=4),
bargap=0.01,
margin=dict(l=left, r=right, b=bottom, t=top),
hovermode='x',
plot_bgcolor='rgb(240,240,240)')
return go.FigureWidget(data=[vote_bar], layout=bar_layout)
def hovering(fw, votes_Clinton_Trump, county_name, bar_colors, width_figd=300, height_figd=400, top_figd=100):
fwd=get_bar_fig(votes_Clinton_Trump[0], bar_colors, width=width_figd, height=height_figd, top=top_figd)
def trigger_update(trace, points, state):
ind = points.point_inds[0]#get the index of the scatter point that is hovered on
with fwd.batch_update():#update data and layout in the bar chart
fwd.data[0].y = votes_Clinton_Trump[ind]
fwd.layout.title = county_name[ind]
fw.data[0].on_hover(trigger_update)
return ipw.HBox([fw, fwd])
dashboard=hovering(fig, votes_Clinton_Trump, county_name, party_color)
dashboard
HBox(children=(FigureWidget({ 'data': [{'hoverinfo': 'text', 'lat': [41.03517190637024, 39.2…