From d7ecee6b95ddcd6c2dbf1fa681c7082de767b3a0 Mon Sep 17 00:00:00 2001 From: David De Martin <59452411+DrDabbidy@users.noreply.github.com> Date: Sun, 12 Dec 2021 17:32:14 -0500 Subject: [PATCH] Update heatmap_generation.py --- heatmap_generation.py | 73 +++++++++++++++++++++++++++++-------------- 1 file changed, 49 insertions(+), 24 deletions(-) diff --git a/heatmap_generation.py b/heatmap_generation.py index cdd8253..9d295f9 100644 --- a/heatmap_generation.py +++ b/heatmap_generation.py @@ -4,61 +4,86 @@ import pandas as pd import json from crime_data import CrimeData +import dash +from dash import dcc +from dash import html -def generate_heatmap(data: CrimeData, crime: str) -> None: +def generate_heatmap(data: CrimeData) -> None: """Generate an animated heatmap for the pindexes of the crime over time given the CrimeData, data.""" with open('local-area-boundary.geojson') as file: regions = json.load(file) - unpacked_data = unpack_data(data, crime) + unpacked_data = unpack_data(data) - df = pd.DateFrame({'date': unpacked_data[0], + df = pd.DataFrame({'date': unpacked_data[0], 'region': unpacked_data[1], - 'p-index': unpacked_data[2]}) + 'p-index': unpacked_data[2], + 'crime-type': unpacked_data[3]}) - fig = px.choropleth_mapbox(df, geojson=regions, - locations='region', - color='p-index', - color_continuous_scale="Viridis", - range_color=(-100, 100), - featureidkey="properties.name", - mapbox_style="carto-positron", - opacity=0.5, - center={"lat": 0, "lon": 0}, - zoom=1, - animation_frame='date') + crime_types = list(data.crime_pindex.keys()) - fig.update_geos(fitbounds="locations", visible=False) - fig.update_layout(margin={"r": 0, "t": 0, "l": 0, "b": 0}, ) + # create a dash app with a dropdown menu so that we can switch between graphs + app = dash.Dash() + app.layout = html.Div([ + dcc.Dropdown( + id='crime-type-dropdown', + options=[{'label': crime, 'value': crime} for crime in crime_types], + value=crime_types[0] + ), + dcc.Graph(id='choropleth-graph')]) - fig.show() + @app.callback( + dash.dependencies.Output('choropleth-graph', 'figure'), + [dash.dependencies.Input('crime-type-dropdown', 'value')]) + def update_output(crime: str): + """Updates which graph is shown in our app.""" + fig = px.choropleth_mapbox(df[df['crime-type'] == crime], geojson=regions, + locations='region', + color='p-index', + color_continuous_scale=['LawnGreen', 'LightBlue', 'DarkRed'], + range_color=(-100, 100), + featureidkey="properties.name", + mapbox_style="carto-positron", + opacity=0.5, + center={"lat": 49.24200376111951, "lon": -123.13312355113719}, + zoom=11, + animation_frame='date', + height=750) + fig.update_geos(fitbounds="locations", visible=False) + fig.update_layout(title=f'P-index graph for {crime}') + return fig -def unpack_data(data: CrimeData, crime: str) -> tuple[list[str], list[str], list[float]]: + app.run_server() + + +def unpack_data(data: CrimeData) -> tuple[list[str], list[str], list[float], list[str]]: """Unpack the data in CrimeData into three lists, one corresponding to the dates, one to the regions, and one to the pindexes.""" dates = [] regions = [] pindexes = [] - pindex_data = data.crime_pindex[crime] + crime_types = [] - for neighbourhood in pindex_data: - for obj in pindex_data[neighbourhood]: + for crime in data.crime_pindex: + for obj in data.crime_pindex[crime].values(): years = sorted(list(obj.p_index_dict.keys())) for year in years: months = list(obj.p_index_dict[year].keys()) + # print(months) for month in months: dates.append(month_year_to_str(month, year)) regions.append(obj.neighbourhood) pindexes.append(obj.get_data(year, month)) + crime_types.append(crime) - return dates, regions, pindexes + return dates, regions, pindexes, crime_types def month_year_to_str(month: int, year: int) -> str: """Given the month and year as ints, return the datestring in the form 'month year'""" months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'] - return f'{months[month]} {year}' + return f'{months[month - 1]} {year}'