LewisBabong commited on
Commit
ca8cf48
·
verified ·
1 Parent(s): 61932f4

Upload 2 files

Browse files
Files changed (2) hide show
  1. dashboard_roug.py +134 -0
  2. requirements.txt +8 -0
dashboard_roug.py ADDED
@@ -0,0 +1,134 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ import pandas as pd
3
+ import plotly.express as px
4
+ import re # Pour utiliser les expressions régulières
5
+
6
+ # Configuration de la page
7
+ st.set_page_config(page_title="Tableau de Bord Épidémie", layout="wide")
8
+
9
+
10
+ # Fonction pour charger un fichier uploadé (CSV ou Excel)
11
+ def load_uploaded_file(uploaded_file):
12
+ if uploaded_file is not None:
13
+ try:
14
+ if uploaded_file.name.endswith(".csv"):
15
+ df = pd.read_csv(uploaded_file, sep="\t")
16
+ elif uploaded_file.name.endswith((".xlsx", ".xls")):
17
+ df = pd.read_excel(uploaded_file)
18
+ else:
19
+ st.error("Type de fichier non supporté. Veuillez uploader un fichier CSV ou Excel.")
20
+ return None
21
+ return df
22
+ except Exception as e:
23
+ st.error(f"Erreur lors du chargement du fichier : {e}")
24
+ return None
25
+ return None
26
+
27
+
28
+ # Interface pour uploader des fichiers dans la sidebar
29
+ st.sidebar.header("📎 Importer vos Bases Excel")
30
+ uploaded_file1 = st.sidebar.file_uploader("📂 Charger un premier fichier", type=["csv", "xlsx", "xls"])
31
+ uploaded_file2 = st.sidebar.file_uploader("📂 Charger un deuxième fichier", type=["csv", "xlsx", "xls"])
32
+
33
+ # Vérifier que les deux fichiers sont chargés
34
+ if uploaded_file1 is None or uploaded_file2 is None:
35
+ st.warning("Veuillez envoyer les deux bases pour afficher les données.")
36
+ st.stop()
37
+
38
+ # Charger les fichiers
39
+ df_a = load_uploaded_file(uploaded_file1)
40
+ df_b = load_uploaded_file(uploaded_file2)
41
+
42
+ # Identifier quel fichier correspond à quelle structure
43
+ if "periodname" in df_a.columns:
44
+ df2, df1 = df_a.copy(), df_b.copy()
45
+ else:
46
+ df2, df1 = df_b.copy(), df_a.copy()
47
+
48
+ # Harmonisation des colonnes dans df2
49
+ df2.rename(columns={
50
+ "organisationunitname": "DistrictofResidence",
51
+ "periodname": "Semaine_Epi",
52
+ "MAPE16_H_19.Rougeole": "MAPE"
53
+ }, inplace=True)
54
+
55
+ df2["MAPE"] = pd.to_numeric(df2["MAPE"], errors='coerce')
56
+
57
+ # Normalisation de la colonne "Semaine_Epi" pour extraire le chiffre
58
+ df2["Semaine_Epi"] = df2["Semaine_Epi"].astype(str).str.extract(r'(\d+)')[0].astype(int)
59
+
60
+ # Fusion des données sur "DistrictofResidence" et "Semaine_Epi"
61
+ df = pd.merge(df1, df2, on=["DistrictofResidence", "Semaine_Epi"], how="outer")
62
+
63
+ # Titre de l'application
64
+ st.markdown("<h1 style='text-align: center; color: #2C3E50;'>📊 Tableau de Bord de l'Épidémie</h1>",
65
+ unsafe_allow_html=True)
66
+
67
+ # Filtres dans la sidebar
68
+ st.sidebar.header("Filtres")
69
+ districts = st.sidebar.multiselect("🏠 Sélectionner un district", df["DistrictofResidence"].dropna().unique())
70
+ weeks = st.sidebar.multiselect("📅 Sélectionner une semaine", df["Semaine_Epi"].unique())
71
+
72
+ # Filtrage des données
73
+ filtered_df = df.copy()
74
+ if districts:
75
+ filtered_df = filtered_df[filtered_df["DistrictofResidence"].isin(districts)]
76
+ if weeks:
77
+ filtered_df = filtered_df[filtered_df["Semaine_Epi"].isin(weeks)]
78
+
79
+ # Statistiques clés
80
+ st.subheader("📌 Statistiques Clés")
81
+ st.markdown("<hr>", unsafe_allow_html=True)
82
+ col1, col2, col3 = st.columns(3)
83
+ with col1:
84
+ st.metric("🧪 Total IgM+", filtered_df["Igm+"].sum())
85
+ st.metric("📄 Total Line List", filtered_df["Line list"].sum())
86
+ with col2:
87
+ st.metric("❌ Total Rejetés", filtered_df["REJETE"].sum())
88
+ st.metric("🔵 Total MAPE", filtered_df["MAPE"].sum())
89
+ with col3:
90
+ st.metric("🟠 Total Compatibles", filtered_df["Compatible"].sum())
91
+
92
+ # Assurer que les semaines sont de 1 à 10
93
+ all_weeks = pd.DataFrame({"Semaine_Epi": range(1, 11)})
94
+ time_series = filtered_df.groupby("Semaine_Epi")[
95
+ ["Igm+", "REJETE", "Compatible", "Line list", "MAPE"]].sum().reset_index()
96
+ time_series = all_weeks.merge(time_series, on="Semaine_Epi", how="left").fillna(0)
97
+
98
+ # Création du graphique avec affichage des valeurs sur chaque segment
99
+ fig = px.bar(
100
+ time_series,
101
+ x="Semaine_Epi",
102
+ y=["Igm+", "REJETE", "Compatible", "Line list", "MAPE"],
103
+ title="📊 Évolution des différents cas",
104
+ color_discrete_map={
105
+ "Igm+": "red",
106
+ "REJETE": "green",
107
+ "Compatible": "orange",
108
+ "Line list": "yellow",
109
+ "MAPE": "blue"
110
+ },
111
+ barmode="stack",
112
+ text_auto=True # Affiche les valeurs sur chaque bande
113
+ )
114
+ fig.update_layout(
115
+ xaxis=dict(tickmode='array', tickvals=list(range(1, 11)), ticktext=[str(i) for i in range(1, 11)])
116
+ )
117
+
118
+ # Affichage du graphique
119
+ st.plotly_chart(fig, use_container_width=True)
120
+
121
+ # Possibilité de télécharger le graphique sous forme d'image PNG
122
+ # Pour cela, Plotly nécessite l'installation de kaleido : pip install -U kaleido
123
+ img_bytes = fig.to_image(format="png")
124
+ st.download_button(
125
+ label="Télécharger le graphique",
126
+ data=img_bytes,
127
+ file_name="graphique.png",
128
+ mime="image/png"
129
+ )
130
+
131
+ # Affichage des données filtrées dans un tableau
132
+ st.subheader("📋 Données Filtrées")
133
+ st.markdown("<hr>", unsafe_allow_html=True)
134
+ st.dataframe(filtered_df, use_container_width=True)
requirements.txt ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+ streamlit~=1.43.0
2
+ pandas~=2.2.3
3
+ folium~=0.19.5
4
+ streamlit_folium~=0.24.0
5
+ geopy~=2.4.1
6
+ numpy~=2.2.3
7
+ scikit-learn~=1.6.1
8
+ plotly~=6.0.0