Djohell commited on
Commit
ca70fb4
·
verified ·
1 Parent(s): 7dde96c

Update app2.py

Browse files
Files changed (1) hide show
  1. app2.py +59 -232
app2.py CHANGED
@@ -70,8 +70,8 @@ if "css_injected" not in st.session_state:
70
  st.session_state.css_injected = True
71
 
72
  #-------------------------------------------------------- Configuration AWS S3 ---------------------------------------------------
73
- aws_access_key_id = os.environ.get("AWS_ACCESS_KEY_ID")
74
- aws_secret_access_key = os.environ.get("AWS_SECRET_ACCESS_KEY")
75
  aws_region = "eu-west-3"
76
 
77
  s3 = boto3.client(
@@ -109,20 +109,6 @@ with header:
109
  # ------------------------------- Tabs ---------------------------------------
110
  content = st.container()
111
  with content:
112
- # # CSS des tabs
113
- # st.markdown("""
114
- # <style>
115
- # button[data-baseweb="tab"] {
116
- # font-size: 20px !important;
117
- # font-weight: 600;
118
- # padding: 10px 18px;
119
- # }
120
- # button[data-baseweb="tab"][aria-selected="true"] {
121
- # color: #1f77b4;
122
- # border-bottom: 3px solid #1f77b4;
123
- # }
124
- # </style>
125
- # """, unsafe_allow_html=True)
126
 
127
  page_tabs = st.tabs([
128
  "Notre Projet",
@@ -152,19 +138,6 @@ def load_model_data() -> pd.DataFrame:
152
  st.error(f"❌ Erreur chargement dataset météo : {e}")
153
  return pd.DataFrame()
154
 
155
-
156
- def load_historique_incendies() -> pd.DataFrame:
157
- bucket = "projet-final-lead"
158
- key = "data/historique_incendies_avec_coordonnees.csv"
159
- try:
160
- obj = s3.get_object(Bucket=bucket, Key=key)
161
- df = pd.read_csv(obj['Body'], sep=';', encoding='utf-8')
162
- return df
163
- except Exception as e:
164
- st.error(f"❌ Erreur : {e}")
165
- return pd.DataFrame()
166
-
167
-
168
  def load_casernes() -> pd.DataFrame:
169
 
170
  bucket = "projet-final-lead"
@@ -178,34 +151,6 @@ def load_casernes() -> pd.DataFrame:
178
  st.error(f"❌ Erreur : {e}")
179
  return pd.DataFrame()
180
 
181
-
182
- def load_data() -> pd.DataFrame:
183
-
184
- bucket = "projet-final-lead"
185
- key = "data/Incendies_2006_2024.csv"
186
- try:
187
- obj = s3.get_object(Bucket=bucket, Key=key)
188
- content = obj["Body"].read().decode("utf-8")
189
- df = pd.read_csv(StringIO(content), sep=";", encoding="utf-8", skiprows=3)
190
- return df
191
- except Exception as e:
192
- st.error(f"❌ Erreur : {e}")
193
- return pd.DataFrame()
194
-
195
-
196
- def load_coords() -> pd.DataFrame:
197
-
198
- bucket = "projet-final-lead"
199
- key = "data/coordonnees_villes.csv"
200
- try:
201
- obj = s3.get_object(Bucket=bucket, Key=key)
202
- content = obj["Body"].read().decode("utf-8")
203
- df = pd.read_csv(StringIO(content), sep=",", encoding="utf-8")
204
- return df
205
- except Exception as e:
206
- st.error(f"❌ Erreur : {e}")
207
- return pd.DataFrame()
208
-
209
  #-------------------------------------------------------- Chargement unique du modèle ---------------------------------------------------
210
  mlflow.set_tracking_uri("https://djohell-ml-flow.hf.space")
211
 
@@ -274,16 +219,23 @@ Le Code forestier encadre leur gestion durable pour protéger la biodiversité,
274
 
275
  st.header("🌲 Zoom sur le taux de boisement des différents départements français")
276
 
 
 
 
 
 
 
 
277
  col1, col2, col3 = st.columns([1,1,1])
278
 
279
  with col1:
280
- st.image("images/puits carbone.png", caption="Puits de carbone", width=300)
281
 
282
  with col2:
283
- st.image("images/racines.png", caption="Limitation de l'érosion", width=300)
284
 
285
  with col3:
286
- st.image("images/rayonnement.png", caption="Limitation du rayonnement solaire", width=300)
287
 
288
  st.write("""---""")
289
 
@@ -336,204 +288,79 @@ Le Code forestier encadre leur gestion durable pour protéger la biodiversité,
336
  with page_tabs[1]:
337
  st.subheader("🗺️ 1. Visualisation des incendies entre 2006 et 2024")
338
 
339
- df_model = load_data()
340
- df_coords = load_coords()
341
- df_historique = load_historique_incendies()
342
-
343
- # Vérifications
344
- if df_model.empty:
345
- st.warning("⚠️ Dataset incendies 2006-2024 vide")
346
- if df_coords.empty:
347
- st.warning("⚠️ Dataset coordonnées villes vide")
348
- if df_historique.empty:
349
- st.warning("⚠️ Dataset historique incendies vide")
350
-
351
- # ---------------------------------------------------------------
352
- # Carte des communes
353
 
354
- if not df_coords.empty:
355
- fig = px.scatter_map(
356
- df_coords,
357
- lat="latitude",
358
- lon="longitude",
359
- hover_name="ville",
360
- height=800,
361
- zoom=4.5,
362
- map_style="carto-positron",
363
- title="Carte interactive des communes touchées par des incendies (2006-2024)"
364
- )
365
- st.plotly_chart(fig, use_container_width=True)
366
-
367
  st.write("""---""")
368
 
369
- # ---------------------------------------------------------------
370
- # DBSCAN Clustering
371
  st.subheader("🔥 2. Détection des clusters d'incendies")
372
- if not df_historique.empty:
373
- commune_counts = df_historique.groupby(['Nom de la commune', 'latitude', 'longitude']).size().reset_index(name='frequence')
374
- df_expanded = commune_counts.loc[commune_counts.index.repeat(commune_counts['frequence'])].reset_index(drop=True)
375
-
376
- X = df_expanded[['latitude', 'longitude']]
377
- coords_rad = np.radians(X)
378
- kms_per_radian = 6371.0088
379
- eps_km = 5
380
- eps = eps_km / kms_per_radian
381
-
382
- db = DBSCAN(eps=eps, min_samples=20, metric='haversine').fit(coords_rad)
383
- df_expanded['cluster'] = db.labels_
384
-
385
- clustered_data = df_expanded[df_expanded['cluster'] != -1]
386
-
387
- fig = px.scatter_map(
388
- clustered_data,
389
- lat="latitude",
390
- lon="longitude",
391
- color="cluster",
392
- hover_name="Nom de la commune",
393
- zoom=5,
394
- height=800,
395
- title="🔥 Clusters d'incendies en France (2006-2024) détectés par DBSCAN",
396
- map_style="carto-positron"
397
- )
398
- st.plotly_chart(fig, use_container_width=True)
399
 
400
- st.info("""
401
- 📌 **À retenir**
402
- Ce graphique met en évidence une forte hétérogénéité territoriale.
403
- Les départements les plus touchés concentrent une part disproportionnée des incendies, ce qui motive une approche prédictive ciblée.
404
- """)
405
 
406
  st.write("""---""")
407
 
408
  # ---------------------------------------------------------------
409
  # Histogramme mensuel
410
  st.subheader("3. Cumul des incendies mensuels par année")
411
- if not df_historique.empty:
412
- df_temp = df_historique.copy()
413
- df_temp['Date'] = pd.to_datetime(df_temp['Date'], errors='coerce')
414
- df_temp = df_temp.dropna(subset=['Date'])
415
- df_temp['mois'] = df_temp['Date'].dt.month
416
- df_temp['année'] = df_temp['Date'].dt.year
417
-
418
- mois_abbr = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
419
- 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
420
- df_temp['mois_nom'] = df_temp['mois'].apply(lambda x: mois_abbr[x - 1])
421
- df_temp['mois_nom'] = pd.Categorical(df_temp['mois_nom'], categories=mois_abbr, ordered=True)
422
-
423
- df_grouped = df_temp.groupby(['mois_nom', 'année']).size().reset_index(name='nombre_feux')
424
-
425
- fig = px.bar(
426
- df_grouped,
427
- x='mois_nom',
428
- y='nombre_feux',
429
- color='année',
430
- barmode='group',
431
- height=600,
432
- width=1000
433
- )
434
- st.plotly_chart(fig, use_container_width=True)
435
 
436
- st.info(""" Sans grande surprise, on observe une saisonnalité marquée des incendies, avec un pic significatif durant les mois de juillet et août.
437
- """)
438
 
439
  st.write("""---""")
440
 
441
  st.subheader("4. Analyse des causes 🔥")
442
 
443
- df_histo = load_historique_incendies()
444
-
445
- if df_histo.empty:
446
- st.warning("⚠️ Dataset historique incendies vide.")
447
- else:
448
- # ---------------------------------------------------- Répartition des causes --------------------------------------------
449
- if "Nature" in df_histo.columns:
450
- causes = df_histo['Nature'].value_counts()
451
-
452
- fig, ax = plt.subplots(figsize=(3.5, 3.5), dpi=80)
453
- ax.pie(
454
- causes.values,
455
- labels=causes.index,
456
- autopct='%1.0f%%',
457
- startangle=140
458
- )
459
-
460
- ax.axis('equal')
461
-
462
- col1, col2, col3 = st.columns([1, 1, 1])
463
-
464
- with col2:
465
- st.pyplot(fig)
466
- else:
467
- st.warning("⚠️ La colonne 'Nature' est absente du DataFrame.")
468
 
469
- st.info("""
470
- 📌 **À retenir** :
471
- L’analyse des causes révèle que la majorité des incendies sont d’origine humaine, soulignant l’importance de la prévention et de la sensibilisation pour réduire ces incidents.""")
472
 
473
- st.write("""---""")
474
 
475
  # ---------------------------------------------------- Nombre total d’incendies par année ----------------------------------
476
- if "Date" in df_histo.columns:
477
- st.subheader("5. Evolution du nombre d’incendies par an")
478
- df_temp = df_histo.copy()
479
- df_temp['Date'] = pd.to_datetime(df_temp['Date'], errors='coerce')
480
- df_temp = df_temp.dropna(subset=['Date'])
481
- df_temp['année'] = df_temp['Date'].dt.year
482
- df_grouped = df_temp.groupby('année').size().reset_index(name='nombre_feux')
483
-
484
- fig = px.bar(
485
- df_grouped,
486
- x='année',
487
- y='nombre_feux',
488
- height=600,
489
- text='nombre_feux'
490
- )
491
- fig.update_xaxes(tickmode='linear', dtick=1)
492
- fig.update_layout(xaxis_title='Année', yaxis_title='Nombre de feux', xaxis_tickangle=0)
493
- st.plotly_chart(fig)
494
- else:
495
- st.warning("⚠️ La colonne 'Date' est absente du DataFrame.")
496
-
497
- st.info("""L'année 2022 fut une année noire avec un nombre record d'incendies, notamment une surface brûlée de 60 000 ha, soit l'équivalent de
498
  84 000 terrains de football, ou encore 5,7 fois la surface de Paris intra-muros.""")
499
 
500
  # ---------------------------------------------------- Top départements
501
  st.subheader("6. Les 10 départements les plus touchés 🔥")
502
 
503
- # Chargement du dataset historique incendies
504
- df_temp = load_historique_incendies()
505
-
506
- if df_temp.empty:
507
- st.warning("⚠️ Le dataset historique incendies est vide.")
508
- elif "Département" not in df_temp.columns:
509
- st.error("❌ La colonne 'Département' est absente du DataFrame.")
510
- else:
511
- # Regroupement par département
512
- df_grouped = df_temp.groupby('Département').size().reset_index(name='nombre_feux')
513
-
514
- # Classement décroissant et sélection du top 10
515
- df_top10 = df_grouped.sort_values(by='nombre_feux', ascending=False).head(10)
516
-
517
- # Graphique en barres
518
- fig = px.bar(
519
- df_top10,
520
- x='Département',
521
- y='nombre_feux',
522
- height=600,
523
- width=1000,
524
- text='nombre_feux'
525
- )
526
-
527
- fig.update_layout(
528
- template='plotly_white',
529
- xaxis_title='Département',
530
- yaxis_title='Nombre de feux',
531
- xaxis_tickangle=-45,
532
- )
533
-
534
- fig.update_traces(textposition='outside')
535
-
536
- st.plotly_chart(fig)
537
 
538
  st.info("""Après analyse, la Corse se démarque nettement comme le département le plus touché par les incendies de forêt en France, justifiant ainsi notre choix de focus pour la suite de notre projet.""")
539
 
 
70
  st.session_state.css_injected = True
71
 
72
  #-------------------------------------------------------- Configuration AWS S3 ---------------------------------------------------
73
+ aws_access_key_id = os.getenv("AWS_ACCESS_KEY_ID")
74
+ aws_secret_access_key = os.getenv("AWS_SECRET_ACCESS_KEY")
75
  aws_region = "eu-west-3"
76
 
77
  s3 = boto3.client(
 
109
  # ------------------------------- Tabs ---------------------------------------
110
  content = st.container()
111
  with content:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
112
 
113
  page_tabs = st.tabs([
114
  "Notre Projet",
 
138
  st.error(f"❌ Erreur chargement dataset météo : {e}")
139
  return pd.DataFrame()
140
 
 
 
 
 
 
 
 
 
 
 
 
 
 
141
  def load_casernes() -> pd.DataFrame:
142
 
143
  bucket = "projet-final-lead"
 
151
  st.error(f"❌ Erreur : {e}")
152
  return pd.DataFrame()
153
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
154
  #-------------------------------------------------------- Chargement unique du modèle ---------------------------------------------------
155
  mlflow.set_tracking_uri("https://djohell-ml-flow.hf.space")
156
 
 
219
 
220
  st.header("🌲 Zoom sur le taux de boisement des différents départements français")
221
 
222
+ col1, col2, col3 = st.columns([1, 2, 1])
223
+ with col2:
224
+ st.image("images/boisement.png", caption="Taux de boisement par département en France en 2024 (source : IGN)", use_container_width=True)
225
+
226
+ st.write("""---""")
227
+
228
+ st.header(" Quels sont les principaux rôles de la forêt ?")
229
  col1, col2, col3 = st.columns([1,1,1])
230
 
231
  with col1:
232
+ st.image("images/puits carbone.png", caption="Puits de carbone", width=400)
233
 
234
  with col2:
235
+ st.image("images/racines.png", caption="Limitation de l'érosion", width=500)
236
 
237
  with col3:
238
+ st.image("images/rayonnement.png", caption="Limitation du rayonnement solaire", width=400)
239
 
240
  st.write("""---""")
241
 
 
288
  with page_tabs[1]:
289
  st.subheader("🗺️ 1. Visualisation des incendies entre 2006 et 2024")
290
 
291
+ image = Image.open("images/incendies.png")
292
+ st.image(
293
+ image,
294
+ use_container_width=True
295
+ )
 
 
 
 
 
 
 
 
 
296
 
 
 
 
 
 
 
 
 
 
 
 
 
 
297
  st.write("""---""")
298
 
299
+ # ----------- DBSCAN Clustering -------------------------------
 
300
  st.subheader("🔥 2. Détection des clusters d'incendies")
301
+
302
+ image = Image.open("images/clustering.png")
303
+ st.image(
304
+ image,
305
+ use_container_width=True
306
+ )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
307
 
308
+ st.info("""
309
+ 📌 **À retenir**
310
+ Ce graphique met en évidence une forte hétérogénéité territoriale.
311
+ Les départements les plus touchés concentrent une part disproportionnée des incendies, ce qui motive une approche prédictive ciblée.
312
+ """)
313
 
314
  st.write("""---""")
315
 
316
  # ---------------------------------------------------------------
317
  # Histogramme mensuel
318
  st.subheader("3. Cumul des incendies mensuels par année")
319
+
320
+ image = Image.open("images/saison.png")
321
+ st.image(
322
+ image,
323
+ use_container_width=True
324
+ )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
325
 
326
+ st.info(""" Sans grande surprise, on observe une saisonnalité marquée des incendies, avec un pic significatif durant les mois de juillet et août.
327
+ """)
328
 
329
  st.write("""---""")
330
 
331
  st.subheader("4. Analyse des causes 🔥")
332
 
333
+ image = Image.open("images/causes.png")
334
+ st.image(
335
+ image,
336
+ use_container_width=True
337
+ )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
338
 
339
+ st.info("""
340
+ 📌 **À retenir** :
341
+ L’analyse des causes révèle que la majorité des incendies sont d’origine humaine, soulignant l’importance de la prévention et de la sensibilisation pour réduire ces incidents.""")
342
 
343
+ st.write("""---""")
344
 
345
  # ---------------------------------------------------- Nombre total d’incendies par année ----------------------------------
346
+ image = Image.open("images/cumul_annuel.png")
347
+ st.image(
348
+ image,
349
+ use_container_width=True
350
+ )
351
+
352
+ st.info("""L'année 2022 fut une année noire avec un nombre record d'incendies, notamment une surface brûlée de 60 000 ha, soit l'équivalent de
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
353
  84 000 terrains de football, ou encore 5,7 fois la surface de Paris intra-muros.""")
354
 
355
  # ---------------------------------------------------- Top départements
356
  st.subheader("6. Les 10 départements les plus touchés 🔥")
357
 
358
+ image = Image.open("images/departement.png")
359
+ st.image(
360
+ image,
361
+ caption="Top 10 des départements les plus touchés par les incendies",
362
+ use_container_width=True
363
+ )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
364
 
365
  st.info("""Après analyse, la Corse se démarque nettement comme le département le plus touché par les incendies de forêt en France, justifiant ainsi notre choix de focus pour la suite de notre projet.""")
366