Skip to content

Commit

Permalink
Merge pull request #51 from somduttasinha/46-create-initial-concept-o…
Browse files Browse the repository at this point in the history
…f-dashboard

Finished dashboard concept
  • Loading branch information
manuGil authored Mar 1, 2024
2 parents ec69843 + e5b3d81 commit 66f32de
Show file tree
Hide file tree
Showing 15 changed files with 49,913 additions and 0 deletions.
Empty file.
Empty file.
Empty file.
87 changes: 87 additions & 0 deletions citizenvoice/dashboard/concept/app/dashboard.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
import dash
import pandas as pd
import plotly.express as px
from dash import Dash, dcc, html, Output, Input
from dash.dependencies import Input, Output
import json
import plotly.io as pio
import dash_bootstrap_components as dbc
from citizenvoice.dashboard.concept.graph_utils.graph_generator import Generator


path = "../resources/census-historic-population-borough.csv"
df = pd.read_csv(path)


year_to_col_name_mapping = {}

for colname in df.columns[2:]:
year_to_col_name_mapping[colname[-4:]] = colname

pio.renderers.default = "browser"
# Building components
stylesheets = [dbc.themes.CYBORG] # change this when we have our own CSS

app = Dash(__name__, external_stylesheets=stylesheets)
title = dcc.Markdown(children='# London population evolution by borough')
project_credits = dcc.Markdown(children='Citizen Voice Project')
input_year = dcc.Dropdown(id="select-year",
options=year_to_col_name_mapping,
multi=False,
value=2011,
style={'width': "70%"})

options_checklist = dcc.Checklist(
id="options-checklist",
options=["option1", "option2"]
)

graph = dcc.Graph(id='choropleth-map',
figure={},
style={
"margin": "0"
}
) # this is the graph that we should be updating

# app.layout = dbc.Container([title, input_year, graph])
app.layout = dbc.Container([
dbc.Row([title]),
dbc.Row(children=[
dbc.Col(children=[options_checklist], style={
'width': "5"
}),
dbc.Col(children=[input_year, graph], style={
'width': "10"
})
]),
dbc.Row(children=[
dbc.Col(children=[project_credits]),
html.Div()
])]

)


@app.callback(
Output(graph, 'figure'),
Input(input_year, component_property='value')
)
def update_graph(year):

generator = Generator(df)
fig = generator.create_choropleth(
geojson_file="../resources/london_boroughs.json",
statistic_column_name="Persons-"+str(year),
area_column_name="Area Name"
)
fig.update_layout(width=600,
height=500)
return fig


def run():
if __name__ == '__main__':
app.run_server(debug=True)


run()
Empty file.
11 changes: 11 additions & 0 deletions citizenvoice/dashboard/concept/data_utils/data_cleaner.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import pandas as pd


class Cleaner:
def __init__(self, dataframe: pd.DataFrame):
self.dataframe = dataframe

def drop_columns(self, column_indices: list):
return self.dataframe.drop(column_indices)
# eventually use args and kwargs

23 changes: 23 additions & 0 deletions citizenvoice/dashboard/concept/data_utils/data_parser.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import json

import pandas as pd


class Parser:
def __init__(self, dataframe: pd.DataFrame):
self.dataframe = dataframe

def combine_df_with_geojson(self, geojson_file):
geojson_data = json.load(open(geojson_file, "r"))
geojson_features = geojson_data['features']

# map ids
id_mapping_dict = {}
for feature in geojson_features:
feature['id'] = feature['properties']['id']
id_mapping_dict[feature['properties']['name']] = feature['id']

combined_df = self.dataframe.copy()

combined_df["id"] = combined_df["Area Name"].apply(lambda x: id_mapping_dict[x])
return combined_df
182 changes: 182 additions & 0 deletions citizenvoice/dashboard/concept/exploration/2-dash.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,182 @@
{
"cells": [
{
"cell_type": "code",
"execution_count": 1,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"import dash\n",
"import pandas as pd\n",
"import plotly.express as px\n",
"from dash import dcc\n",
"from dash import html\n",
"from dash.dependencies import Input, Output"
]
},
{
"cell_type": "code",
"execution_count": 2,
"outputs": [],
"source": [
"app = dash.Dash(__name__)"
],
"metadata": {
"collapsed": false
}
},
{
"cell_type": "code",
"execution_count": 3,
"outputs": [],
"source": [
"df = pd.read_csv(\"resources/census-historic-population-borough.csv\")"
],
"metadata": {
"collapsed": false
}
},
{
"cell_type": "code",
"execution_count": 4,
"outputs": [
{
"data": {
"text/plain": " Area Code Area Name Persons-1801 Persons-1811 Persons-1821 \\\n0 00AA City of London 129000 121000 125000 \n1 00AB Barking and Dagenham 3000 4000 5000 \n2 00AC Barnet 8000 9000 11000 \n3 00AD Bexley 5000 6000 7000 \n4 00AE Brent 2000 2000 3000 \n\n Persons-1831 Persons-1841 Persons-1851 Persons-1861 Persons-1871 ... \\\n0 123000 124000 128000 112000 75000 ... \n1 6000 7000 8000 8000 10000 ... \n2 13000 14000 15000 20000 29000 ... \n3 9000 11000 12000 15000 22000 ... \n4 3000 5000 5000 6000 19000 ... \n\n Persons-1921 Persons-1931 Persons-1939 Persons-1951 Persons-1961 \\\n0 14000 11000 9000 5000 4767 \n1 44000 138000 184000 189000 177092 \n2 147000 231000 296000 320000 318373 \n3 76000 95000 179000 205000 209893 \n4 184000 251000 310000 311000 295893 \n\n Persons-1971 Persons-1981 Persons-1991 Persons-2001 Persons-2011 \n0 4000 5864 4230 7181 7375 \n1 161000 149786 140728 163944 185911 \n2 307000 293436 284106 314565 356386 \n3 217000 215233 211404 218301 231997 \n4 281000 253275 227903 263466 311215 \n\n[5 rows x 24 columns]",
"text/html": "<div>\n<style scoped>\n .dataframe tbody tr th:only-of-type {\n vertical-align: middle;\n }\n\n .dataframe tbody tr th {\n vertical-align: top;\n }\n\n .dataframe thead th {\n text-align: right;\n }\n</style>\n<table border=\"1\" class=\"dataframe\">\n <thead>\n <tr style=\"text-align: right;\">\n <th></th>\n <th>Area Code</th>\n <th>Area Name</th>\n <th>Persons-1801</th>\n <th>Persons-1811</th>\n <th>Persons-1821</th>\n <th>Persons-1831</th>\n <th>Persons-1841</th>\n <th>Persons-1851</th>\n <th>Persons-1861</th>\n <th>Persons-1871</th>\n <th>...</th>\n <th>Persons-1921</th>\n <th>Persons-1931</th>\n <th>Persons-1939</th>\n <th>Persons-1951</th>\n <th>Persons-1961</th>\n <th>Persons-1971</th>\n <th>Persons-1981</th>\n <th>Persons-1991</th>\n <th>Persons-2001</th>\n <th>Persons-2011</th>\n </tr>\n </thead>\n <tbody>\n <tr>\n <th>0</th>\n <td>00AA</td>\n <td>City of London</td>\n <td>129000</td>\n <td>121000</td>\n <td>125000</td>\n <td>123000</td>\n <td>124000</td>\n <td>128000</td>\n <td>112000</td>\n <td>75000</td>\n <td>...</td>\n <td>14000</td>\n <td>11000</td>\n <td>9000</td>\n <td>5000</td>\n <td>4767</td>\n <td>4000</td>\n <td>5864</td>\n <td>4230</td>\n <td>7181</td>\n <td>7375</td>\n </tr>\n <tr>\n <th>1</th>\n <td>00AB</td>\n <td>Barking and Dagenham</td>\n <td>3000</td>\n <td>4000</td>\n <td>5000</td>\n <td>6000</td>\n <td>7000</td>\n <td>8000</td>\n <td>8000</td>\n <td>10000</td>\n <td>...</td>\n <td>44000</td>\n <td>138000</td>\n <td>184000</td>\n <td>189000</td>\n <td>177092</td>\n <td>161000</td>\n <td>149786</td>\n <td>140728</td>\n <td>163944</td>\n <td>185911</td>\n </tr>\n <tr>\n <th>2</th>\n <td>00AC</td>\n <td>Barnet</td>\n <td>8000</td>\n <td>9000</td>\n <td>11000</td>\n <td>13000</td>\n <td>14000</td>\n <td>15000</td>\n <td>20000</td>\n <td>29000</td>\n <td>...</td>\n <td>147000</td>\n <td>231000</td>\n <td>296000</td>\n <td>320000</td>\n <td>318373</td>\n <td>307000</td>\n <td>293436</td>\n <td>284106</td>\n <td>314565</td>\n <td>356386</td>\n </tr>\n <tr>\n <th>3</th>\n <td>00AD</td>\n <td>Bexley</td>\n <td>5000</td>\n <td>6000</td>\n <td>7000</td>\n <td>9000</td>\n <td>11000</td>\n <td>12000</td>\n <td>15000</td>\n <td>22000</td>\n <td>...</td>\n <td>76000</td>\n <td>95000</td>\n <td>179000</td>\n <td>205000</td>\n <td>209893</td>\n <td>217000</td>\n <td>215233</td>\n <td>211404</td>\n <td>218301</td>\n <td>231997</td>\n </tr>\n <tr>\n <th>4</th>\n <td>00AE</td>\n <td>Brent</td>\n <td>2000</td>\n <td>2000</td>\n <td>3000</td>\n <td>3000</td>\n <td>5000</td>\n <td>5000</td>\n <td>6000</td>\n <td>19000</td>\n <td>...</td>\n <td>184000</td>\n <td>251000</td>\n <td>310000</td>\n <td>311000</td>\n <td>295893</td>\n <td>281000</td>\n <td>253275</td>\n <td>227903</td>\n <td>263466</td>\n <td>311215</td>\n </tr>\n </tbody>\n</table>\n<p>5 rows × 24 columns</p>\n</div>"
},
"execution_count": 4,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"df.head()"
],
"metadata": {
"collapsed": false
}
},
{
"cell_type": "code",
"execution_count": 5,
"outputs": [
{
"data": {
"text/plain": "{'1801': 'Persons-1801',\n '1811': 'Persons-1811',\n '1821': 'Persons-1821',\n '1831': 'Persons-1831',\n '1841': 'Persons-1841',\n '1851': 'Persons-1851',\n '1861': 'Persons-1861',\n '1871': 'Persons-1871',\n '1881': 'Persons-1881',\n '1891': 'Persons-1891',\n '1901': 'Persons-1901',\n '1911': 'Persons-1911',\n '1921': 'Persons-1921',\n '1931': 'Persons-1931',\n '1939': 'Persons-1939',\n '1951': 'Persons-1951',\n '1961': 'Persons-1961',\n '1971': 'Persons-1971',\n '1981': 'Persons-1981',\n '1991': 'Persons-1991',\n '2001': 'Persons-2001',\n '2011': 'Persons-2011'}"
},
"execution_count": 5,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"year_to_col_name_mapping = {\n",
"\n",
"}\n",
"\n",
"for colname in df.columns[2:]:\n",
" year_to_col_name_mapping[colname[-4:]] = colname\n",
"\n",
"\n",
"year_to_col_name_mapping"
],
"metadata": {
"collapsed": false
}
},
{
"cell_type": "code",
"execution_count": 6,
"outputs": [],
"source": [
"\n",
"\n",
"app.layout = html.Div([\n",
" html.H1(\"London population evolution by borough\"),\n",
" dcc.Dropdown(\n",
" id=\"select-year\",\n",
" options=year_to_col_name_mapping,\n",
" multi=False,\n",
" value=2011,\n",
" style={'width': \"40%\"}\n",
" ),\n",
"\n",
" # the div below is where our output graph will eventually lie\n",
" html.Div(id='output-container',\n",
" children=[]),\n",
"\n",
" dcc.Graph(id='choropleth-map',\n",
" figure={})\n",
"])"
],
"metadata": {
"collapsed": false
}
},
{
"cell_type": "code",
"execution_count": 8,
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Dash is running on http://127.0.0.1:8050/\n",
"\n",
" * Serving Flask app '__main__'\n",
" * Debug mode: off\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.\n",
" * Running on http://127.0.0.1:8050\n",
"Press CTRL+C to quit\n"
]
}
],
"source": [
"if __name__ == '__main__':\n",
" app.run_server(debug=False)"
],
"metadata": {
"collapsed": false
}
},
{
"cell_type": "code",
"execution_count": null,
"outputs": [],
"source": [],
"metadata": {
"collapsed": false
}
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 2
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython2",
"version": "2.7.6"
}
},
"nbformat": 4,
"nbformat_minor": 0
}
Loading

0 comments on commit 66f32de

Please sign in to comment.