The World Population Dashboard App

Pattern Matching Callbacks – Creating different charts for Data Visualization with callbacks

import dash
from dash import dcc
from dash import html
from dash.dependencies import Input, Output, ALL, State, MATCH, ALLSMALLER
import plotly.express as px
import pandas as pd
import numpy as np
df = pd.read_csv("Documents/Data Science/population.csv")
print(df)
           country    year    population
0             China  2020.0  1.439324e+09
1             China  2019.0  1.433784e+09
2             China  2018.0  1.427648e+09
3             China  2017.0  1.421022e+09
4             China  2016.0  1.414049e+09
...             ...     ...           ...
4180  United States  1965.0  1.997337e+08
4181  United States  1960.0  1.867206e+08
4182  United States  1955.0  1.716853e+08
4183          India  1960.0  4.505477e+08
4184          India  1955.0  4.098806e+08

[4185 rows x 3 columns]
# dropping null values
df = df.dropna()
print(df.head(10))
  country    year    population
0   China  2020.0  1.439324e+09
1   China  2019.0  1.433784e+09
2   China  2018.0  1.427648e+09
3   China  2017.0  1.421022e+09
4   China  2016.0  1.414049e+09
5   China  2015.0  1.406848e+09
6   China  2010.0  1.368811e+09
7   China  2005.0  1.330776e+09
8   China  2000.0  1.290551e+09
9   China  1995.0  1.240921e+09
app = dash.Dash(__name__)
app.layout = html.Div([
    html.H1("The World Population Dashboard with Dynamic Callbacks", style={"textAlign":"center"}),
    html.Hr(),
    html.P("Add as many charts for Data Visualization:"),
    html.Div(children=[
        html.Button('Add Chart', id='add-chart', n_clicks=0),
    ]),
    html.Div(id='container', children=[])
])
@app.callback(
    Output('container', 'children'),
    [Input('add-chart', 'n_clicks')],
    [State('container', 'children')]
)
def display_graphs(n_clicks, div_children):
    new_child = html.Div(
        style={'width': '45%', 'display': 'inline-block', 'outline': 'thin lightgrey solid', 'padding': 10},
        children=[
            dcc.Graph(
                id={
                    'type': 'dynamic-graph',
                    'index': n_clicks
                },
                figure={}
            ),
            dcc.RadioItems(
                id={
                    'type': 'dynamic-choice',
                    'index': n_clicks
                },
                options=[{'label': 'Bar Chart', 'value': 'bar'},
                         {'label': 'Line Chart', 'value': 'line'},
                         {'label': 'Scatter Chart', 'value': 'scatter'},
                         {'label': 'Pie Chart', 'value': 'pie'}],
                value='bar',
            ),
            dcc.Dropdown(
                id={
                    'type': 'dynamic-dpn-s',
                    'index': n_clicks
                },
                options=[{'label': s, 'value': s} for s in np.sort(df['country'].unique())],
                multi=True,
                value=["United States", "China"],
            ),
            dcc.Dropdown(
                id={
                    'type': 'dynamic-dpn-ctg',
                    'index': n_clicks
                },
                options=[{'label': c, 'value': c} for c in ['country']],
                value='country',
                clearable=False
            ),
            dcc.Dropdown(
                id={
                    'type': 'dynamic-dpn-num',
                    'index': n_clicks
                },
                options=[{'label': n, 'value': n} for n in ['population']],
                value='population',
                clearable=False
            )
            
        ]
    )
    div_children.append(new_child)
    return div_children
html.Br()
@app.callback(
    Output({'type': 'dynamic-graph', 'index': MATCH}, 'figure'),
    [Input(component_id={'type': 'dynamic-dpn-s', 'index': MATCH}, component_property='value'),
     Input(component_id={'type': 'dynamic-dpn-ctg', 'index': MATCH}, component_property='value'),
     Input(component_id={'type': 'dynamic-dpn-num', 'index': MATCH}, component_property='value'),
     Input({'type': 'dynamic-choice', 'index': MATCH}, 'value')]
)
def update_graph(s_value, ctg_value, num_value, chart_choice):
    print(s_value)
    dff = df[df['country'].isin(s_value)]

    if chart_choice == 'bar':
        dff = dff.groupby([ctg_value], as_index=False)[['population']].sum()
        fig = px.bar(dff, x='country', y=num_value)
        return fig
    elif chart_choice == 'line':
        if len(s_value) == 0:
            return {}
        else:
            dff = dff.groupby([ctg_value, 'year'], as_index=False)[['population']].sum()
            fig = px.line(dff, x='year', y=num_value, color=ctg_value)
            return fig
    elif chart_choice == 'scatter':
        if len(s_value) == 1:
            return {}
        else:
            dff = dff.groupby([ctg_value, 'year'], as_index=False)[['population']].sum()
            fig = px.scatter(dff, x='year', y=num_value, color=ctg_value)
            return fig    
    elif chart_choice == 'pie':
        fig = px.pie(dff, names=ctg_value, values=num_value)
        return fig
if __name__ == '__main__':
    app.run_server(debug=False)
Dash is running on http://127.0.0.1:8050/

 * Serving Flask app "__main__" (lazy loading)
 * Environment: production
   WARNING: This is a development server. Do not use it in a production deployment.
   Use a production WSGI server instead.
 * Debug mode: off
 * Running on http://127.0.0.1:8050/ (Press CTRL+C to quit)
127.0.0.1 - - [21/Nov/2021 04:37:47] "GET / HTTP/1.1" 200 -
127.0.0.1 - - [21/Nov/2021 04:37:47] "GET /_favicon.ico?v=2.0.0 HTTP/1.1" 200 -
127.0.0.1 - - [21/Nov/2021 04:37:47] "GET /_dash-layout HTTP/1.1" 200 -
127.0.0.1 - - [21/Nov/2021 04:37:47] "GET /_dash-dependencies HTTP/1.1" 200 -
127.0.0.1 - - [21/Nov/2021 04:37:47] "POST /_dash-update-component HTTP/1.1" 200 -
127.0.0.1 - - [21/Nov/2021 04:37:47] "GET /_dash-component-suites/dash/dcc/async-graph.js HTTP/1.1" 200 -
127.0.0.1 - - [21/Nov/2021 04:37:47] "GET /_dash-component-suites/dash/dcc/async-plotlyjs.js HTTP/1.1" 200 -
127.0.0.1 - - [21/Nov/2021 04:37:47] "GET /_dash-component-suites/dash/dcc/async-dropdown.js HTTP/1.1" 200 -
['United States', 'China']
127.0.0.1 - - [21/Nov/2021 04:37:48] "POST /_dash-update-component HTTP/1.1" 200 -
127.0.0.1 - - [21/Nov/2021 04:38:01] "POST /_dash-update-component HTTP/1.1" 200 -
127.0.0.1 - - [21/Nov/2021 04:38:01] "POST /_dash-update-component HTTP/1.1" 200 -
127.0.0.1 - - [21/Nov/2021 04:38:01] "POST /_dash-update-component HTTP/1.1" 200 -
['United States', 'China']
['United States', 'China']
127.0.0.1 - - [21/Nov/2021 04:38:04] "POST /_dash-update-component HTTP/1.1" 200 -
127.0.0.1 - - [21/Nov/2021 04:38:04] "POST /_dash-update-component HTTP/1.1" 200 -
127.0.0.1 - - [21/Nov/2021 04:38:04] "POST /_dash-update-component HTTP/1.1" 200 -
['United States', 'China']
['United States', 'China']
['United States', 'China']
127.0.0.1 - - [21/Nov/2021 04:38:04] "POST /_dash-update-component HTTP/1.1" 200 -
127.0.0.1 - - [21/Nov/2021 04:38:05] "POST /_dash-update-component HTTP/1.1" 200 -
127.0.0.1 - - [21/Nov/2021 04:38:05] "POST /_dash-update-component HTTP/1.1" 200 -
127.0.0.1 - - [21/Nov/2021 04:38:05] "POST /_dash-update-component HTTP/1.1" 200 -
['United States', 'China']
['United States', 'China']
['United States', 'China']
['United States', 'China']
127.0.0.1 - - [21/Nov/2021 04:38:05] "POST /_dash-update-component HTTP/1.1" 200 -
127.0.0.1 - - [21/Nov/2021 04:38:05] "POST /_dash-update-component HTTP/1.1" 200 -
127.0.0.1 - - [21/Nov/2021 04:38:09] "POST /_dash-update-component HTTP/1.1" 200 -
['United States', 'China']
127.0.0.1 - - [21/Nov/2021 04:38:18] "POST /_dash-update-component HTTP/1.1" 200 -
['United States', 'China']
127.0.0.1 - - [21/Nov/2021 04:38:24] "POST /_dash-update-component HTTP/1.1" 200 -
['United States', 'China']
127.0.0.1 - - [21/Nov/2021 04:38:39] "POST /_dash-update-component HTTP/1.1" 200 -
['United States', 'China', 'India']
127.0.0.1 - - [21/Nov/2021 04:38:53] "POST /_dash-update-component HTTP/1.1" 200 -
['United States', 'China', 'India', 'Nigeria']
127.0.0.1 - - [21/Nov/2021 04:39:14] "POST /_dash-update-component HTTP/1.1" 200 -
['United States', 'China', 'India', 'Nigeria', 'Russia']
127.0.0.1 - - [21/Nov/2021 04:39:26] "POST /_dash-update-component HTTP/1.1" 200 -
['United States', 'China', 'India']
127.0.0.1 - - [21/Nov/2021 04:39:30] "POST /_dash-update-component HTTP/1.1" 200 -
['United States', 'China', 'India', 'Nigeria']
127.0.0.1 - - [21/Nov/2021 04:39:37] "POST /_dash-update-component HTTP/1.1" 200 -
['United States', 'China', 'India', 'Nigeria', 'Russia']
127.0.0.1 - - [21/Nov/2021 04:39:51] "POST /_dash-update-component HTTP/1.1" 200 -
['United States', 'China', 'India']
127.0.0.1 - - [21/Nov/2021 04:40:06] "POST /_dash-update-component HTTP/1.1" 200 -
['United States', 'China', 'India', 'Nigeria']
127.0.0.1 - - [21/Nov/2021 04:40:12] "POST /_dash-update-component HTTP/1.1" 200 -
['United States', 'China', 'India', 'Nigeria', 'Russia']
127.0.0.1 - - [21/Nov/2021 04:40:20] "POST /_dash-update-component HTTP/1.1" 200 -
['United States', 'China', 'India']
127.0.0.1 - - [21/Nov/2021 04:40:26] "POST /_dash-update-component HTTP/1.1" 200 -
['United States', 'China', 'India', 'Nigeria']
127.0.0.1 - - [21/Nov/2021 04:40:33] "POST /_dash-update-component HTTP/1.1" 200 -
['United States', 'China', 'India', 'Nigeria', 'Russia']

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s