Commit 441d7dc25c
Verified · cmc
Layout: unified · split
app.py +14 −18
| @@ -1,10 +1,10 @@ | |||
| 1 | from dash import Dash, html, dcc, callback, Output, Input | 1 | from dash import Dash, html, dcc, callback, Output, Input, dash_table |
| 2 | import plotly.express as px | 2 | import plotly.express as px |
| 3 | import pandas as pd | 3 | import pandas as pd |
| 4 | import sqlite3 | 4 | import sqlite3 |
| 5 | 5 | ||
| 6 | # Connect to database and query all incidents | 6 | # Connect to database and query all incidents |
| 7 | connection = sqlite3.connect("../raw_data/ingress.db") | 7 | connection = sqlite3.connect("./raw_data/ingress.db") |
| 8 | cursor = connection.cursor() | 8 | cursor = connection.cursor() |
| 9 | query = "SELECT * FROM incidents;" | 9 | query = "SELECT * FROM incidents;" |
| 10 | df = pd.read_sql_query(query, connection).sort_values(by="description") | 10 | df = pd.read_sql_query(query, connection).sort_values(by="description") |
| @@ -18,36 +18,32 @@ app.layout = html.Div(children = [ | |||
| 18 | html.H1(children="Omaha Police Invidents", style={"textAlign":"center"}), | 18 | html.H1(children="Omaha Police Invidents", style={"textAlign":"center"}), |
| 19 | html.Div([ | 19 | html.Div([ |
| 20 | html.H2(children="Totals per Category and Year", style={"textAlign":"center"}), | 20 | html.H2(children="Totals per Category and Year", style={"textAlign":"center"}), |
| 21 | dcc.Dropdown(df.sort_values("description").description.unique(), "INJURY", id="bar-dropdown"), | 21 | dcc.Dropdown(df.sort_values("description").description.unique(), "INJURY", id="dropdown"), |
| 22 | dcc.Dropdown(df.sort_values("year").year.unique(), "2023", id="bar-year-dropdown"), | 22 | dcc.Dropdown(df.sort_values("year").year.unique(), "2023", id="year-dropdown"), |
| 23 | dcc.Graph(id="bar-graph") | 23 | html.Hr(), |
| 24 | ]), | 24 | dash_table.DataTable(data=df.to_dict("records"), page_size=5, id="table"), |
| 25 | html.Div([ | ||
| 26 | html.H2(children="Map of Incidents per Category and Year", style={"textAlign":"center"}), | 25 | html.H2(children="Map of Incidents per Category and Year", style={"textAlign":"center"}), |
| 27 | dcc.Dropdown(df.sort_values("description").description.unique(), "INJURY", id="map-dropdown"), | ||
| 28 | dcc.Dropdown(df.sort_values("year").year.unique(), "2023", id="map-year-dropdown"), | ||
| 29 | dcc.Graph(id="map-graph") | 26 | dcc.Graph(id="map-graph") |
| 30 | ]) | 27 | ]) |
| 31 | ]) | 28 | ]) |
| 32 | 29 | ||
| 33 | # Create bar graph | 30 | # Create table |
| 34 | @callback( | 31 | @callback( |
| 35 | Output("bar-graph", "figure"), | 32 | Output("table", "data"), |
| 36 | Input("bar-dropdown", "value"), | 33 | Input("dropdown", "value"), |
| 37 | Input("bar-year-dropdown", "value") | 34 | Input("year-dropdown", "value") |
| 38 | ) | 35 | ) |
| 39 | def update_bar_graph(description, year): | 36 | def update_table(description, year): |
| 40 | dff = df[df.year == year] | 37 | dff = df[df.year == year] |
| 41 | dff = dff.value_counts(subset=["description"]) | ||
| 42 | dff = dff.reset_index() | 38 | dff = dff.reset_index() |
| 43 | dff = dff[dff.description == description] | 39 | dff = dff[dff.description == description] |
| 44 | return px.bar(dff, x="description", y="count") | 40 | return dff.to_dict("records") |
| 45 | 41 | ||
| 46 | # Create map | 42 | # Create map |
| 47 | @callback( | 43 | @callback( |
| 48 | Output("map-graph", "figure"), | 44 | Output("map-graph", "figure"), |
| 49 | Input("map-dropdown", "value"), | 45 | Input("dropdown", "value"), |
| 50 | Input("map-year-dropdown", "value") | 46 | Input("year-dropdown", "value") |
| 51 | ) | 47 | ) |
| 52 | def update_map(description, year): | 48 | def update_map(description, year): |
| 53 | dff = df[df.year == year] | 49 | dff = df[df.year == year] |
assets/styles.css +4 −3
| @@ -1,8 +1,9 @@ | |||
| 1 | body { | 1 | body { |
| 2 | font-family: -apple-system, BlinkMacSystemFont, avenir next, avenir, segoe ui, helvetica neue, helvetica, Cantarell, Ubuntu, roboto, noto, arial, sans-serif; | 2 | font-family: -apple-system, BlinkMacSystemFont, avenir next, avenir, segoe ui, helvetica neue, helvetica, Cantarell, Ubuntu, roboto, noto, arial, sans-serif; |
| 3 | } | ||
| 4 | |||
| 5 | #_dash-app-content { | ||
| 6 | max-width: 80vw; | 3 | max-width: 80vw; |
| 7 | margin: 2rem auto; | 4 | margin: 2rem auto; |
| 5 | } | ||
| 6 | |||
| 7 | hr { | ||
| 8 | margin: 1rem auto; | ||
| 8 | }\ No newline at end of file | 9 | }\ No newline at end of file |