File size: 5,754 Bytes
ca8cf48
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
181c458
ca8cf48
 
 
 
 
181c458
 
 
 
ca8cf48
 
 
 
 
 
 
181c458
 
 
 
 
 
 
 
ca8cf48
 
 
 
 
 
 
 
 
 
 
 
 
 
181c458
 
ca8cf48
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
import streamlit as st
import pandas as pd
import plotly.express as px
import re  # Pour utiliser les expressions régulières

# Configuration de la page
st.set_page_config(page_title="Tableau de Bord Épidémie", layout="wide")


# Fonction pour charger un fichier uploadé (CSV ou Excel)
def load_uploaded_file(uploaded_file):
    if uploaded_file is not None:
        try:
            if uploaded_file.name.endswith(".csv"):
                df = pd.read_csv(uploaded_file, sep="\t")
            elif uploaded_file.name.endswith((".xlsx", ".xls")):
                df = pd.read_excel(uploaded_file)
            else:
                st.error("Type de fichier non supporté. Veuillez uploader un fichier CSV ou Excel.")
                return None
            return df
        except Exception as e:
            st.error(f"Erreur lors du chargement du fichier : {e}")
            return None
    return None


# Interface pour uploader des fichiers dans la sidebar
st.sidebar.header("📎 Importer vos Bases Excel")
uploaded_file1 = st.sidebar.file_uploader("📂 Charger un premier fichier", type=["csv", "xlsx", "xls"])
uploaded_file2 = st.sidebar.file_uploader("📂 Charger un deuxième fichier", type=["csv", "xlsx", "xls"])

# Vérifier que les deux fichiers sont chargés
if uploaded_file1 is None or uploaded_file2 is None:
    st.warning("Veuillez envoyer les deux bases pour afficher les données.")
    st.stop()

# Charger les fichiers
df_a = load_uploaded_file(uploaded_file1)
df_b = load_uploaded_file(uploaded_file2)

# Identifier quel fichier correspond à quelle structure
# Celui contenant la colonne "periodname" correspond à df2 (la base avec "organisationunitname")
if "periodname" in df_a.columns:
    df2, df1 = df_a.copy(), df_b.copy()
else:
    df2, df1 = df_b.copy(), df_a.copy()

# Pour df1, on s'assure que la colonne DistrictofResidence est en majuscules et nettoyée
if "DistrictofResidence" in df1.columns:
    df1["DistrictofResidence"] = df1["DistrictofResidence"].str.upper().str.strip()

# Harmonisation des colonnes dans df2
df2.rename(columns={
    "organisationunitname": "DistrictofResidence",
    "periodname": "Semaine_Epi",
    "MAPE16_H_19.Rougeole": "MAPE"
}, inplace=True)

# Nettoyer la colonne DistrictofResidence dans df2 :
# - Suppression du mot-clé "District" ou "district" en début de chaîne (avec insensibilité à la casse)
# - Transformation en majuscules et suppression des espaces inutiles
df2["DistrictofResidence"] = df2["DistrictofResidence"].str.replace(r'^district\s*', '',
                                                                    flags=re.IGNORECASE, regex=True).str.upper().str.strip()


# Conversion de la colonne MAPE en numérique
df2["MAPE"] = pd.to_numeric(df2["MAPE"], errors='coerce')

# Normalisation de la colonne "Semaine_Epi" pour extraire le chiffre
df2["Semaine_Epi"] = df2["Semaine_Epi"].astype(str).str.extract(r'(\d+)')[0].astype(int)

# Fusion des données sur "DistrictofResidence" et "Semaine_Epi"
df = pd.merge(df1, df2, on=["DistrictofResidence", "Semaine_Epi"], how="outer")

# Titre de l'application
st.markdown("<h1 style='text-align: center; color: #2C3E50;'>📊 Tableau de Bord de l'Épidémie</h1>",
            unsafe_allow_html=True)

# Filtres dans la sidebar
st.sidebar.header("Filtres")
districts = st.sidebar.multiselect("🏠 Sélectionner un district", sorted(df["DistrictofResidence"].dropna().unique()))
weeks = st.sidebar.multiselect("📅 Sélectionner une semaine", sorted(df["Semaine_Epi"].unique()))

# Filtrage des données
filtered_df = df.copy()
if districts:
    filtered_df = filtered_df[filtered_df["DistrictofResidence"].isin(districts)]
if weeks:
    filtered_df = filtered_df[filtered_df["Semaine_Epi"].isin(weeks)]

# Statistiques clés
st.subheader("📌 Statistiques Clés")
st.markdown("<hr>", unsafe_allow_html=True)
col1, col2, col3 = st.columns(3)
with col1:
    st.metric("🧪 Total IgM+", filtered_df["Igm+"].sum())
    st.metric("📄 Total Line List", filtered_df["Line list"].sum())
with col2:
    st.metric("❌ Total Rejetés", filtered_df["REJETE"].sum())
    st.metric("🔵 Total MAPE", filtered_df["MAPE"].sum())
with col3:
    st.metric("🟠 Total Compatibles", filtered_df["Compatible"].sum())

# Assurer que les semaines sont de 1 à 10
all_weeks = pd.DataFrame({"Semaine_Epi": range(1, 11)})
time_series = filtered_df.groupby("Semaine_Epi")[
    ["Igm+", "REJETE", "Compatible", "Line list", "MAPE"]].sum().reset_index()
time_series = all_weeks.merge(time_series, on="Semaine_Epi", how="left").fillna(0)

# Création du graphique avec affichage des valeurs sur chaque segment
fig = px.bar(
    time_series,
    x="Semaine_Epi",
    y=["Igm+", "REJETE", "Compatible", "Line list", "MAPE"],
    title="📊 Évolution des différents cas",
    color_discrete_map={
        "Igm+": "red",
        "REJETE": "green",
        "Compatible": "orange",
        "Line list": "yellow",
        "MAPE": "blue"
    },
    barmode="stack",
    text_auto=True  # Affiche les valeurs sur chaque bande
)
fig.update_layout(
    xaxis=dict(tickmode='array', tickvals=list(range(1, 11)), ticktext=[str(i) for i in range(1, 11)])
)

# Affichage du graphique
st.plotly_chart(fig, use_container_width=True)

# Possibilité de télécharger le graphique sous forme d'image PNG
# Pour cela, Plotly nécessite l'installation de kaleido : pip install -U kaleido
img_bytes = fig.to_image(format="png")
st.download_button(
    label="Télécharger le graphique",
    data=img_bytes,
    file_name="graphique.png",
    mime="image/png"
)

# Affichage des données filtrées dans un tableau
st.subheader("📋 Données Filtrées")
st.markdown("<hr>", unsafe_allow_html=True)
st.dataframe(filtered_df, use_container_width=True)