File size: 12,215 Bytes
0f6836e
 
b6db5c9
0f6836e
 
f513c11
0f6836e
 
b6db5c9
0f6836e
a98c212
 
0f6836e
f513c11
 
a98c212
 
f8a9026
 
 
 
0f6836e
 
 
 
 
 
f513c11
0f6836e
f8a9026
a98c212
f513c11
a98c212
 
0f6836e
 
 
 
 
 
 
b3e6969
0f6836e
 
 
b3e6969
0f6836e
 
 
f8a9026
a98c212
f8a9026
 
f513c11
f8a9026
a98c212
f513c11
 
 
 
0f6836e
f8a9026
 
 
 
 
 
 
 
 
 
 
a98c212
0f6836e
b3e6969
0f6836e
 
a98c212
 
 
f513c11
0f6836e
b3e6969
0f6836e
a98c212
0f6836e
 
b3e6969
0f6836e
 
 
b3e6969
0f6836e
 
 
f513c11
 
 
 
b3e6969
0f6836e
a98c212
0f6836e
 
b3e6969
0f6836e
 
 
f513c11
0f6836e
f513c11
 
 
 
 
 
 
 
 
 
b3e6969
a98c212
0f6836e
 
a98c212
0f6836e
b3e6969
0f6836e
 
a98c212
0f6836e
a98c212
f8a9026
b3e6969
0f6836e
 
 
b3e6969
0f6836e
 
 
b3e6969
0f6836e
 
b3e6969
0f6836e
 
 
a98c212
f8a9026
 
 
 
 
 
 
f513c11
f8a9026
 
 
 
0f6836e
a98c212
8ddca3e
f513c11
 
 
f8a9026
 
0f6836e
a98c212
 
0f6836e
a98c212
 
f8a9026
a98c212
 
 
0f6836e
a98c212
 
 
 
f513c11
a98c212
 
b3e6969
 
a98c212
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
f513c11
a98c212
 
 
 
 
 
 
 
 
b3e6969
a98c212
 
0f6836e
 
 
 
f513c11
 
0f6836e
a98c212
 
0f6836e
 
a98c212
b3e6969
d8e6abf
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
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
from taipy import Gui
import pandas as pd
import numpy as np
import plotly.express as px
import plotly.graph_objects as go
import plotly.io as pio
import matplotlib.pyplot as plt
import matplotlib.colors as mcolors
import matplotlib.cm as cm

from functions import *
from dashboard import *

pio.templates.default = "simple_white"

# CHARGEMENT DES DONNEES
df_controls, df_individus, df_sites, df_distances, df_mapping = load_data_antenna()
liste_sites_antennes = sorted(["Brelouze", "Mairie d'Annepont", "Grottes de Loubeau", "Le Plessis", "Puy-Chenin", "Cézelle", "La Bourtière", "Goizet (W)", "Château de Gagemont", "Faye-L'Abbesse - Bourg", "Guibaud", "Cave Billard", "Grotte de Boisdichon", "Les Roches", "Barrage de l'Aigle", "Gouffre de la Fage",
                  "Ancienne citerne à eau", "Château de Verteuil", "Les Dames", "Château de Hautefort", "Les Tours de Merle - Tour Fulcon", "Le Petit Pin", "Maison Brousse", "Caves de Laubenheimer", "Château de Villandraut", "Tunnel ferroviaire", "Grotte de la carrière", "Centrale hydroélectrique de Claredent", "Fermette des Nobis",
                  "Beauregard", "Grotte de la Deveze", "Petexaenea (Site générique Galeries N&S)", "Gouffre de Bexanka", "Mikelauenziloa"])
ETUDE_valides = ["Diag CEN", "Diag NATURA 2000", "Diag FDS_Oléron", "ECOFECT (GR/CCPNA)", "ECOFECT (Hors GR)", "TRANSPY ESPAGNE", "TRANSPY FRANCE"]

# Initialisation des variables d'état
selected_dpt = []
selected_dpt_gant = []
selected_sp = []
selected_gender = []
selected_age = []
selected_sites = []
selected_communes = []
selected_dates = [df_controls['DATE'].min(), df_controls['DATE'].max()]
selected_period = ['Transit', 'Parturition', 'Hivernale']
dates_gant = [df_controls['DATE'].min(), df_controls['DATE'].max()]
df_empty = pd.DataFrame()

# CONTENU
## ROOT PAGE
FEDER = "images/FEDER-NA.png"
PREFET = "images/Prefet_NA.jpg"
VERT = "images/FranceNationVerte.jpg"

with open("pages/home.md", "r", encoding = "utf-8") as file:
    root_md = file.read()

## PAGE DE PRESENTATION
with open("pages/page1.md", "r", encoding = "utf-8") as file:
    page1 = file.read()

## VISUALISATION DES DONNEES D'ANTENNES
communes = sorted(df_controls['COMMUNE'].unique().tolist())
departements = sorted(df_controls['DEPARTEMENT'].unique().tolist())
species = sorted(df_distances['CODE_ESP'].unique().tolist())
genders = sorted(df_individus['SEXE'].dropna().unique().tolist())
age = sorted(df_individus['AGE'].dropna().unique().tolist())
sites = sorted(df_controls['LIEU_DIT'].dropna().unique().tolist())
dates = [df_controls['DATE'].min(), df_controls['DATE'].max()]
periods = ['Transit', 'Parturition', 'Hivernale']
transit_months = [3, 4, 5, 9, 10, 11]   # Printemps et Automne
parturition_months = [6, 7, 8]          # Été
hivernale_months = [12, 1, 2]           # Hiver

# Callback du sélécteur de sites
def refresh_sites(state):
    selected_communes = state.selected_communes or []
    
    if selected_communes:
        filtered_df = df_controls[df_controls['COMMUNE'].isin(selected_communes)]
    else:
        filtered_df = df_controls

    state.sites = sorted(filtered_df['LIEU_DIT'].unique().tolist())

m = generate_map(df_empty, df_sites)

with open("pages/page2.md", "r", encoding = "utf-8") as file:
    page2 = file.read()

# Callback de la carte
def refresh_map_button(state):
    df_filtered = df_distances.copy()
    df_filtered['DATE_ARRIVEE'] = pd.to_datetime(df_filtered['DATE_ARRIVEE'])
    
    # Filtrer par département d'origine
    if state.selected_dpt:
        equipped_pit = df_filtered[(df_filtered['DPT_DEPART'].isin(state.selected_dpt)) | (df_filtered['DPT_ARRIVEE'].isin(state.selected_dpt))]['NUM_PIT'].unique()
        df_filtered = df_filtered[df_filtered['NUM_PIT'].isin(equipped_pit)]
    
    # Filtrer par espèce
    if state.selected_sp:
        df_filtered = df_filtered[df_filtered['CODE_ESP'].isin(state.selected_sp)]

    # Filtrer par genre
    if state.selected_gender:
        df_filtered = df_filtered[df_filtered['SEXE'].isin(state.selected_gender)]

    # Filtrer par âge
    if state.selected_age:
        df_filtered = df_filtered[df_filtered['AGE'].isin(state.selected_age)]

    # Filtrer par site d'origine
    if state.selected_sites:
        site_pit = df_filtered[(df_filtered['SITE_DEPART'].isin(state.selected_sites)) | (df_filtered['SITE_ARRIVEE'].isin(state.selected_sites))]['NUM_PIT'].unique()        
        df_filtered = df_filtered[df_filtered['NUM_PIT'].isin(site_pit)]
    
    # Filtrer par intervalle de dates
    if state.selected_dates and len(state.selected_dates) == 2:
        start_date = pd.Timestamp(state.selected_dates[0])
        end_date = pd.Timestamp(state.selected_dates[1])
        df_filtered = df_filtered[(df_filtered['DATE_DEPART'] >= start_date) & (df_filtered['DATE_ARRIVEE'] <= end_date)]
    
    # Filtrage en fonction des périodes
    mask = pd.Series([False] * len(df_filtered), index = df_filtered.index)
    if "Transit" in state.selected_period:
        mask |= df_filtered['DATE_ARRIVEE'].dt.month.isin(transit_months)
    if "Parturition" in state.selected_period:
        mask |= df_filtered['DATE_ARRIVEE'].dt.month.isin(parturition_months)
    if "Hivernale" in state.selected_period:
        mask |= df_filtered['DATE_ARRIVEE'].dt.month.isin(hivernale_months)
    df_filtered = df_filtered[mask]

    # Rafraichir la carte
    state.m = generate_map(df_filtered, df_sites)

## PHENOLOGIES DES SITES
gant_global = gant_diagram(df_controls)

with open("pages/page3.md", "r", encoding = "utf-8") as file:
    page3 = file.read()

# Callbacks du diagramme de Gant
def update_gant(state):
    df_filtered_gant = df_controls.copy()
    df_filtered_gant = df_filtered_gant[df_filtered_gant['LIEU_DIT'].isin(liste_sites_antennes)]

    # Convertir les dates sélectionnées en objets Timestamp
    if state.selected_dpt_gant:
        df_filtered_gant = df_filtered_gant[df_filtered_gant['DEPARTEMENT'].isin(state.selected_dpt_gant)]

    if state.dates_gant and len(state.dates_gant) == 2:
        start_date = pd.Timestamp(state.dates_gant[0])
        end_date = pd.Timestamp(state.dates_gant[1])

        # Filtrer les dates
        df_filtered_gant = df_filtered_gant[(df_filtered_gant['DATE'] >= start_date) & (df_filtered_gant['DATE'] <= end_date)]

    state.gant_global = gant_diagram(df_filtered_gant)

## STATISTIQUES ANALYTIQUES
# Initialisation de tous les plots
df_controls_valide = df_controls[df_controls['ETUDE'].isin(ETUDE_valides)]
df_individus_valide = df_individus[df_individus['ETUDE'].isin(ETUDE_valides)]

plot_detection_year = detection_by_year(df_controls_valide)      # Barplot du nombre de détections par an et par espèce
plot_capture_year = capture_by_year(df_individus_valide)         # Barplot du nombre de captures par an et par espèces
plot_control_year = control_by_year(df_controls_valide)          # Barplot du nombre de contrôles par an et par espèces
plot_frequencies = detection_frequencies(df_controls_valide)     # Courbes de fréquences de détections par jour de l'année et par site
plot_frequencies_global = detection_frequencies_global(df_controls_valide)     # Courbes de fréquences de détections totales par jour de l'année
plot_pie_controled = pie_controled(df_controls_valide)           # Pieplot des individus contrôlés
plot_pie_marked = pie_marked(df_individus_valide)                # Pieplot des individus marqués
plot_top_detection = top_detection(df_controls_valide)           # Barplot horizontal des 10 individus les plus détectés
plot_box_distances = distance_boxplot(df_distances)              # Boxplot des distances par espèce

# Initialisation des variables à plot
total_recaptured = df_controls.query('ACTION == "C"')['NUM_PIT'].nunique()       # Individus contrôlés
total_marked = df_individus['NUM_PIT'].nunique()                                 # Individus marqués
sites_capture = df_individus['LIEU_DIT'].nunique()                               # Sites capturés au moins une fois
sites_antennes = df_sites['LIEU_DIT'].nunique()                                  # Sites contrôlés au moins une fois
transition_table_plot = df_distances[['NUM_PIT', 'CODE_ESP', 'DATE_DEPART', 'SITE_DEPART', 'DATE_ARRIVEE', 'SITE_ARRIVEE', 'DIST_KM']].sort_values(by='DIST_KM', ascending = False)
transition_table_plot['DIST_KM'] = transition_table_plot['DIST_KM'].round(2)

with open("pages/page4.md", "r", encoding = "utf-8") as file:
    page4 = file.read()

## FICHE SITE
# Initialisation du sélecteur et des plots
selection_fiche = ['Ancienne citerne à eau']
df_controls_fiche = df_controls[df_controls['LIEU_DIT'].isin(selection_fiche)]
df_individus_fiche = df_individus[df_individus['LIEU_DIT'].isin(selection_fiche)]
df_distances_fiche = df_distances[(df_distances['SITE_DEPART'].isin(selection_fiche)) | (df_distances['SITE_ARRIVEE'].isin(selection_fiche))]

plot_detection_year_fiche = detection_by_year(df_controls_fiche)      # Barplot du nombre de détections par an et par espèce
plot_capture_year_fiche = capture_by_year(df_individus_fiche)         # Barplot du nombre de captures par an et par espèces
plot_control_year_fiche = control_by_year(df_controls_fiche)          # Barplot du nombre de contrôles par an et par espèces
plot_frequencies_fiche = detection_frequencies(df_controls_fiche)     # Courbes de fréquences de détections par jour de l'année et par site
plot_frequencies_global_fiche = detection_frequencies_global(df_controls_fiche)     # Courbes de fréquences de détections totales par jour de l'année
plot_pie_controled_fiche = pie_controled(df_controls_fiche)           # Pieplot des individus contrôlés
plot_pie_marked_fiche = pie_marked(df_individus_fiche)                # Pieplot des individus marqués

# Initialisation des variables à plot
total_recaptured_fiche = df_controls_fiche['NUM_PIT'].nunique()       # Individus contrôlés
total_marked_fiche = df_individus_fiche['NUM_PIT'].nunique()          # Individus marqués
sites_antennes_fiche = df_sites['LIEU_DIT'].nunique()                 # Sites contrôlés au moins une fois
map_fiche = generate_map(df_distances_fiche, df_sites)                # Map du site et des connexions
gant_diagram_fiche = gant_diagram_concat(df_controls_fiche)

def update_fiche(state):
    # Filtrage en fonction de la sélection
    selected_sites = [state.selection_fiche]
    df_controls_fiche = df_controls[df_controls['LIEU_DIT'].isin(selected_sites)]
    df_individus_fiche = df_individus[df_individus['LIEU_DIT'].isin(selected_sites)]
    df_distances_fiche = df_distances[(df_distances['SITE_DEPART'].isin(selected_sites)) | (df_distances['SITE_ARRIVEE'].isin(selected_sites))]
    
    # Mise à jour des visualisations
    state.plot_detection_year_fiche = detection_by_year(df_controls_fiche)
    state.plot_capture_year_fiche = capture_by_year(df_individus_fiche)
    state.plot_control_year_fiche = control_by_year(df_controls_fiche)
    state.plot_frequencies_fiche = detection_frequencies(df_controls_fiche)
    state.plot_frequencies_global_fiche = detection_frequencies_global(df_controls_fiche)
    state.plot_pie_controled_fiche = pie_controled(df_controls_fiche)
    state.plot_pie_marked_fiche = pie_marked(df_individus_fiche)
    state.map_fiche = generate_map(df_distances_fiche, df_sites)
    state.gant_diagram_fiche = gant_diagram_concat(df_controls_fiche)
    
    # Mise à jour des variables globales
    state.total_recaptured_fiche = df_controls_fiche['NUM_PIT'].nunique()
    state.total_marked_fiche = df_individus_fiche['NUM_PIT'].nunique()
    state.sites_antennes_fiche = df_sites['LIEU_DIT'].nunique()

with open("pages/page5.md", "r", encoding = "utf-8") as file:
    page5 = file.read()

# DEMARRAGE DE L'APPLICATION
pages = {
    "/": root_md,
    # "presentation": page1,
    "carto_cmr": page2,
    "phenologie": page3,
    "statistiques": page4,
    "fiche_site": page5
}

Gui.register_content_provider(Map, expose_folium)
gui = Gui(pages = pages, css_file = "assets/styles.css")
gui.run(host = '0.0.0.0', port = 7860, use_session = True, dark_mode = False, stylekit = False, watermark = "") # use_session = True pour permettre l'usage de plusieurs users en même temps