Py.Cafe

antonymilne/

dash-gapminder-analysis

Dynamic Gapminder Analysis

DocsPricing
  • app.py
  • requirements.txt
app.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
import dash
from dash import dcc, html, Input, Output, State
import plotly.express as px

df = px.data.gapminder()
years = sorted(df["year"].unique())

app = dash.Dash(__name__)

app.layout = html.Div([
    dcc.Slider(id="year", min=years[0], max=years[-1], value=years[0],
               marks={y: str(y) for y in years}, step=None),
    html.Button("▶ Play", id="play"),
    dcc.Interval(id="tick", interval=800, disabled=True),
    dcc.Graph(id="map"),
    dcc.Graph(id="scatter")
])

@app.callback(
    Output("tick", "disabled"),
    Output("play", "children"),
    Input("play", "n_clicks"),
    State("tick", "disabled"),
    prevent_initial_call=True
)
def toggle_play(_, disabled):
    return (not disabled, "⏸ Pause" if disabled else "▶ Play")

@app.callback(
    Output("year", "value"),
    Input("tick", "n_intervals"),
    State("year", "value"),
    prevent_initial_call=True
)
def advance(_, current):
    i = years.index(current)
    return years[(i + 1) % len(years)]

@app.callback(
    Output("map", "figure"),
    Output("scatter", "figure"),
    Input("year", "value")
)
def update_figures(year):
    dfx = df[df["year"] == year]
    map_fig = px.choropleth(dfx, locations="iso_alpha", color="lifeExp",
                            hover_name="country", title=f"Life Expectancy {year}")
    scatter_fig = px.scatter(dfx, x="gdpPercap", y="lifeExp", size="pop",
                             color="continent", hover_name="country",
                             log_x=True, title=f"GDP vs Life Expectancy {year}")
    return map_fig, scatter_fig

if __name__ == "__main__":
    app.run_server(debug=True)