from dash import Dash, Input, Output, dcc, html
import dash_bootstrap_components as dbc
import dash_customizable_app_style as dcas
import plotly.express as px
from plotly.graph_objects import Figure
import pandas as pd
from figures import plots
gender_parity_df: pd.DataFrame = pd.read_csv("https://raw.githubusercontent.com/plotly/Figure-Friday/refs/heads/main/2025/week-26/gender-parity-in-managerial-positions.csv")
gender_pay_gap_df: pd.DataFrame = pd.read_csv("https://raw.githubusercontent.com/plotly/Figure-Friday/refs/heads/main/2025/week-26/gender-pay-gap.csv")
labor_product_df: pd.DataFrame = pd.read_csv("https://raw.githubusercontent.com/plotly/Figure-Friday/refs/heads/main/2025/week-26/labor-productivity.csv")
unemployment_df: pd.DataFrame = pd.read_csv("https://raw.githubusercontent.com/plotly/Figure-Friday/refs/heads/main/2025/week-26/unemployment.csv")
parity_grid = plots.create_grid(gender_parity_df, 'parity_grid')
pay_gap_grid = plots.create_grid(gender_pay_gap_df, 'pay_gap_grid')
bor_par_grid = plots.create_grid(labor_product_df, 'bor_par_grid')
unemployment_grid = plots.create_grid(unemployment_df, 'unemployment_grid')
app = Dash ("Figure Friday 2025 week 26", external_stylesheets=[dbc.themes.BOOTSTRAP])
# App layout
app.layout = html.Div(
id = "main_container",
style = {"minHeight": "100vh"},
children = [
dcas.customize_app_selectors(),
html.Div(
id = "main_div",
className = "m-0 p-2 w-100",
children = [
html.Div(
className = "row m-0 p-0",
children = [
html.H1("State of the global labor market", className="p-4 pb-3 fw-bold text-primary mb-0 border-bottom"),
dbc.Row([
dbc.Col(
html.P("Select dataset",
className = 'ms-3 mt-4 fs-5'),
width = 'auto'),
dbc.Col(
dcc.Dropdown(
id = 'dataset',
className = 'text-dark mt-4',
options = ['Gender parity', 'Genter pay gap', 'Labor productivity', 'Unemployment'],
value = 'Labor productivity'),
width = 4),
]),
dbc.Row(id = "dataset_title",
className='text-center fs-4 mt-4'),
# Line
html.Div(
className = "col-6 m-0 p-0",
children = [
dcc.Loading(
children = [
dcc.Store(id={"type": "figure-store", "index": "line"}),
dcc.Graph(id={"type": "graph", "index": "line"}),
]),
]),
# Heatmap
html.Div(
className = "col-6 m-0 p-0",
children = [
dcc.Loading(
children = [
dcc.Store(id={"type": "figure-store", "index": "heatmap"}),
dcc.Graph(id={"type": "graph", "index": "heatmap"}),
])
]),
# Box
html.Div(
className = "col-4 m-0 p-0",
children = [
dcc.Loading(
children = [
dcc.Store(id={"type": "figure-store", "index": "box"}),
dcc.Graph(id={"type": "graph", "index": "box"}),
])
]),
# Bar
html.Div(
className = "col-8 m-0 p-0",
children = [
dcc.Loading(
children = [
dcc.Store(id={"type": "figure-store", "index": "bar"}),
dcc.Graph(id={"type": "graph", "index": "bar"}),
])
]),
# Grid
html.Div(
id = 'dataset_grid',
className ='row m-0 p-0'),
]
),
])
])
@app.callback(
Output({"type": "figure-store", "index": "line"}, 'data'),
Output({"type": "figure-store", "index": "heatmap"}, 'data'),
Output({"type": "figure-store", "index": "box"}, 'data'),
Output({"type": "figure-store", "index": "bar"}, 'data'),
Output('dataset_grid', 'children'),
Output('dataset_title', 'children'),
Input('dataset', 'value')
)
def update_plot(dataset):
if dataset == 'Gender parity':
df = gender_parity_df
dataset_grid = parity_grid
elif dataset == 'Genter pay gap':
df = gender_pay_gap_df
dataset_grid = pay_gap_grid
elif dataset == 'Labor productivity':
df = labor_product_df
dataset_grid = bor_par_grid
else:
df = unemployment_df
dataset_grid = unemployment_grid
dataset_title = html.P(f"{dataset} changes over time")
#Line
fig = px.line(df, x='Year', y=df.columns[1:].tolist())
fig.update_layout(legend_title_text='World Area')
fig.update_xaxes( showline = True,
showgrid = False,
linewidth = 0.5,
linecolor = 'gray',
mirror = False,
zeroline = True)
fig.update_yaxes( showline = True,
showgrid = False,
linewidth = 0.5,
linecolor = 'gray',
mirror = False,
zeroline = True)
columns_to_use = df.columns[1:].tolist()
df_melted = df.melt(id_vars = 'Year',
value_vars = columns_to_use,
var_name = 'World Area',
value_name = 'Value')
years_sorted = sorted(df_melted['Year'].unique())
# Heatmap
heatmap = px.density_heatmap(df_melted,
x='Year',
y='World Area',
z='Value',
color_continuous_scale='Viridis',
nbinsx=len(years_sorted),
category_orders={'Year': years_sorted},
histfunc='avg')
heatmap.update_layout(coloraxis_colorbar=dict(title="% Average"))
heatmap.update_xaxes(type='category', tickangle=45)
# Box
box = px.box(df_melted, x='World Area', y='Value', color='World Area')
box.update_xaxes(type='category', tickangle=45)
box.update_xaxes( showline = True,
showgrid = False,
linewidth = 0.5,
linecolor = 'gray',
mirror = False,
zeroline = True)
box.update_yaxes( showline = True,
showgrid = False,
linewidth = 0.5,
linecolor = 'gray',
mirror = False,
zeroline = True)
# Bar
bar = px.bar(df_melted, x='Year', y='Value', color='World Area', barmode='stack')
bar.update_xaxes(type='category', tickangle=45)
bar.update_xaxes( showline = True,
showgrid = False,
linewidth = 0.5,
linecolor = 'gray',
mirror = False,
zeroline = True)
bar.update_yaxes( showline = True,
showgrid = False,
linewidth = 0.5,
linecolor = 'gray',
mirror = False,
zeroline = True)
return fig.to_dict(), heatmap.to_dict(), box.to_dict(), bar.to_dict(), dataset_grid, dataset_title
if __name__ == "__main__":
app.run(debug=False)