streamlit_app / streamlit /pages /Predictions.py
martper56's picture
import streamlit code from streamlit branch
632ab6a
import streamlit as st
import boto3
import pandas as pd
import json
import matplotlib.pyplot as plt
# Titre de la page
st.title("Predictions - ville de Rennes")
# Paramètres S3 (à adapter ou utiliser variables d'environnement pour plus de sécurité)
AWS_ACCESS_KEY_ID = "AKIAQJXL2QR4KZ2RZYW4"
AWS_SECRET_ACCESS_KEY = "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"
BUCKET_NAME = "jedha-quality-air"
PREFIX = "datasets/output/"
# FILE_KEY = "datasets/output/20250711-064810_prediction_data.json"
# @st.cache_data(show_spinner=True)
def load_data_from_s3():
s3 = boto3.client(
"s3",
aws_access_key_id=AWS_ACCESS_KEY_ID,
aws_secret_access_key=AWS_SECRET_ACCESS_KEY,
)
response = s3.list_objects_v2(Bucket=BUCKET_NAME, Prefix=PREFIX)
# Vérifie s'il y a des objets
if "Contents" in response:
# Trie les objets par date de dernière modification (LastModified)
latest_file = max(response["Contents"], key=lambda x: x["LastModified"])
latest_key = latest_file["Key"]
# Récupère l'objet
latest_object = s3.get_object(Bucket=BUCKET_NAME, Key=latest_key)
content = latest_object["Body"].read().decode("utf-8")
print("Latest file key:", latest_key)
else:
print("Aucun fichier trouvé dans ce dossier.")
# response = s3.get_object(Bucket=BUCKET_NAME, Key=FILE_KEY)
# content = response["Body"].read().decode("utf-8")
data = json.loads(content)
# Extraction date et heure du nom fichier
filename = latest_key.split("/")[-1]
datetime_str = filename.split("_")[0] # "20250711-064810"
date_str = datetime_str[:8]
time_str = datetime_str[9:]
formatted_date = pd.to_datetime(date_str, format="%Y%m%d").date()
formatted_time = pd.to_datetime(time_str, format="%H%M%S").time()
df = pd.DataFrame([data])
df["date"] = formatted_date
df["heure UTC"] = formatted_time
return df, formatted_date, formatted_time
# Chargement des données
df, formatted_date, formatted_time = load_data_from_s3()
pollution_seuils = {
"PM25": [
(0, 10, "#4ee3dc", "Bon"),
(10, 20, "#53c8b5", "Moyen"),
(20, 25, "#f3dd57", "Dégradé"),
(25, 50, "#f47d61", "Mauvais"),
(50, 75, "#b22133", "Très mauvais"),
(75, float("inf"), "#7d2e8e", "Extrêmement mauvais"),
],
"PM10": [
(0, 20, "#4ee3dc", "Bon"),
(20, 40, "#53c8b5", "Moyen"),
(40, 50, "#f3dd57", "Dégradé"),
(50, 100, "#f47d61", "Mauvais"),
(100, 150, "#b22133", "Très mauvais"),
(150, float("inf"), "#7d2e8e", "Extrêmement mauvais"),
],
"NOX": [
(0, 40, "#4ee3dc", "Bon"),
(40, 90, "#53c8b5", "Moyen"),
(90, 120, "#f3dd57", "Dégradé"),
(120, 230, "#f47d61", "Mauvais"),
(230, 340, "#b22133", "Très mauvais"),
(340, float("inf"), "#7d2e8e", "Extrêmement mauvais"),
],
"O3": [
(0, 50, "#4ee3dc", "Bon"),
(50, 100, "#53c8b5", "Moyen"),
(100, 130, "#f3dd57", "Dégradé"),
(130, 240, "#f47d61", "Mauvais"),
(240, 380, "#b22133", "Très mauvais"),
(380, float("inf"), "#7d2e8e", "Extrêmement mauvais"),
],
}
# Fonction pour récupérer la couleur selon les seuils
def get_pollution_color(polluant, valeur):
seuils = pollution_seuils.get(polluant)
for bas, haut, couleur, libelle in seuils:
if bas <= valeur < haut:
return couleur, libelle
return "#cccccc" # fallback gris
# Affichage tableau
st.subheader("Données de prédiction")
st.dataframe(df)
st.markdown("")
st.markdown("")
st.markdown("")
# Création du plot
polluants = ["O3", "NOX", "PM10", "PM25"]
valeurs = [df[col].iloc[0] for col in polluants]
couleurs = ["#8da0cb", "#fc8d62", "#66c2a5", "#a6d854"] # tons pastel et mats
fig, ax = plt.subplots(figsize=(6, 3)) # taille plus compacte
bars = ax.bar(polluants, valeurs, color=couleurs)
# Titre avec date et heure
titre = f"Pollution le {formatted_date} à {formatted_time.strftime('%H:%M:%S')}"
ax.set_title(titre, fontsize=14)
ax.set_xlabel("Polluants", fontsize=12)
ax.set_ylabel("Valeurs", fontsize=12)
# Valeurs sur barres
max_val = max(valeurs)
for bar, val in zip(bars, valeurs):
height = bar.get_height()
ax.text(
bar.get_x() + bar.get_width() / 2,
height + max_val * 0.02,
f"{val:.1f}",
ha="center",
fontsize=8,
)
# Centrage avec colonnes Streamlit
left_co, cent_co, right_co = st.columns([1, 2, 1])
with cent_co:
st.pyplot(fig)
st.subheader("Qualité de l’air")
for i, polluant in enumerate(polluants):
val = valeurs[i]
color, libelle = get_pollution_color(polluant, val)
st.markdown(
f"""
<div style='background-color:{color};padding:10px 15px;
margin:6px 0;border-radius:10px;
color:black;font-weight:bold;font-size:16px;'>
{polluant} : {val:.1f} µg/m³ - {libelle}
</div>
""",
unsafe_allow_html=True
)