import altair as alt
import pandas as pd
import plotly.graph_objects as go
import streamlit as st
from src.helper_functions import custom_metric_box, pollution_box
from src.predict import get_data_and_predictions
st.set_page_config(
page_title="Utrecht Pollution Dashboard",
page_icon="🌱",
layout="wide",
initial_sidebar_state="expanded",
)
alt.themes.enable("dark")
model_NO2, model_O3 = load_models()
week_data, predictions_O3, predictions_NO2 = get_data_and_predictions()
today = week_data.iloc[-1]
previous_day = week_data.iloc[-2]
dates_past = pd.date_range(end=pd.Timestamp.today(), periods=8).to_list()
dates_future = pd.date_range(
start=pd.Timestamp.today() + pd.Timedelta(days=1), periods=3
).to_list()
# O3 and NO2 values for the past 7 days
o3_past_values = week_data["O3"]
no2_past_values = week_data["NO2"]
o3_future_values = pd.Series(predictions_O3[0].flatten())
no2_future_values = pd.Series(predictions_NO2[0].flatten())
o3_values = pd.concat([o3_past_values, o3_future_values], ignore_index=True)
no2_values = pd.concat([no2_past_values, no2_future_values], ignore_index=True)
dates = dates_past + dates_future
df = pd.DataFrame({"Date": dates, "O3": o3_values, "NO2": no2_values})
# App Title
st.title("Utrecht Pollution Dashboard🌱")
col1, col2 = st.columns((2, 3))
# Create a 3-column layout
with col1:
st.subheader("Current Weather")
subcol1, subcol2 = st.columns((1, 1))
with subcol1:
custom_metric_box(
label="Temperature",
value=f"{round(today['mean_temp'] * 0.1)} °C",
delta=f"{round(today['mean_temp'] * 0.1) - round(previous_day['mean_temp'] * 0.1)} °C",
)
custom_metric_box(
label="Humidity",
value=f"{round(today['humidity'])} %",
delta=f"{round(today['humidity']) - round(previous_day['humidity'])} %",
)
custom_metric_box(
label="Pressure",
value=f"{round(today['pressure'] * 0.1)} hPa",
delta=f"{round(today['pressure'] * 0.1) - round(previous_day['pressure'] * 0.1)} hPa",
)
with subcol2:
custom_metric_box(
label="Precipitation",
value=f"{round(today['percipitation'] * 0.1)} mm",
delta=f"{round(today['percipitation'] * 0.1) - round(previous_day['percipitation'] * 0.1)} mm",
)
custom_metric_box(
label="Solar Radiation",
value=f"{round(today['global_radiation'])} J/m²",
delta=f"{round(today['global_radiation']) - round(previous_day['global_radiation'])} J/m²",
)
custom_metric_box(
label="Wind Speed",
value=f"{round(today['wind_speed'] * 0.1, 1)} m/s",
delta=f"{round(today['wind_speed'] * 0.1, 1) - round(previous_day['wind_speed'] * 0.1, 1)} m/s",
)
with col2:
st.subheader("Current Pollution Levels")
sub1, sub2 = st.columns((1, 1))
# Display the prediction
# st.write(f'Predicted Pollution Level: {prediction[0]:.2f}')
with sub1:
pollution_box(
label="O3",
value=f"{round(today['O3'])} µg/m³",
delta=f"{round(int(today['O3']) - int(previous_day['O3']))} µg/m³",
)
with st.expander("Learn more about O3", expanded=False):
st.markdown(
"*Ozone (O3)*: A harmful gas at ground level, contributing to respiratory issues and aggravating asthma.",
unsafe_allow_html=True,
)
with sub2:
pollution_box(
label="NO2",
value=f"{round(today['NO2'])} µg/m³",
delta=f"{round(int(today['NO2']) - int(previous_day['NO2']))} µg/m³",
)
with st.expander("Learn more about O3", expanded=False):
st.markdown(
"*Wadeva particle (NO2)*: A harmful gas at ground level, contributing to respiratory issues and aggravating asthma.",
unsafe_allow_html=True,
)
# Create two columns for two separate graphs
# Plot O3 in the first subcolumn
st.subheader("O3 and NO2 Prediction")
# Plot NO2 in the second subcolumn
fig_o3 = go.Figure()
fig_o3.add_trace(
go.Scatter(
x=df["Date"],
y=df["O3"],
mode="lines+markers",
name="O3",
line=dict(color="rgb(0, 191, 255)", width=4),
hovertemplate="%{x|%d-%b-%Y}
%{y} µg/m³",
)
)
fig_o3.add_shape(
dict(
type="line",
x0=pd.Timestamp.today(),
x1=pd.Timestamp.today(),
y0=min(o3_values),
y1=max(o3_values),
line=dict(color="White", width=3, dash="dash"),
)
)
fig_o3.update_layout(
plot_bgcolor="rgba(0, 0, 0, 0)",
paper_bgcolor="rgba(0, 0, 0, 0)",
yaxis_title="O3 Concentration (µg/m³)",
font=dict(size=14),
hovermode="x",
xaxis=dict(
title="Date",
type="date",
tickmode="array",
tickvals=df["Date"],
tickformat="%d-%b",
tickangle=-45,
tickcolor="gray",
),
)
st.plotly_chart(fig_o3, key="fig_o3")
fig_no2 = go.Figure()
fig_no2.add_trace(
go.Scatter(
x=df["Date"],
y=df["NO2"],
mode="lines+markers",
name="NO2",
line=dict(color="rgb(255, 20, 147)", width=4),
)
)
fig_no2.add_shape(
dict(
type="line",
x0=pd.Timestamp.today(),
x1=pd.Timestamp.today(),
y0=min(no2_values),
y1=max(no2_values),
line=dict(color="gray", width=3, dash="dash"),
)
)
fig_no2.update_layout(
plot_bgcolor="rgba(0, 0, 0, 0)",
paper_bgcolor="rgba(0, 0, 0, 0)",
yaxis_title="NO2 Concentration (µg/m³)",
font=dict(size=14),
hovermode="x",
xaxis=dict(
title="Date",
type="date",
tickmode="array",
tickvals=df["Date"],
tickformat="%d-%b",
tickangle=-45,
tickcolor="gray",
),
)
st.plotly_chart(fig_no2, key="fig_no2")