Spaces:
Sleeping
Sleeping
Update src/module/Data_Exploration.py
Browse files- src/module/Data_Exploration.py +45 -21
src/module/Data_Exploration.py
CHANGED
|
@@ -198,45 +198,69 @@ class DataExplorer:
|
|
| 198 |
|
| 199 |
fig_week = px.bar(df_week, title="Moyenne par Jour", color=df_week.values, color_continuous_scale="Blues")
|
| 200 |
st.plotly_chart(fig_week, use_container_width=True)
|
|
|
|
| 201 |
|
| 202 |
# ==========================================================================
|
| 203 |
-
# 3. STRESS-TEST SCÉNARIOS & DMS
|
| 204 |
# ==========================================================================
|
| 205 |
def tab_stress_scenarios(self):
|
| 206 |
st.markdown("### 🌪️ Impact des Scénarios de Crise")
|
| 207 |
st.caption("Corrélation entre les types de scénarios (Covid, Grippe) et la tension hospitalière.")
|
| 208 |
|
| 209 |
-
|
|
|
|
|
|
|
| 210 |
if df_res is None or 'scenario' not in df_res.columns:
|
| 211 |
st.warning("Données ressources ou scénarios manquantes.")
|
| 212 |
return
|
| 213 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 214 |
# 1. Boxplot Taux d'Occupation par Scénario
|
| 215 |
st.markdown("#### Saturation des Lits par Scénario")
|
| 216 |
-
|
| 217 |
-
|
| 218 |
-
|
| 219 |
-
|
| 220 |
-
|
| 221 |
-
|
| 222 |
-
|
| 223 |
-
|
|
|
|
|
|
|
| 224 |
|
| 225 |
# 2. Corrélation Tension Personnel vs Occupation
|
| 226 |
st.markdown("#### Corrélation : Occupation Lits vs Tension Personnel")
|
| 227 |
col1, col2 = st.columns([3, 1])
|
| 228 |
with col1:
|
| 229 |
-
|
| 230 |
-
|
| 231 |
-
|
| 232 |
-
|
| 233 |
-
|
| 234 |
-
|
| 235 |
-
|
| 236 |
-
|
| 237 |
-
|
| 238 |
-
|
| 239 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 240 |
|
| 241 |
with col2:
|
| 242 |
st.info("""
|
|
|
|
| 198 |
|
| 199 |
fig_week = px.bar(df_week, title="Moyenne par Jour", color=df_week.values, color_continuous_scale="Blues")
|
| 200 |
st.plotly_chart(fig_week, use_container_width=True)
|
| 201 |
+
|
| 202 |
|
| 203 |
# ==========================================================================
|
| 204 |
+
# 3. STRESS-TEST SCÉNARIOS & DMS (CORRIGÉ)
|
| 205 |
# ==========================================================================
|
| 206 |
def tab_stress_scenarios(self):
|
| 207 |
st.markdown("### 🌪️ Impact des Scénarios de Crise")
|
| 208 |
st.caption("Corrélation entre les types de scénarios (Covid, Grippe) et la tension hospitalière.")
|
| 209 |
|
| 210 |
+
# On récupère une COPIE pour ne pas casser l'original si on modifie
|
| 211 |
+
df_res = self.get_df('ressources').copy() if self.get_df('ressources') is not None else None
|
| 212 |
+
|
| 213 |
if df_res is None or 'scenario' not in df_res.columns:
|
| 214 |
st.warning("Données ressources ou scénarios manquantes.")
|
| 215 |
return
|
| 216 |
|
| 217 |
+
# --- CORRECTION CRITIQUE DES TYPES ---
|
| 218 |
+
# On force la conversion en nombres. Tout ce qui n'est pas un chiffre devient NaN (vide)
|
| 219 |
+
cols_numeriques = ['taux_occupation', 'tension_personnel', 'lits_total']
|
| 220 |
+
for col in cols_numeriques:
|
| 221 |
+
if col in df_res.columns:
|
| 222 |
+
df_res[col] = pd.to_numeric(df_res[col], errors='coerce')
|
| 223 |
+
|
| 224 |
+
# On supprime les lignes qui ont des NaN dans ces colonnes critiques
|
| 225 |
+
# Cela évite le crash de Plotly
|
| 226 |
+
df_clean = df_res.dropna(subset=cols_numeriques)
|
| 227 |
+
|
| 228 |
+
if df_clean.empty:
|
| 229 |
+
st.error("Aucune donnée valide disponible après nettoyage des colonnes numériques.")
|
| 230 |
+
return
|
| 231 |
+
|
| 232 |
# 1. Boxplot Taux d'Occupation par Scénario
|
| 233 |
st.markdown("#### Saturation des Lits par Scénario")
|
| 234 |
+
try:
|
| 235 |
+
top_scenarios = df_clean['scenario'].value_counts().head(5).index.tolist()
|
| 236 |
+
df_filtered = df_clean[df_clean['scenario'].isin(top_scenarios)]
|
| 237 |
+
|
| 238 |
+
fig_box = px.box(df_filtered, x='scenario', y='taux_occupation', color='scenario',
|
| 239 |
+
title="Distribution du Taux d'Occupation par Type de Crise",
|
| 240 |
+
points="outliers")
|
| 241 |
+
st.plotly_chart(fig_box, use_container_width=True)
|
| 242 |
+
except Exception as e:
|
| 243 |
+
st.warning(f"Erreur affichage Boxplot : {e}")
|
| 244 |
|
| 245 |
# 2. Corrélation Tension Personnel vs Occupation
|
| 246 |
st.markdown("#### Corrélation : Occupation Lits vs Tension Personnel")
|
| 247 |
col1, col2 = st.columns([3, 1])
|
| 248 |
with col1:
|
| 249 |
+
try:
|
| 250 |
+
# Note: J'ai retiré trendline="ols" par sécurité car il nécessite le module 'statsmodels'
|
| 251 |
+
# Si vous l'avez, vous pouvez le remettre.
|
| 252 |
+
fig_scatter = px.scatter(df_clean, x='taux_occupation', y='tension_personnel',
|
| 253 |
+
color='service_code', size='lits_total',
|
| 254 |
+
hover_data=['date', 'scenario'],
|
| 255 |
+
title="Zone de Danger : Tension > 80%")
|
| 256 |
+
|
| 257 |
+
# Ajout zones de danger
|
| 258 |
+
fig_scatter.add_hrect(y0=0.8, y1=1.5, line_width=0, fillcolor="red", opacity=0.1, annotation_text="Danger RH")
|
| 259 |
+
fig_scatter.add_vrect(x0=0.9, x1=1.5, line_width=0, fillcolor="orange", opacity=0.1, annotation_text="Saturation Lits")
|
| 260 |
+
|
| 261 |
+
st.plotly_chart(fig_scatter, use_container_width=True)
|
| 262 |
+
except Exception as e:
|
| 263 |
+
st.error(f"Erreur Scatter Plot : {e}")
|
| 264 |
|
| 265 |
with col2:
|
| 266 |
st.info("""
|