Commit b54de6b4 authored by Terézia Slanináková's avatar Terézia Slanináková
Browse files

Finished, added more plots, cleanup, demo, final changes

parent a131d255
Loading
Loading
Loading
Loading
+11 −1
Original line number Diff line number Diff line
#  project: Smoking, obesity and alcohol consumption
#  PV251 Project: Smoking, obesity and alcohol consumption
## Info
- Author: Terézia Slanináková (445526)
- Date: 24.12.2019
@@ -7,3 +7,13 @@
- Prerequisite: python3 installed
- `pip install -r requirements.txt` will install the dependencies
- `python index.py` will launch the server on http://127.0.0.1:8050/

## Description
The data shows oecd healthrisk data of smoking, alcohol consumption and overweight/obese population throughout the world (and years). The data was published for [Health at a Glance](http://dx.doi.org/10.1787/19991312), original data may be found [here](https://data.oecd.org/healthrisk/daily-smokers.htm#indicator-chart).

1. Percentage of daily smokers (15+ yrs) | men-women-total | 1960-2018
2. Liters of alcohol / capita / year (15+ yrs) | total | 1960-2018
3. Percentage of population (15+ yrs) | measured-selfreported | 1978-2018

## Demo
![demo](demo.gif)
 No newline at end of file
+168 −86
Original line number Diff line number Diff line
import dash
from dash.dependencies import *
import dash_core_components as dcc
import dash_html_components as html
import pandas as pd
@@ -7,64 +8,49 @@ import plotly.graph_objs as go
from app import app

df = pd.read_csv('data/oecd.csv')
df_smokers = pd.read_csv("./data/oecd-smokers.csv")
df_alc = pd.read_csv("./data/oecd-alc.csv")
df_obese = pd.read_csv("./data/oecd-obese.csv")

layout = html.Div([
    html.Div([
        html.H3("Smoking, obesity and alcohol consumption (1960-2017)")], style={'textAlign': "center", "padding-bottom": "30"}),
    html.Div([
        html.Span("Indicator to display: (e.g. Smoking)", className="six columns",  style={"text-align": "right", "width": "40%", "padding-top": 10}),
        dcc.Dropdown(id="value-selected", value='lifeExp', 
            options=[{'label': "Smoking", 'value': 'smoke'}, {'label': "Alcohol", 'value': 'alcohol'}, {'label': "Overweight/Obese", 'value': 'obese'}],
            style={"display": "block", "margin-left": "auto", "margin-right": "auto", "width": "70%"},
            className="six columns")
        ], 
        className="row"
    ),
    html.Div([
        dcc.Graph(id="my-graph")], 
        style={'width': '100vh', 'display': 'inline-block',  'vertical-align': 'center'}),
    html.Div([
        html.Div([dcc.Graph(id="my-graph2", animate=False)], style={'width': '50%', 'display': 'inline-block', 'vertical-align': 'left', 'float':'left', 'overflowY': 'scroll', 'height': 500}),
        html.Div([dcc.Graph(id="my-graph3")], style={'width': '50%', 'display': 'inline-block', 'vertical-align': 'right', 'overflow': 'hidden'})
    ])
],  style={'width': '100vh'}, className="container")


@app.callback(
    [dash.dependencies.Output("my-graph", "figure"), dash.dependencies.Output("my-graph2", "figure"), dash.dependencies.Output("my-graph3", "figure")],
    [dash.dependencies.Input("value-selected", "value")]
)
def update_figure(selected):
    fig = go.Figure()
    horBarChart1 = go.Figure()
def get_labels_for_countries():
    locations = df["LOCATION"].unique()
    loc_dicts = []
    for l in locations:
        loc_dicts.append({"label": l, "value": l})
    return loc_dicts

    df_smoke = df[(df["INDICATOR"] == "SMOKERS") & (df["SUBJECT"] == "TOT")]
    df_alc = df[(df["INDICATOR"] == "ALCOHOL") & (df["SUBJECT"] == "TOT")]
    df_overobese = df[(df["INDICATOR"] == "OVEROBESE")]
    def title(text):
        if text == "smoke":
            return "% of population (15+) smoking"
        elif text == "alcohol":
            return "Pure alcohol consumption per capita (liters)"
def get_title_indicator(selected_indicator):
    title = ""
    if selected_indicator == "smoke":
        title = "% of population (15+) smoking"
    elif selected_indicator == "obese":
        title = "% of population being Overweight or obese"
    else:
            return "% of population being Overweight or obese"
    if selected == "smoke":
        df_to_use = df_smoke
    elif selected == "alcohol":
        df_to_use = df_alc
        title = "Pure alcohol consumption per capita (liters)"
    return title

def get_title(selected_indicator, selected_gender, selected_obese):
    title = get_title_indicator(selected_indicator)
    if selected_indicator == "smoke":
        if selected_gender == "women":
            title += " (Women)"
        elif selected_gender == "men":
            title += " (Men)"
        else:
        df_to_use = df_overobese
            title += " (Men+Women)"
    elif selected_indicator == "obese":
        if selected_obese == "measured":
            title += " (Measured)"
        elif selected_obese == "reported":
            title += " (Self-reported)"
    
    make_visible = False
    for year in range(df_to_use["TIME"].min(), df_to_use["TIME"].max(), 1):
        df_to_use_per_year = df_to_use[df_to_use["TIME"] == year]
        if year == df_to_use["TIME"].max()-1:
            make_visible = True
        fig.add_trace(
            go.Choropleth(
                locations=df_to_use_per_year['LOCATION'],
                z=df_to_use_per_year["Value"],
                text=df_to_use_per_year['LOCATION'],
    return title

def create_choropleth(locations, values, make_visible):
    return go.Choropleth(
            locations=locations,
            z=values,
            text=locations,
            autocolorscale=False,
            reversescale = True,
            colorscale = [
@@ -78,47 +64,143 @@ def update_figure(selected):
            marker={'line': {'color': 'rgb(0,0,0)','width': 0.5}},
            colorbar={"thickness": 20,"len": 0.3,"x": 0,"y": 0.4}, 
            visible=make_visible)
        )
        sorted_df = df_to_use_per_year.sort_values(by='Value', ascending=False)
        horBarChart1.add_trace(go.Bar(
            x=sorted_df["Value"],
            y=sorted_df["LOCATION"],
            orientation='h'))

def create_slider(df_years, choropleth_data):
    steps = []
    for i in range(df_to_use["TIME"].min(), df_to_use["TIME"].max(), 1):
        step = dict(
            method="restyle",
            args=["visible", [False] * len(fig.data)],
            label=i
        )
        step["args"][1][i-df_to_use["TIME"].min()] = True
    for i in range(df_years.min(), df_years.max(), 1):
        step = dict(method="restyle", args=["visible", [False] * len(choropleth_data)], label=i)
        step["args"][1][i-df_years.min()] = True
        steps.append(step)

    sliders = [dict(
    slider = [dict(
        active=len(steps)-1,
        currentvalue={"prefix": "Year: "},
        steps=steps
    )]
    return slider

layout = html.Div([
    html.Div([
        html.H3("Smoking, obesity and alcohol consumption (1960-2017)")], style={'textAlign': "center", "padding-left": 30}),
    html.Div([
        html.Span("Indicator to display: (e.g. Alcohol)", className="six columns",  style={"text-align": "right", "width": "50%", "padding-top": 10, "padding-left": "10%"}),
        dcc.Dropdown(id="value-selected-indicator", value='alcohol', 
            options=[{'label': "Smoking", 'value': 'smoke'}, {'label': "Alcohol", 'value': 'alcohol'}, {'label': "Overweight/Obese", 'value': 'obese'}],
            style={"display": "block", "margin-left": "auto", "margin-right": "auto", "width": "70%"})
        ], 
        className="row"
    ),
    html.Div([
        html.Div([
            html.Span("Gender (Relevant to smoking)", className="six columns",  style={"text-align": "right", "width": "40%", "padding-left": 70}),
            dcc.Dropdown(id="value-selected-gender", value='total', 
                options=[{'label': "Women", 'value': 'women'}, {'label': "Men", 'value': 'men'}, {'label': "Both", 'value': 'total'}],
                style={"display": "block", "margin-left": "auto", "margin-right": "0", "width": "70%", "padding-left": 70})
            ], 
            className="row", style={'font-size': '0.7em', 'float':'left', 'width': '50%'}
        ),
        html.Div([
            html.Span("Measured/self-reported (Relevant to overweight/obese)", className="six columns",  style={"text-align": "right", "width": "40%", "padding-left": 70}),
            dcc.Dropdown(id="value-selected-obese", value='both', 
                options=[{'label': "Measured", 'value': 'measured'}, {'label': "Self-reported", 'value': 'reported'}, {'label': "Both", 'value': 'both'}],
                style={"display": "block", "margin-left": "auto", "margin-right": "auto", "width": "70%", "padding-left": 90},
                className="six columns")
            ], 
            className="row", style={'font-size': '0.7em', 'float':'right', 'width': '50%'}
        )
    ], style={'overflow': 'hidden', 'width': '100%', 'padding-top': 10, 'padding-bottom': '10%'}),
    html.Div([
        dcc.Graph(id="choropleth")], 
        style={'width': '100vh', 'display': 'inline-block',  'vertical-align': 'center'}),
    html.Div([dcc.Graph(id="horizontal-bar", animate=False)], style={'vertical-align': 'center', 'padding-bottom': '10%'}),
    html.Div([
        html.Span("Pick a country", className="six columns",  style={"padding-top": 20, "padding-left": 70}),
        dcc.Dropdown(id="value-selected-country", value='AUS', 
            options=get_labels_for_countries(),
            style={'width': '20vh', "padding-left": 70},
            className="six columns")],
        className="row-2", style={'padding-left': '30%'}
    ),
    html.Div([
        html.Div([
            dcc.Graph(id="obesity-line")], 
            style={'float':'left', 'width': '33%'}),
        html.Div([
            dcc.Graph(id="smoke-line")], 
            style={'float':'left', 'width': '33%'}),
        html.Div([
            dcc.Graph(id="alc-consumption-line")], 
            style={'overflow': 'hidden', 'width': '34%'}),
    ], style={'overflow': 'hidden', 'width': '100%', 'padding-top': 10} )
],  className="container")

    fig3 = go.Figure(go.Bar(
            x=[20, 14, 23],
            y=['giraffes', 'orangutans', 'monkeys'],
            orientation='h'))

@app.callback(
    [Output("choropleth", "figure"), Output("horizontal-bar", "figure"), Output("obesity-line", "figure"),
    Output("smoke-line", "figure"), Output("alc-consumption-line", "figure")],
    [Input("value-selected-indicator", "value"), Input("value-selected-country", "value"),
    Input("value-selected-gender", "value"), Input("value-selected-obese", "value")]
)

def update_figures(selected_indicator, selected_country, selected_gender, selected_obese):
    choropleth = go.Figure()
    horBarChart1 = go.Figure()
    
    if selected_indicator == "smoke":     df_ind = df_smokers
    elif selected_indicator == "alcohol": df_ind = df_alc
    else:                                 df_ind = df_obese
    df_ind_sel = df_ind

    if selected_indicator == "smoke":
        if selected_gender == "women":
            df_ind_sel = df_ind[df_ind["SUBJECT"] == "WOMEN"]
        elif selected_gender == "men":
            df_ind_sel = df_ind[df_ind["SUBJECT"] == "MEN"]
        else:
            df_ind_sel = df_ind[df_ind["SUBJECT"] == "TOT"]
    elif selected_indicator == "obese":
        if selected_obese == "measured":
            df_ind_sel = df_ind[df_ind["SUBJECT"] == "MEASURED"]
        elif selected_obese == "reported":
            df_ind_sel = df_ind[df_ind["SUBJECT"] == "SELFREPORTED"]

    make_visible = False
    for year in range(df_ind_sel["TIME"].min(), df_ind_sel["TIME"].max(), 1):
        df_to_use_per_year = df_ind_sel[df_ind_sel["TIME"] == year]
        if year == df_ind_sel["TIME"].max()-1:
            make_visible = True
        # --- Choropleth -- #
        choropleth.add_trace(create_choropleth(df_to_use_per_year['LOCATION'], df_to_use_per_year['Value'], make_visible))
        
        # --- Horizontal bar chart -- #
        df_dropped = df_to_use_per_year.drop_duplicates(["LOCATION"])
        df_dropped = df_dropped.sort_values(by=['Value'])
        horBarChart1.add_trace(go.Bar(x=df_dropped["Value"], y=df_dropped["LOCATION"], orientation='h', visible=make_visible))
        horBarChart1.update_layout(autosize=False, width=500, height=500, margin=go.layout.Margin(l=50, r=50, b=100, t=100, pad=4))

    sliders = create_slider(df_ind_sel["TIME"], choropleth.data)

    # --- 3 Line charts per country -- #
    df_ = df[df["LOCATION"] == selected_country]
    x1 = df_[(df_["INDICATOR"] == "OVEROBESE")].drop_duplicates(["TIME"]).sort_values(by=["TIME"])
    x2 = df_[(df_["INDICATOR"] == "SMOKERS") & (df_["SUBJECT"] == "TOT")]
    x3 = df_[(df_["INDICATOR"] == "ALCOHOL")]
    fig3 = go.Figure(go.Scatter(x=x1["TIME"], y=x1["Value"], marker_color='royalblue'))
    fig4 = go.Figure(go.Scatter(x=x2["TIME"], y=x2["Value"], marker_color='lightsalmon'))
    fig5 = go.Figure(go.Scatter(x=x3["TIME"], y=x3["Value"], marker_color='lightseagreen'))

    return [
        {"data": fig.data,
        {"data": choropleth.data,
         "layout": go.Layout(
         title=title(selected),height=800,
         geo={
            'showframe': False,
            'showcoastlines': True, 
            'showcountries': True,
            'countrycolor': 'gray'
         },
         sliders=sliders)}, 
         title=get_title(selected_indicator, selected_gender, selected_obese),height=800,
         geo={'showframe': False, 'showcoastlines': True, 'showcountries': True, 'countrycolor': 'gray' }, sliders=sliders)}, 
        {"data": horBarChart1.data, 
         "layout": go.Layout(title="Comparison of countries", yaxis=dict(title="y", tickmode="linear"), sliders=sliders)
         "layout": go.Layout(title=get_title_indicator(selected_indicator) + " | Sorted country comparison", xaxis=dict(title="Year"), yaxis=dict(title="Country"), sliders=sliders)
        },
        {"data": fig3.data, 
         "layout": go.Layout(title="random")}]
         "layout": go.Layout(title=f"Obesity in {selected_country}", xaxis=dict(title="Year"), yaxis=dict(title=get_title_indicator("obese")))},
        {"data": fig4.data, 
         "layout": go.Layout(title=f"Smoking in {selected_country}", xaxis=dict(title="Year"), yaxis=dict(title=get_title_indicator("smoke")))},
        {"data": fig5.data, 
         "layout": go.Layout(title=f"Alcohol consumption in {selected_country}", xaxis=dict(title="Year"), yaxis=dict(title=get_title_indicator("alcohol")))},
    ]

data/oecd-alc.csv

0 → 100644
+2326 −0

File added.

Preview size limit exceeded, changes collapsed.

data/oecd-obese.csv

0 → 100644
+500 −0

File added.

Preview size limit exceeded, changes collapsed.

data/oecd-smokers.csv

0 → 100644
+2372 −0

File added.

Preview size limit exceeded, changes collapsed.

Loading