""" 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