Tracy André commited on
Commit
e244cf3
·
1 Parent(s): 150fdd6
DEPLOYMENT.md DELETED
@@ -1,63 +0,0 @@
1
- # Déploiement Hugging Face Spaces
2
-
3
- ## ✅ Fix ArrowInvalid Intégré
4
-
5
- Cette application inclut un fix complet pour les erreurs `ArrowInvalid` qui peuvent survenir lors du chargement de datasets depuis Hugging Face.
6
-
7
- ### 🔧 Problème Résolu
8
-
9
- L'erreur suivante ne peut plus se reproduire :
10
- ```
11
- ArrowInvalid("Failed to parse string: 'Coué - ' as a scalar of type double")
12
- ```
13
-
14
- ### 🛠️ Solution Implémentée
15
-
16
- Le fichier `data_loader.py` inclut :
17
- - **Protection Arrow multi-niveaux** avec 3 stratégies de fallback
18
- - **Conversion sécurisée** des types problématiques
19
- - **Nettoyage automatique** des valeurs corrompues
20
- - **Validation robuste** des données
21
-
22
- ### 📦 Requirements pour HF
23
-
24
- Utilisez `requirements.txt` (sans audioop-lts) :
25
-
26
- ```txt
27
- gradio==4.25.0
28
- pandas>=2.0.0,<3.0.0
29
- numpy>=1.21.0,<2.0.0
30
- matplotlib>=3.5.0,<4.0.0
31
- seaborn>=0.11.0,<1.0.0
32
- plotly>=5.0.0,<6.0.0
33
- scipy>=1.7.0,<2.0.0
34
- scikit-learn>=1.0.0,<2.0.0
35
- datasets>=2.0.0,<5.0.0
36
- huggingface_hub>=0.16.0,<1.0.0
37
- pyarrow>=14.0.0,<22.0.0
38
- ```
39
-
40
- ### 🚀 Déploiement
41
-
42
- 1. **Upload** tous les fichiers vers HF Spaces
43
- 2. **Point d'entrée** : `app.py`
44
- 3. **Python version** : 3.10+ (compatible)
45
- 4. **Hardware** : CPU Basic suffisant
46
-
47
- ### 🔐 Garanties
48
-
49
- - ✅ **Aucune erreur ArrowInvalid** possible
50
- - ✅ **Compatible Python 3.10** (HF Spaces)
51
- - ✅ **Chargement de datasets sécurisé**
52
- - ✅ **Interface Gradio fonctionnelle**
53
-
54
- ### 🧪 Test Local
55
-
56
- ```bash
57
- # Tester la configuration
58
- python -c "
59
- from data_loader import DataLoader
60
- loader = DataLoader()
61
- print('✅ Fix Arrow intégré et fonctionnel!')
62
- "
63
- ```
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
GUIDE_REQUETES_HERBICIDES.md DELETED
@@ -1,177 +0,0 @@
1
- # 🔍 Guide des Requêtes Herbicides
2
-
3
- ## Nouvelles Fonctionnalités Intégrées
4
-
5
- L'application d'analyse des adventices agricoles a été enrichie avec un système de requêtes avancées pour l'analyse des herbicides. Voici comment utiliser ces nouvelles fonctionnalités :
6
-
7
- ## 📋 Accès aux Fonctionnalités
8
-
9
- Dans l'interface Gradio, vous trouverez un nouvel onglet **"🔍 Requêtes Herbicides"** qui contient 4 sous-onglets spécialisés :
10
-
11
- ---
12
-
13
- ## 🏆 Top IFT par Année
14
-
15
- **Objectif :** Identifier les parcelles avec les Indices de Fréquence de Traitement (IFT) herbicides les plus élevés pour une année donnée.
16
-
17
- ### Utilisation :
18
- 1. Sélectionnez l'année à analyser dans la liste déroulante
19
- 2. Choisissez le nombre de parcelles à afficher (5 à 50)
20
- 3. Cliquez sur "🔍 Analyser les IFT"
21
-
22
- ### Résultats :
23
- - **Graphique en barres** : Classement visuel des parcelles par IFT décroissant
24
- - **Tableau détaillé** : Numéro de parcelle, surface, IFT, quantité totale, nombre de produits
25
-
26
- ### Cas d'usage :
27
- - **Surveillance prioritaire** : Identifier les parcelles nécessitant une attention particulière
28
- - **Benchmarking** : Comparer les pratiques entre parcelles
29
- - **Audit réglementaire** : Suivre les parcelles à forte intensité de traitement
30
-
31
- ---
32
-
33
- ## 📖 Historique Parcelle
34
-
35
- **Objectif :** Tracer l'historique complet des herbicides utilisés sur une parcelle spécifique.
36
-
37
- ### Utilisation :
38
- 1. Saisissez le numéro de la parcelle (ex: 21, 22, etc.)
39
- 2. Définissez le nombre d'années à analyser (1 à 15)
40
- 3. Cliquez sur "🔍 Analyser l'historique"
41
-
42
- ### Résultats :
43
- - **Graphique chronologique** : Évolution des produits et quantités par année
44
- - **Tableau historique** : Détail par année avec produits, quantités et dates
45
-
46
- ### Cas d'usage :
47
- - **Planification de rotation** : Voir l'historique avant d'implanter une culture sensible
48
- - **Traçabilité** : Documenter les pratiques passées
49
- - **Analyse tendances** : Observer l'évolution des pratiques sur une parcelle
50
-
51
- ---
52
-
53
- ## 🎯 Recherche de Produits
54
-
55
- **Objectif :** Trouver les parcelles ayant reçu (ou n'ayant PAS reçu) des produits spécifiques.
56
-
57
- ### Utilisation :
58
- 1. Saisissez les noms de produits séparés par des virgules
59
- - Exemple : `Minarex, Chardex, Aligator`
60
- - Supporte la recherche partielle (ex: "Chardex" trouve "Chardex 500")
61
- 2. Définissez la période d'analyse (1 à 15 années)
62
- 3. Choisissez votre type de recherche :
63
- - **"✅ Parcelles AVEC ces produits"** : Trouve les parcelles qui ont reçu au moins un des produits
64
- - **"❌ Parcelles SANS ces produits"** : Trouve les parcelles qui n'ont reçu aucun de ces produits
65
-
66
- ### Résultats :
67
- - **Message de statut** : Nombre de parcelles trouvées
68
- - **Tableau des résultats** : Liste des parcelles avec détails (années, quantités, dates)
69
-
70
- ### Cas d'usage :
71
- - **Rotation Chardex** : `Chardex` → Trouver les parcelles sans Chardex pour cultures sensibles
72
- - **Évitement de résidus** : Identifier les parcelles sans produits persistants
73
- - **Conformité réglementaire** : Tracer l'usage de produits spécifiques
74
-
75
- ### Exemples de Requêtes Utiles :
76
-
77
- #### Pour cultures sensibles (pois, haricot) :
78
- ```
79
- Recherche "SANS" : Chardex, Minarex
80
- → Trouve les parcelles adaptées aux légumineuses
81
- ```
82
-
83
- #### Pour audit d'un produit :
84
- ```
85
- Recherche "AVEC" : Aligator
86
- → Trace tous les usages d'Aligator
87
- ```
88
-
89
- #### Pour éviter les résistances :
90
- ```
91
- Recherche "AVEC" : Glyphosate, Round
92
- → Identifie les parcelles à forte pression glyphosate
93
- ```
94
-
95
- ---
96
-
97
- ## 🗓️ Périodes d'Intervention
98
-
99
- **Objectif :** Analyser les patterns temporels d'application des herbicides par parcelle.
100
-
101
- ### Utilisation :
102
- 1. Définissez la période d'analyse (1 à 15 années)
103
- 2. Cliquez sur "🔍 Analyser les périodes"
104
-
105
- ### Résultats :
106
- - **Graphique scatter** : Position des interventions dans l'année vs intensité
107
- - X = Mois de début d'intervention
108
- - Y = Nombre d'interventions
109
- - Taille = Quantité totale utilisée
110
- - Couleur = Nombre de produits différents
111
-
112
- - **Heatmap** : Répartition mensuelle des interventions par année
113
- - Visualise les pics d'activité saisonniers
114
- - Compare l'évolution temporelle entre années
115
-
116
- - **Tableau détaillé** : Analyse par parcelle avec :
117
- - Période d'activité (année début/fin)
118
- - Nombre total d'interventions
119
- - Mois de début/fin des traitements
120
- - Liste des mois d'intervention
121
- - Nombre de produits uniques
122
- - Quantité totale
123
-
124
- ### Cas d'usage :
125
- - **Optimisation temporelle** : Identifier les meilleures fenêtres d'intervention
126
- - **Planification cultural** : Éviter les conflits avec les périodes de traitement
127
- - **Analyse climatique** : Corréler les interventions avec les conditions météo
128
- - **Benchmarking temporel** : Comparer les strategies temporelles entre parcelles
129
-
130
- ---
131
-
132
- ## 💡 Conseils d'Utilisation
133
-
134
- ### Recherche de Produits Efficace :
135
- - Utilisez des **noms partiels** : "Chardex" trouve "Chardex 500", "Chardex WG", etc.
136
- - **Combinez plusieurs produits** : "Chardex, Minarex" pour une recherche large
137
- - **Soyez spécifique** : "Round" vs "Roundup" selon vos besoins
138
-
139
- ### Interprétation des IFT :
140
- - **IFT < 1** : Usage faible, parcelles intéressantes pour cultures sensibles
141
- - **IFT 1-3** : Usage modéré, surveillance recommandée
142
- - **IFT > 3** : Usage intensif, rotation conseillée avant cultures sensibles
143
-
144
- ### Analyse Temporelle :
145
- - **Mars-Avril** : Période classique de désherbage de printemps
146
- - **Septembre-Octobre** : Traitements d'automne (colza, céréales)
147
- - **Heatmap** : Rouge = forte activité, Bleu = période calme
148
-
149
- ---
150
-
151
- ## 🔧 Support Technique
152
-
153
- - **Données manquantes** : Les requêtes s'adaptent automatiquement aux colonnes disponibles
154
- - **Recherche insensible à la casse** : "chardex" = "CHARDEX"
155
- - **Gestion des erreurs** : Messages explicites en cas de problème
156
- - **Performance** : Optimisé pour des datasets de plusieurs milliers de lignes
157
-
158
- ---
159
-
160
- ## 📞 Questions Fréquentes
161
-
162
- **Q: Que faire si aucune parcelle n'est trouvée ?**
163
- R: Vérifiez l'orthographe des produits et élargissez la période de recherche.
164
-
165
- **Q: Comment interpréter un IFT élevé ?**
166
- R: IFT élevé = forte pression herbicide. Considérez une rotation ou des techniques alternatives.
167
-
168
- **Q: Puis-je rechercher plusieurs produits à la fois ?**
169
- R: Oui, séparez-les par des virgules. La recherche trouve les parcelles avec AU MOINS UN des produits.
170
-
171
- **Q: Comment identifier les parcelles pour pois/haricot ?**
172
- R: Recherchez les parcelles "SANS" Chardex sur 10 ans, puis vérifiez leur historique.
173
-
174
- ---
175
-
176
- *Développé pour le Hackathon CRA Bretagne 🏆*
177
- *Application d'aide à la décision pour une agriculture durable*
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
HF_DEPLOY_GUIDE.md DELETED
@@ -1,117 +0,0 @@
1
- # 🚀 Guide de Déploiement Hugging Face Spaces
2
-
3
- ## ✅ Problème ArrowInvalid RÉSOLU
4
-
5
- Cette application résout définitivement l'erreur :
6
- ```
7
- ArrowInvalid("Failed to parse string: 'Coué - ' as a scalar of type double")
8
- ```
9
-
10
- ## 📋 Requirements.txt Optimisé
11
-
12
- Le fichier `requirements.txt` a été optimisé pour HF Spaces (Python 3.10) :
13
-
14
- ```txt
15
- gradio>=4.44.0,<5.0.0
16
- pandas>=2.0.0,<3.0.0
17
- numpy>=1.21.0,<2.0.0
18
- matplotlib>=3.5.0,<4.0.0
19
- seaborn>=0.11.0,<1.0.0
20
- plotly>=5.0.0,<6.0.0
21
- scipy>=1.7.0,<2.0.0
22
- scikit-learn>=1.0.0,<2.0.0
23
- datasets>=2.0.0,<5.0.0
24
- huggingface_hub>=0.16.0,<1.0.0
25
- pyarrow>=14.0.0,<22.0.0
26
- ```
27
-
28
- ## 🔧 Changements Apportés
29
-
30
- ### ❌ SUPPRIMÉ
31
- - `audioop-lts>=0.2.1` (incompatible Python 3.10)
32
-
33
- ### ✅ AJOUTÉ/CORRIGÉ
34
- - Versions épinglées avec limites supérieures
35
- - Gradio mis à jour vers 4.44+
36
- - Fix ArrowInvalid intégré dans `data_loader.py`
37
-
38
- ## 🛠️ Instructions de Déploiement
39
-
40
- ### 1. Créer un Space HF
41
-
42
- ```bash
43
- # Sur Hugging Face Spaces
44
- # Nom: votre-app-name
45
- # Type: Gradio
46
- # Python version: 3.10
47
- # Hardware: CPU Basic
48
- ```
49
-
50
- ### 2. Uploader les Fichiers
51
-
52
- Fichiers requis :
53
- - ✅ `app.py` (point d'entrée)
54
- - ✅ `data_loader.py` (fix Arrow intégré)
55
- - ✅ `requirements.txt` (optimisé)
56
- - ✅ `config.py`
57
- - ✅ `interface.py`
58
- - ✅ `analyzer.py`
59
- - ✅ `visualizations.py`
60
- - ✅ `sample_data.csv`
61
-
62
- ### 3. Configuration HF
63
-
64
- **Fichier de configuration Space** (optionnel) :
65
- ```yaml
66
- title: Votre App Name
67
- emoji: 🌱
68
- colorFrom: green
69
- colorTo: blue
70
- sdk: gradio
71
- sdk_version: 4.44.0
72
- app_file: app.py
73
- pinned: false
74
- license: mit
75
- ```
76
-
77
- ## 🔐 Garanties
78
-
79
- - ✅ **Aucune erreur ArrowInvalid possible**
80
- - ✅ **Compatible Python 3.10 HF Spaces**
81
- - ✅ **Pas de dépendance audioop-lts**
82
- - ✅ **Chargement datasets sécurisé**
83
- - ✅ **Interface responsive**
84
-
85
- ## 🧪 Test Avant Déploiement
86
-
87
- ```bash
88
- # Test local
89
- conda run python -c "
90
- from data_loader import DataLoader
91
- import gradio as gr
92
- print('✅ Prêt pour HF!')
93
- "
94
- ```
95
-
96
- ## 📞 Support
97
-
98
- En cas de problème ArrowInvalid :
99
- 1. Vérifiez que `data_loader.py` contient le fix
100
- 2. Confirmez l'absence d'`audioop-lts`
101
- 3. Utilisez le fichier `requirements.txt` fourni
102
-
103
- ## 🎯 Architecture du Fix
104
-
105
- ```python
106
- # data_loader.py - Protection multi-niveaux
107
- def _safe_load_from_hf():
108
- # Stratégie 1: HF direct + protection Arrow
109
- # Stratégie 2: Fichiers repo + types string
110
- # Stratégie 3: Fichier local + nettoyage
111
-
112
- def _clean_data_types():
113
- # Nettoie "Coué - " → None
114
- # Convertit types sécurisés
115
- ```
116
-
117
- **L'application est maintenant 100% compatible avec Hugging Face Spaces !** 🚀
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
NOUVELLE_FONCTIONNALITE_PARCELLES.md DELETED
@@ -1,156 +0,0 @@
1
- # 🏠 Nouvelle Fonctionnalité : Filtrage par Parcelle
2
-
3
- ## 📋 Fonctionnalité Ajoutée
4
-
5
- Dans l'onglet **"📅 Analyse par Année"**, une nouvelle liste déroulante a été ajoutée pour permettre la sélection par parcelle spécifique, en complément du filtrage par année existant.
6
-
7
- ## 🎯 Objectif
8
-
9
- Permettre une analyse granulaire des données agricoles en combinant :
10
- - **Filtrage temporel** : Par année
11
- - **Filtrage spatial** : Par parcelle spécifique
12
-
13
- ## 🔧 Fonctionnement
14
-
15
- ### Interface Utilisateur
16
-
17
- L'interface comprend maintenant **deux contrôles de filtrage** côte à côte :
18
-
19
- 1. **🗓️ Sélectionner une année**
20
- - Liste déroulante des années disponibles
21
- - Année la plus récente sélectionnée par défaut
22
-
23
- 2. **🏠 Sélectionner une parcelle** *(NOUVEAU)*
24
- - Liste déroulante de toutes les parcelles disponibles
25
- - Format d'affichage : `Numéro - Nom de la parcelle`
26
- - Option "Toutes les parcelles" par défaut
27
- - 84 parcelles disponibles dans les données actuelles
28
-
29
- ### Synchronisation des Contrôles
30
-
31
- - **Mise à jour automatique** : Changer l'année OU la parcelle rafraîchit tous les graphiques
32
- - **Réactivité** : Les modifications sont appliquées immédiatement
33
- - **Cohérence** : Tous les graphiques et statistiques reflètent la sélection combinée
34
-
35
- ## 📊 Impacts sur les Visualisations
36
-
37
- ### 1. Statistiques Résumé
38
- - **Titre dynamique** : Indique l'année et la parcelle sélectionnées
39
- - **Métriques adaptées** :
40
- - Nombre de parcelles (1 si parcelle spécifique, N si toutes)
41
- - Surface totale/moyenne de la sélection
42
- - Interventions herbicides pour la sélection
43
-
44
- **Exemple :**
45
- ```
46
- ## 📊 Statistiques pour l'année 2014 - Parcelle 2 (Kersuzan Bas)
47
- - Nombre de parcelles: 1
48
- - Nombre d'interventions: 27
49
- - Surface totale: 49.68 hectares
50
- - Interventions herbicides: 6 (22.2%)
51
- ```
52
-
53
- ### 2. Graphique des Cultures
54
- - **Scope adapté** : Répartition des cultures pour la parcelle sélectionnée
55
- - **Titre dynamique** : Inclut l'année et la parcelle
56
- - **Données filtrées** : Seules les cultures de la parcelle sélectionnée
57
-
58
- ### 3. Timeline des Interventions
59
- - **Activité focalisée** : Répartition mensuelle pour la parcelle spécifique
60
- - **Pattern individuel** : Comprendre les habitudes d'une parcelle particulière
61
- - **Comparaison temporelle** : Évolution des pratiques sur une parcelle
62
-
63
- ### 4. Analyse des Herbicides
64
- - **Usage spécifique** : Top des herbicides utilisés sur la parcelle
65
- - **Pratiques individuelles** : Stratégies herbicides parcelle par parcelle
66
- - **Traçabilité** : Historique précis des traitements
67
-
68
- ## 💡 Cas d'Usage
69
-
70
- ### 🔍 Analyse Parcellaire Détaillée
71
- ```
72
- Sélection : 2014 + Parcelle 2 (Kersuzan Bas)
73
- Résultat : Vue complète des pratiques sur cette parcelle en 2014
74
- Usage : Audit détaillé, préparation de rotation, analyse de conformité
75
- ```
76
-
77
- ### 📈 Comparaison Entre Parcelles
78
- ```
79
- Étape 1 : Analyser Parcelle A en 2014
80
- Étape 2 : Analyser Parcelle B en 2014
81
- Résultat : Comparaison des pratiques entre parcelles similaires
82
- ```
83
-
84
- ### 🎯 Suivi Longitudinal
85
- ```
86
- Sélection : Parcelle 2 en 2014, puis 2015, puis 2016...
87
- Résultat : Évolution des pratiques sur une parcelle spécifique
88
- Usage : Analyse de l'impact des changements de pratiques
89
- ```
90
-
91
- ### 🌾 Préparation de Culture
92
- ```
93
- Contexte : Vouloir planter du pois sur Parcelle 2
94
- Action : Analyser l'historique herbicide de cette parcelle
95
- Décision : Évaluer la compatibilité avec la culture sensible
96
- ```
97
-
98
- ## ⚙️ Aspects Techniques
99
-
100
- ### Gestion des Types de Données
101
- - **Conversion automatique** : String ↔ Integer pour les numéros de parcelles
102
- - **Robustesse** : Gestion des erreurs de conversion
103
- - **Compatibilité** : Fonctionne avec différents formats de données
104
-
105
- ### Performance
106
- - **Filtrage optimisé** : Pandas operations pour des performances élevées
107
- - **Mémoire efficace** : Pas de duplication inutile des données
108
- - **Réactivité** : Mise à jour instantanée des visualisations
109
-
110
- ### Architecture
111
- ```python
112
- # Nouvelle méthode de filtrage combiné
113
- def filter_data_by_year_and_parcel(self, year, parcel_id):
114
- # Filtrage temporel ET spatial
115
- # Gestion des types de données
116
- # Validation des entrées
117
-
118
- # Méthodes de visualisation mises à jour
119
- def create_year_culture_analysis(self, year, parcel_id=None):
120
- def create_year_interventions_timeline(self, year, parcel_id=None):
121
- def create_year_herbicide_analysis(self, year, parcel_id=None):
122
- def get_year_summary_stats(self, year, parcel_id=None):
123
- ```
124
-
125
- ## 🎉 Avantages
126
-
127
- ### Pour l'Utilisateur
128
- - **Granularité** : Analyse au niveau parcelle le plus fin
129
- - **Flexibilité** : Vue globale OU spécifique selon les besoins
130
- - **Intuitivité** : Interface simple avec deux listes déroulantes
131
- - **Rapidité** : Exploration interactive des données
132
-
133
- ### Pour l'Analyse
134
- - **Précision** : Données exactes pour une parcelle donnée
135
- - **Comparabilité** : Benchmarking facile entre parcelles
136
- - **Traçabilité** : Suivi détaillé des pratiques
137
- - **Conformité** : Audit parcelle par parcelle
138
-
139
- ### Pour la Décision
140
- - **Ciblage** : Recommandations spécifiques à une parcelle
141
- - **Planning** : Préparation des rotations avec historique précis
142
- - **Optimisation** : Ajustement des pratiques parcelle par parcelle
143
- - **Réglementation** : Respect des contraintes par parcelle
144
-
145
- ## 🔮 Évolutions Futures Possibles
146
-
147
- 1. **Filtrage multiple** : Sélection de plusieurs parcelles simultanément
148
- 2. **Comparaison visuelle** : Graphiques côte-à-côte pour plusieurs parcelles
149
- 3. **Alertes personnalisées** : Notifications pour parcelles à surveiller
150
- 4. **Export parcellaire** : Rapports PDF par parcelle
151
- 5. **Cartographie** : Visualisation géospatiale des parcelles
152
-
153
- ---
154
-
155
- *Développé pour le Hackathon CRA Bretagne 🏆*
156
- *Amélioration continue de l'aide à la décision agricole*
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app.py CHANGED
@@ -736,6 +736,83 @@ class AgricultureAnalyzer:
736
  fig.add_annotation(text="Colonne 'produit' manquante",
737
  xref="paper", yref="paper", x=0.5, y=0.5, showarrow=False)
738
  return fig
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
739
 
740
  # Initialisation de l'analyseur
741
  analyzer = AgricultureAnalyzer()
@@ -907,6 +984,115 @@ def create_interface():
907
  💡 **Utilisation**: Combinez les filtres pour explorer les données en détail
908
  """)
909
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
910
  with gr.TabItem("🔍 Requêtes Herbicides"):
911
  gr.Markdown("## Requêtes avancées pour l'analyse des herbicides")
912
 
 
736
  fig.add_annotation(text="Colonne 'produit' manquante",
737
  xref="paper", yref="paper", x=0.5, y=0.5, showarrow=False)
738
  return fig
739
+
740
+ def get_data_table_by_year_and_parcel(self, year, parcel_id=None, max_rows=1000):
741
+ """Retourne un tableau des données pour une année et optionnellement une parcelle"""
742
+ try:
743
+ filtered_data = self.filter_data_by_year_and_parcel(year, parcel_id)
744
+
745
+ if filtered_data is None or len(filtered_data) == 0:
746
+ if parcel_id and parcel_id != "ALL":
747
+ return None, f"❌ Aucune donnée pour l'année {year} et la parcelle {parcel_id}"
748
+ else:
749
+ return None, f"❌ Aucune donnée pour l'année {year}"
750
+
751
+ # Sélectionner les colonnes les plus importantes pour l'affichage
752
+ display_cols = []
753
+ important_cols = [
754
+ 'millesime', 'numparcell', 'nomparc', 'surfparc',
755
+ 'libelleusag', 'datedebut', 'datefin', 'libevenem',
756
+ 'familleprod', 'produit', 'quantitetot', 'unite'
757
+ ]
758
+
759
+ for col in important_cols:
760
+ if col in filtered_data.columns:
761
+ display_cols.append(col)
762
+
763
+ if not display_cols:
764
+ return None, "❌ Aucune colonne importante trouvée"
765
+
766
+ # Préparer les données pour l'affichage
767
+ display_df = filtered_data[display_cols].copy()
768
+
769
+ # Formater les colonnes pour un meilleur affichage
770
+ if 'surfparc' in display_df.columns:
771
+ display_df['surfparc'] = display_df['surfparc'].round(2)
772
+ if 'quantitetot' in display_df.columns:
773
+ display_df['quantitetot'] = pd.to_numeric(display_df['quantitetot'], errors='coerce').round(3)
774
+
775
+ # Trier par date si disponible, sinon par parcelle
776
+ if 'datedebut' in display_df.columns:
777
+ # Convertir les dates pour le tri
778
+ display_df['date_sort'] = pd.to_datetime(display_df['datedebut'], format='%d/%m/%y', errors='coerce')
779
+ display_df = display_df.sort_values(['numparcell', 'date_sort'])
780
+ display_df = display_df.drop('date_sort', axis=1)
781
+ else:
782
+ display_df = display_df.sort_values('numparcell')
783
+
784
+ # Limiter le nombre de lignes pour l'affichage
785
+ if len(display_df) > max_rows:
786
+ display_df = display_df.head(max_rows)
787
+ info_msg = f"📊 Affichage de {max_rows} premières lignes sur {len(filtered_data)} total"
788
+ else:
789
+ info_msg = f"📊 {len(display_df)} enregistrements au total"
790
+
791
+ # Renommer les colonnes pour un affichage plus clair
792
+ column_names = {
793
+ 'millesime': 'Année',
794
+ 'numparcell': 'N° Parcelle',
795
+ 'nomparc': 'Nom Parcelle',
796
+ 'surfparc': 'Surface (ha)',
797
+ 'libelleusag': 'Culture',
798
+ 'datedebut': 'Date Début',
799
+ 'datefin': 'Date Fin',
800
+ 'libevenem': 'Type Intervention',
801
+ 'familleprod': 'Famille Produit',
802
+ 'produit': 'Produit',
803
+ 'quantitetot': 'Quantité',
804
+ 'unite': 'Unité'
805
+ }
806
+
807
+ # Renommer seulement les colonnes qui existent
808
+ rename_dict = {k: v for k, v in column_names.items() if k in display_df.columns}
809
+ display_df = display_df.rename(columns=rename_dict)
810
+
811
+ return display_df, info_msg
812
+
813
+ except Exception as e:
814
+ print(f"❌ Erreur dans get_data_table_by_year_and_parcel: {e}")
815
+ return None, f"❌ Erreur lors de la génération du tableau: {str(e)[:100]}..."
816
 
817
  # Initialisation de l'analyseur
818
  analyzer = AgricultureAnalyzer()
 
984
  💡 **Utilisation**: Combinez les filtres pour explorer les données en détail
985
  """)
986
 
987
+ with gr.TabItem("📋 Données par Année"):
988
+ gr.Markdown("## Exploration des données tabulaires par année et parcelle")
989
+
990
+ # Contrôles de filtrage identiques à l'onglet précédent
991
+ with gr.Row():
992
+ with gr.Column():
993
+ # Liste déroulante pour sélectionner l'année
994
+ data_year_dropdown = gr.Dropdown(
995
+ choices=available_years,
996
+ value=available_years[-1] if available_years else None,
997
+ label="🗓️ Sélectionner une année",
998
+ info="Choisissez l'année à analyser"
999
+ )
1000
+
1001
+ with gr.Column():
1002
+ # Liste déroulante pour sélectionner la parcelle
1003
+ data_parcel_dropdown = gr.Dropdown(
1004
+ choices=list(zip(parcel_choices, parcel_values)),
1005
+ value="ALL" if available_parcels else None,
1006
+ label="🏠 Sélectionner une parcelle",
1007
+ info="Choisissez une parcelle spécifique ou 'Toutes les parcelles'"
1008
+ )
1009
+
1010
+ # Contrôles supplémentaires
1011
+ with gr.Row():
1012
+ with gr.Column():
1013
+ max_rows_slider = gr.Slider(
1014
+ minimum=100,
1015
+ maximum=5000,
1016
+ value=1000,
1017
+ step=100,
1018
+ label="📊 Nombre maximum de lignes à afficher"
1019
+ )
1020
+
1021
+ with gr.Column():
1022
+ update_data_btn = gr.Button("🔄 Actualiser les données", variant="primary")
1023
+ export_info = gr.Markdown("💡 **Astuce**: Vous pouvez copier les données du tableau ci-dessous")
1024
+
1025
+ # Message d'information
1026
+ data_info_msg = gr.Markdown("")
1027
+
1028
+ # Tableau des données
1029
+ data_table = gr.Dataframe(
1030
+ label="📋 Données détaillées",
1031
+ interactive=False,
1032
+ wrap=True,
1033
+ height=500
1034
+ )
1035
+
1036
+ # Fonction de mise à jour des données
1037
+ def update_data_table(selected_year, selected_parcel, max_rows):
1038
+ if selected_year is None:
1039
+ return "❌ Veuillez sélectionner une année", None
1040
+
1041
+ try:
1042
+ data_df, info_msg = analyzer.get_data_table_by_year_and_parcel(
1043
+ selected_year, selected_parcel, max_rows
1044
+ )
1045
+
1046
+ if data_df is None:
1047
+ return info_msg, None
1048
+
1049
+ return info_msg, data_df
1050
+
1051
+ except Exception as e:
1052
+ return f"❌ Erreur: {str(e)}", None
1053
+
1054
+ # Connecter les contrôles aux mises à jour
1055
+ update_data_btn.click(
1056
+ update_data_table,
1057
+ inputs=[data_year_dropdown, data_parcel_dropdown, max_rows_slider],
1058
+ outputs=[data_info_msg, data_table]
1059
+ )
1060
+
1061
+ data_year_dropdown.change(
1062
+ update_data_table,
1063
+ inputs=[data_year_dropdown, data_parcel_dropdown, max_rows_slider],
1064
+ outputs=[data_info_msg, data_table]
1065
+ )
1066
+
1067
+ data_parcel_dropdown.change(
1068
+ update_data_table,
1069
+ inputs=[data_year_dropdown, data_parcel_dropdown, max_rows_slider],
1070
+ outputs=[data_info_msg, data_table]
1071
+ )
1072
+
1073
+ # Initialiser avec les valeurs par défaut
1074
+ if available_years:
1075
+ default_data_parcel = "ALL"
1076
+ initial_info, initial_data = update_data_table(default_year, default_data_parcel, 1000)
1077
+ data_info_msg.value = initial_info
1078
+ if initial_data is not None:
1079
+ data_table.value = initial_data
1080
+
1081
+ gr.Markdown("""
1082
+ **Informations sur cet onglet:**
1083
+ - 📋 **Vue tabulaire**: Exploration détaillée des données ligne par ligne
1084
+ - 🔍 **Filtrage avancé**: Combinez année et parcelle pour cibler vos recherches
1085
+ - 📊 **Contrôle du volume**: Ajustez le nombre de lignes affichées
1086
+ - 📋 **Colonnes optimisées**: Affichage des informations les plus pertinentes
1087
+ - 🗓️ **Tri intelligent**: Données triées par parcelle et date
1088
+
1089
+ 💡 **Cas d'usage**:
1090
+ - Vérification détaillée des interventions
1091
+ - Export de données pour analyse externe
1092
+ - Traçabilité parcelle par parcelle
1093
+ - Audit des pratiques agricoles
1094
+ """)
1095
+
1096
  with gr.TabItem("🔍 Requêtes Herbicides"):
1097
  gr.Markdown("## Requêtes avancées pour l'analyse des herbicides")
1098