Py.Cafe

zakhtar/

dash-tanzania-schools-temperature

Tanzania Schools Temperature 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
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
import pandas as pd
import numpy as np
from dash import Dash, dcc, html, Input, Output
import dash_bootstrap_components as dbc
import plotly.express as px

# Load and parse CSV with mixed datetime formats
final_df = pd.read_csv('tanzania_schools_merged_cleaned_dates_new.csv')
final_df['Date / Time (UTC)'] = pd.to_datetime(final_df['Date / Time (UTC)'], format='mixed', dayfirst=True, errors='coerce')

# App setup with Bootstrap theme
app = Dash(__name__, external_stylesheets=[dbc.themes.BOOTSTRAP])
app.title = "Tanzania Schools Temperature Dashboard"

# Region and school lists
regions = sorted(final_df['Region'].dropna().unique())
initial_region = regions[0]
schools_by_region = sorted(final_df[final_df['Region'] == initial_region]['School Name'].dropna().unique())

app.layout = dbc.Container([
    dbc.Row([
        dbc.Col(html.H2("📈 Tanzania Schools Temperature Dashboard"), width=12, className="text-center my-4")
    ]),
    
    dbc.Row([
        dbc.Col([
            html.Label("Select Region", className="fw-bold"),
            dcc.Dropdown(
                id='region-dropdown',
                options=[{'label': r, 'value': r} for r in regions],
                value=initial_region,
                clearable=False
            )
        ], md=6),

        dbc.Col([
            html.Label("Select School(s)", className="fw-bold"),
            dcc.Dropdown(
                id='school-dropdown',
                options=[{'label': s, 'value': s} for s in schools_by_region],
                value=[schools_by_region[0]],
                multi=True,
                clearable=False
            )
        ], md=6),
    ], className="mb-4"),

    dbc.Row([
        dbc.Col([
            html.Div(id='temperature-graphs')
        ], width=12)
    ])
], fluid=True)

@app.callback(
    Output('school-dropdown', 'options'),
    Output('school-dropdown', 'value'),
    Input('region-dropdown', 'value')
)
def update_school_dropdown(selected_region):
    filtered_schools = sorted(final_df[final_df['Region'] == selected_region]['School Name'].dropna().unique())
    return [{'label': s, 'value': s} for s in filtered_schools], [filtered_schools[0]] if filtered_schools else []

@app.callback(
    Output('temperature-graphs', 'children'),
    Input('school-dropdown', 'value')
)
def update_graphs(selected_schools):
    if not selected_schools:
        return html.P("No school selected.")
    
    graphs = []
    for school in selected_schools:
        df_school = final_df[final_df['School Name'] == school].sort_values('Date / Time (UTC)').copy()
        df_school['Time Gap'] = df_school['Date / Time (UTC)'].diff().dt.total_seconds()
        df_school.loc[df_school['Time Gap'] > 3600, 'Temperature (°C)'] = np.nan

        fig = px.line(
            df_school,
            x='Date / Time (UTC)',
            y='Temperature (°C)',
            title=f"Temperature Over Time - {school}"
        )

        fig.update_layout(
            xaxis_title='Date / Time (UTC)',
            yaxis_title='Temperature (°C)',
            dragmode='zoom',
            template='plotly_white',
            margin=dict(l=40, r=40, t=60, b=40)
        )

        graphs.append(dcc.Graph(figure=fig))

    return graphs

if __name__ == '__main__':
    app.run(debug=True)