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")