import dash import dash_mantine_components as dmc import plotly.express as px from dash import Input, Output, callback, dcc, html from dash_iconify import DashIconify app = dash.Dash(__name__) server = app.server df = px.data.gapminder() def create_scatter_plot(selected_year, selected_continent=None): filtered_df = df[df["year"] == selected_year] if selected_continent and selected_continent != "All": filtered_df = filtered_df[filtered_df["continent"] == selected_continent] fig = px.scatter( filtered_df, x="gdpPercap", y="lifeExp", size="pop", color="continent", hover_name="country", log_x=True, size_max=60, title=f"Life Expectancy vs GDP per Capita ({selected_year})", ) fig.update_layout( template="plotly_dark", paper_bgcolor="rgba(0,0,0,0)", plot_bgcolor="rgba(0,0,0,0)", ) return fig def create_line_chart(selected_country): country_data = df[df["country"] == selected_country] fig = px.line( country_data, x="year", y="lifeExp", title=f"{selected_country} - Life Expectancy", ) fig.update_layout( template="plotly_dark", paper_bgcolor="rgba(0,0,0,0)", plot_bgcolor="rgba(0,0,0,0)", ) return fig def create_bar_chart(selected_year): year_data = df[df["year"] == selected_year] continent_stats = year_data.groupby("continent")["lifeExp"].mean().reset_index() fig = px.bar( continent_stats, x="continent", y="lifeExp", color="continent", title=f"Average Life Expectancy by Continent ({selected_year})", ) fig.update_layout( template="plotly_dark", paper_bgcolor="rgba(0,0,0,0)", plot_bgcolor="rgba(0,0,0,0)", showlegend=False, ) return fig def create_datacard(title, value, icon, color): return dmc.Card( [ dmc.Group( [ DashIconify(icon=icon, width=30, color=color), html.Div( [ dmc.Text(value, size="xl", fw=700, c="white"), dmc.Text(title, size="sm", c="dimmed"), ] ), ], align="center", gap="md", ) ], p="md", className="datacard", ) app.layout = dmc.MantineProvider( [ html.Link( href="https://fonts.googleapis.com/css2?family=Outfit:wght@100..900&display=swap", rel="stylesheet", ), dmc.Group( [ DashIconify(icon="twemoji:globe-with-meridians", width=45), dmc.Text( "Gapminder World Data Explorer", ml=10, size="xl", fw=900, c="white" ), ], align="center", className="header", mb="md", ), dmc.Grid( [ dmc.GridCol( [ dmc.Stack( [ dmc.Card( [ dmc.Text("Controls", size="lg", mb="md"), dmc.Stack( [ html.Div( [ dmc.Text( "Year:", size="sm", mb=5 ), dmc.Slider( id="year-slider", min=1952, max=2007, step=5, value=2007, marks=[ { "value": year, "label": str(year), } for year in [ 1952, 1967, 1982, 1997, 2007, ] ], ), ] ), html.Div( [ dmc.Text( "Continent Filter:", size="sm", mb=5, ), dmc.Select( id="continent-dropdown", data=[ { "value": "All", "label": "All Continents", } ] + [ { "value": cont, "label": cont, } for cont in sorted( df[ "continent" ].unique() ) ], value="All", ), ] ), html.Div( [ dmc.Text( "Select Country:", size="sm", mb=5, ), dmc.Select( id="country-dropdown", data=[ { "value": country, "label": country, } for country in sorted( df[ "country" ].unique() ) ], value="United States", searchable=True, ), ] ), ], gap="lg", ), ], p="md", className="control-card", ) ] ) ], span=3, ), dmc.GridCol( [ dmc.Stack( [ html.Div(id="stats-cards"), dmc.Card( [dcc.Graph(id="scatter-plot")], p="sm", className="chart-card", ), ], gap="md", ) ], span=9, ), ], gutter="md", ), dmc.Grid( [ dmc.GridCol( [ dmc.Card( [dcc.Graph(id="line-chart")], p="sm", className="chart-card" ) ], span=6, ), dmc.GridCol( [ dmc.Card( [dcc.Graph(id="bar-chart")], p="sm", className="chart-card" ) ], span=6, ), ], gutter="md", mt="md", ), ], forceColorScheme="dark", theme={"colorScheme": "dark"}, ) @callback( Output("scatter-plot", "figure"), [Input("year-slider", "value"), Input("continent-dropdown", "value")], ) def update_scatter_plot(selected_year, selected_continent): return create_scatter_plot(selected_year, selected_continent) @callback(Output("line-chart", "figure"), Input("country-dropdown", "value")) def update_line_chart(selected_country): return create_line_chart(selected_country) @callback(Output("bar-chart", "figure"), Input("year-slider", "value")) def update_bar_chart(selected_year): return create_bar_chart(selected_year) @callback(Output("stats-cards", "children"), Input("year-slider", "value")) def update_stats(selected_year): year_data = df[df["year"] == selected_year] avg_life_exp = round(year_data["lifeExp"].mean(), 1) total_pop = year_data["pop"].sum() num_countries = len(year_data) avg_gdp = round(year_data["gdpPercap"].mean(), 0) return dmc.Grid( [ dmc.GridCol( create_datacard( "Life Expectancy", f"{avg_life_exp} years", "mdi:heart-pulse", "#ff6b35", ), span=3, ), dmc.GridCol( create_datacard( "Population", f"{total_pop / 1e9:.1f}B", "mdi:account-group", "#1f77b4", ), span=3, ), dmc.GridCol( create_datacard( "Countries", str(num_countries), "mdi:earth", "#2ca02c" ), span=3, ), dmc.GridCol( create_datacard( "GDP per Capita", f"${avg_gdp:,.0f}", "mdi:currency-usd", "#d62728" ), span=3, ), ], gutter="sm", ) if __name__ == "__main__": app.run(debug=True, port=8050)