jaimalklyde commited on
Commit
64bbd81
·
verified ·
1 Parent(s): db5e703

Update src/module/Data_Exploration.py

Browse files
Files changed (1) hide show
  1. 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
- df_res = self.get_df('ressources')
 
 
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
- # On filtre les scénarios 'Normal' pour voir le contraste
217
- top_scenarios = df_res['scenario'].value_counts().head(5).index.tolist()
218
- df_filtered = df_res[df_res['scenario'].isin(top_scenarios)]
219
-
220
- fig_box = px.box(df_filtered, x='scenario', y='taux_occupation', color='scenario',
221
- title="Distribution du Taux d'Occupation par Type de Crise",
222
- points="outliers")
223
- st.plotly_chart(fig_box, use_container_width=True)
 
 
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
- fig_scatter = px.scatter(df_res, x='taux_occupation', y='tension_personnel',
230
- color='service_code', size='lits_total',
231
- hover_data=['date', 'scenario'],
232
- title="Zone de Danger : Tension > 80%",
233
- trendline="ols") # Nécessite statsmodels, sinon retirer trendline
234
-
235
- # Ajout zones de danger
236
- fig_scatter.add_hrect(y0=0.8, y1=1.5, line_width=0, fillcolor="red", opacity=0.1, annotation_text="Danger RH")
237
- fig_scatter.add_vrect(x0=0.9, x1=1.5, line_width=0, fillcolor="orange", opacity=0.1, annotation_text="Saturation Lits")
238
-
239
- st.plotly_chart(fig_scatter, use_container_width=True)
 
 
 
 
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("""