File size: 6,728 Bytes
676811f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
"""
Module de visualisation des données agricoles
"""
import plotly.express as px
import plotly.graph_objects as go
from config import RISK_COLORS, PLOT_CONFIG


class AgricultureVisualizer:
    """Classe responsable de la création des visualisations"""
    
    def __init__(self, data=None, risk_analysis=None):
        self.df = data
        self.risk_analysis = risk_analysis
    
    def set_data(self, data, risk_analysis=None):
        """Définit les données à visualiser"""
        self.df = data
        if risk_analysis is not None:
            self.risk_analysis = risk_analysis
    
    def create_risk_visualization(self):
        """Crée la visualisation des risques"""
        if self.risk_analysis is None or len(self.risk_analysis) == 0:
            # Créer un graphique vide avec message d'erreur
            fig = px.scatter(title="❌ Aucune donnée d'analyse des risques disponible")
            fig.add_annotation(
                text="Veuillez charger les données d'abord", 
                xref="paper", yref="paper", x=0.5, y=0.5, showarrow=False
            )
            return fig
        
        risk_df = self.risk_analysis.reset_index()
        
        # Vérifier quelles colonnes sont disponibles pour hover_data
        available_hover_cols = []
        for col in ['nomparc', 'libelleusag']:
            if col in risk_df.columns:
                available_hover_cols.append(col)
        
        fig = px.scatter(
            risk_df, 
            x='surfparc', 
            y='IFT_herbicide_approx',
            color='Risque_adventice',
            size='Nb_herbicides',
            hover_data=available_hover_cols if available_hover_cols else None,
            color_discrete_map=RISK_COLORS,
            title="🎯 Analyse du Risque Adventice par Parcelle",
            labels={
                'surfparc': 'Surface de la parcelle (ha)',
                'IFT_herbicide_approx': 'IFT Herbicide (approximatif)',
                'Risque_adventice': 'Niveau de risque'
            }
        )
        
        fig.update_layout(
            width=PLOT_CONFIG["width"], 
            height=PLOT_CONFIG["height"], 
            title_font_size=PLOT_CONFIG["title_font_size"]
        )
        return fig
    
    def create_culture_analysis(self):
        """Analyse par type de culture"""
        if self.df is None or len(self.df) == 0:
            # Créer un graphique vide avec message d'erreur
            fig = px.pie(title="❌ Aucune donnée disponible")
            fig.add_annotation(
                text="Veuillez charger les données d'abord", 
                xref="paper", yref="paper", x=0.5, y=0.5, showarrow=False
            )
            return fig
        
        if 'libelleusag' not in self.df.columns:
            fig = px.pie(title="❌ Colonne 'libelleusag' non disponible")
            fig.add_annotation(
                text="Les données de culture ne sont pas disponibles", 
                xref="paper", yref="paper", x=0.5, y=0.5, showarrow=False
            )
            return fig
        
        culture_counts = self.df['libelleusag'].value_counts()
        
        fig = px.pie(
            values=culture_counts.values, 
            names=culture_counts.index,
            title="🌱 Répartition des Cultures"
        )
        
        fig.update_layout(width=700, height=500)
        return fig
    
    def create_risk_distribution(self):
        """Distribution des niveaux de risque"""
        if self.risk_analysis is None or len(self.risk_analysis) == 0:
            # Créer un graphique vide avec message d'erreur
            fig = px.bar(title="❌ Aucune analyse des risques disponible")
            fig.add_annotation(
                text="Veuillez charger les données d'abord", 
                xref="paper", yref="paper", x=0.5, y=0.5, showarrow=False
            )
            return fig
        
        risk_counts = self.risk_analysis['Risque_adventice'].value_counts()
        
        fig = px.bar(
            x=risk_counts.index, 
            y=risk_counts.values,
            color=risk_counts.index,
            color_discrete_map=RISK_COLORS,
            title="📊 Distribution des Niveaux de Risque Adventice",
            labels={'x': 'Niveau de risque', 'y': 'Nombre de parcelles'}
        )
        
        fig.update_layout(width=700, height=500, showlegend=False)
        return fig
    
    def create_herbicide_timeline(self):
        """Crée un graphique de l'évolution temporelle des herbicides"""
        if self.df is None or len(self.df) == 0:
            fig = px.line(title="❌ Aucune donnée disponible")
            fig.add_annotation(
                text="Veuillez charger les données d'abord", 
                xref="paper", yref="paper", x=0.5, y=0.5, showarrow=False
            )
            return fig
        
        if 'millesime' not in self.df.columns or 'familleprod' not in self.df.columns:
            fig = px.line(title="❌ Colonnes nécessaires non disponibles")
            fig.add_annotation(
                text="Les données temporelles ne sont pas disponibles", 
                xref="paper", yref="paper", x=0.5, y=0.5, showarrow=False
            )
            return fig
        
        # Filtrer les herbicides et grouper par année
        herbicides_df = self.df[self.df['familleprod'] == 'Herbicides']
        if len(herbicides_df) == 0:
            fig = px.line(title="❌ Aucune donnée d'herbicide disponible")
            return fig
        
        yearly_herbicides = herbicides_df.groupby('millesime').agg({
            'numparcell': 'nunique',
            'quantitetot': 'sum'
        }).reset_index()
        
        fig = px.line(
            yearly_herbicides,
            x='millesime',
            y='quantitetot',
            title="📈 Évolution de l'Usage des Herbicides par Année",
            labels={
                'millesime': 'Année',
                'quantitetot': 'Quantité totale d\'herbicides'
            }
        )
        
        fig.update_layout(width=700, height=400)
        return fig
    
    def create_surface_analysis(self):
        """Analyse de la distribution des surfaces"""
        if self.df is None or len(self.df) == 0:
            fig = px.histogram(title="❌ Aucune donnée disponible")
            return fig
        
        fig = px.histogram(
            self.df,
            x='surfparc',
            nbins=20,
            title="📏 Distribution des Surfaces de Parcelles",
            labels={
                'surfparc': 'Surface (ha)',
                'count': 'Nombre de parcelles'
            }
        )
        
        fig.update_layout(width=700, height=400)
        return fig