Spaces:
Sleeping
Sleeping
| import pandas as pd | |
| import numpy as np | |
| import plotly.express as px | |
| import plotly.graph_objects as go | |
| from plotly.subplots import make_subplots | |
| import folium | |
| from streamlit_folium import folium_static | |
| import streamlit as st | |
| def create_price_distribution_chart(data, predicted_price=None): | |
| """ | |
| Crée un histogramme de la distribution des prix avec la prédiction | |
| """ | |
| if data is None or 'price' not in data.columns: | |
| return None | |
| fig = px.histogram( | |
| data, | |
| x='price', | |
| nbins=50, | |
| title=" Distribution des Prix Immobiliers", | |
| labels={'price': 'Prix ($)', 'count': 'Nombre de propriétés'}, | |
| color_discrete_sequence=['#3498db'] | |
| ) | |
| # Ajouter une ligne verticale pour la prédiction | |
| if predicted_price is not None: | |
| fig.add_vline( | |
| x=predicted_price, | |
| line_dash="dash", | |
| line_color="red", | |
| annotation_text=f"Votre prédiction: ${predicted_price:,.0f}", | |
| annotation_position="top right" | |
| ) | |
| fig.update_layout( | |
| template="plotly_dark", | |
| plot_bgcolor='rgba(0,0,0,0)', | |
| paper_bgcolor='rgba(0,0,0,0)', | |
| font=dict(color='#D4DCFF'), | |
| title_font_size=20, | |
| showlegend=False | |
| ) | |
| return fig | |
| def create_feature_impact_chart(data, feature_name, predicted_price=None): | |
| """ | |
| Crée un graphique montrant l'impact d'une caractéristique sur le prix | |
| """ | |
| if data is None or feature_name not in data.columns or 'price' not in data.columns: | |
| return None | |
| # Calculer la moyenne des prix par valeur de la caractéristique | |
| feature_impact = data.groupby(feature_name)['price'].mean().reset_index() | |
| fig = px.line( | |
| feature_impact, | |
| x=feature_name, | |
| y='price', | |
| title=f" Impact de {feature_name} sur le Prix", | |
| labels={'price': 'Prix Moyen ($)', feature_name: feature_name.title()}, | |
| markers=True | |
| ) | |
| # Ajouter une ligne horizontale pour la prédiction | |
| if predicted_price is not None: | |
| fig.add_hline( | |
| y=predicted_price, | |
| line_dash="dash", | |
| line_color="red", | |
| annotation_text=f"Votre prédiction: ${predicted_price:,.0f}", | |
| annotation_position="top right" | |
| ) | |
| fig.update_layout( | |
| template="plotly_dark", | |
| plot_bgcolor='rgba(0,0,0,0)', | |
| paper_bgcolor='rgba(0,0,0,0)', | |
| font=dict(color='#D4DCFF'), | |
| title_font_size=16, | |
| title=dict( | |
| x=0.5, | |
| xanchor='center', | |
| y=0.95, | |
| yanchor='top', | |
| pad=dict(t=20, b=30, l=20, r=20) | |
| ) | |
| ) | |
| return fig | |
| def create_price_vs_area_chart(data, predicted_price=None, predicted_area=None): | |
| """ | |
| Crée un graphique de dispersion prix vs surface | |
| """ | |
| if data is None or 'sqft_living' not in data.columns or 'price' not in data.columns: | |
| return None | |
| fig = px.scatter( | |
| data, | |
| x='sqft_living', | |
| y='price', | |
| title=" Prix vs Surface Habitable", | |
| labels={'sqft_living': 'Surface Habitable (pieds²)', 'price': 'Prix ($)'}, | |
| opacity=0.6, | |
| color_discrete_sequence=['#3498db'] | |
| ) | |
| # Ajouter le point de prédiction | |
| if predicted_price is not None and predicted_area is not None: | |
| fig.add_scatter( | |
| x=[predicted_area], | |
| y=[predicted_price], | |
| mode='markers', | |
| marker=dict(size=15, color='red', symbol='star'), | |
| name='Votre prédiction', | |
| showlegend=True | |
| ) | |
| fig.update_layout( | |
| template="plotly_dark", | |
| plot_bgcolor='rgba(0,0,0,0)', | |
| paper_bgcolor='rgba(0,0,0,0)', | |
| font=dict(color='#D4DCFF'), | |
| title_font_size=16 | |
| ) | |
| return fig | |
| def create_correlation_heatmap(data): | |
| """ | |
| Crée une heatmap de corrélation entre les caractéristiques | |
| """ | |
| if data is None: | |
| return None | |
| # Sélectionner les colonnes numériques | |
| numeric_cols = data.select_dtypes(include=[np.number]).columns | |
| if len(numeric_cols) < 2: | |
| return None | |
| correlation_matrix = data[numeric_cols].corr() | |
| fig = px.imshow( | |
| correlation_matrix, | |
| title=" Matrice de Corrélation des Caractéristiques", | |
| color_continuous_scale='RdBu', | |
| aspect="auto" | |
| ) | |
| fig.update_layout( | |
| template="plotly_dark", | |
| plot_bgcolor='rgba(0,0,0,0)', | |
| paper_bgcolor='rgba(0,0,0,0)', | |
| font=dict(color='#D4DCFF'), | |
| title_font_size=16 | |
| ) | |
| return fig | |
| def create_interactive_map(data, lat=None, long=None, predicted_price=None): | |
| """ | |
| Crée une carte interactive avec les propriétés et la prédiction | |
| """ | |
| if data is None or 'lat' not in data.columns or 'long' not in data.columns: | |
| return None | |
| # Calculer le centre de la carte | |
| center_lat = data['lat'].mean() if lat is None else lat | |
| center_long = data['long'].mean() if long is None else long | |
| # Créer la carte | |
| m = folium.Map( | |
| location=[center_lat, center_long], | |
| zoom_start=10, | |
| tiles='cartodbpositron' | |
| ) | |
| # Ajouter les propriétés existantes (échantillon pour éviter la surcharge) | |
| sample_data = data.sample(min(100, len(data))) | |
| for idx, row in sample_data.iterrows(): | |
| folium.CircleMarker( | |
| location=[row['lat'], row['long']], | |
| radius=3, | |
| popup=f"Prix: ${row['price']:,.0f}<br>Surface: {row['sqft_living']} pieds²", | |
| color='blue', | |
| fill=True, | |
| fillOpacity=0.7 | |
| ).add_to(m) | |
| # Ajouter la prédiction si disponible | |
| if lat is not None and long is not None and predicted_price is not None: | |
| folium.Marker( | |
| location=[lat, long], | |
| popup=f"Votre prédiction: ${predicted_price:,.0f}", | |
| icon=folium.Icon(color='red', icon='star') | |
| ).add_to(m) | |
| return m | |
| def create_price_by_zipcode_chart(data, predicted_price=None, predicted_zipcode=None): | |
| """ | |
| Crée un graphique des prix moyens par code postal | |
| """ | |
| if data is None or 'zipcode' not in data.columns or 'price' not in data.columns: | |
| return None | |
| # Calculer le prix moyen par code postal | |
| zipcode_prices = data.groupby('zipcode')['price'].mean().reset_index() | |
| zipcode_prices = zipcode_prices.sort_values('price', ascending=False).head(20) | |
| fig = px.bar( | |
| zipcode_prices, | |
| x='zipcode', | |
| y='price', | |
| title=" Prix Moyen par Code Postal (Top 20)", | |
| labels={'price': 'Prix Moyen ($)', 'zipcode': 'Code Postal'}, | |
| color='price', | |
| color_continuous_scale='viridis' | |
| ) | |
| # Ajouter une ligne horizontale pour la prédiction | |
| if predicted_price is not None: | |
| fig.add_hline( | |
| y=predicted_price, | |
| line_dash="dash", | |
| line_color="red", | |
| annotation_text=f"Votre prédiction: ${predicted_price:,.0f}", | |
| annotation_position="top right" | |
| ) | |
| fig.update_layout( | |
| template="plotly_dark", | |
| plot_bgcolor='rgba(0,0,0,0)', | |
| paper_bgcolor='rgba(0,0,0,0)', | |
| font=dict(color='#D4DCFF'), | |
| title_font_size=16, | |
| xaxis_tickangle=-45, | |
| title=dict( | |
| x=0.5, | |
| xanchor='center', | |
| y=0.95, | |
| yanchor='top', | |
| pad=dict(t=20, b=30, l=20, r=20) | |
| ) | |
| ) | |
| return fig | |
| def create_comparison_dashboard(data, predicted_price, input_features): | |
| """ | |
| Crée un tableau de bord de comparaison | |
| """ | |
| if data is None: | |
| return None | |
| # Calculer les statistiques de comparaison | |
| stats = { | |
| 'Prix moyen du marché': f"${data['price'].mean():,.0f}", | |
| 'Prix médian du marché': f"${data['price'].median():,.0f}", | |
| 'Votre prédiction': f"${predicted_price:,.0f}", | |
| 'Différence avec la moyenne': f"${predicted_price - data['price'].mean():,.0f}", | |
| 'Pourcentage vs moyenne': f"{((predicted_price / data['price'].mean()) - 1) * 100:.1f}%" | |
| } | |
| # Créer un graphique de comparaison | |
| comparison_data = pd.DataFrame({ | |
| 'Métrique': ['Prix Moyen', 'Prix Médian', 'Votre Prédiction'], | |
| 'Prix': [data['price'].mean(), data['price'].median(), predicted_price] | |
| }) | |
| fig = px.bar( | |
| comparison_data, | |
| x='Métrique', | |
| y='Prix', | |
| title=" Comparaison avec le Marché", | |
| color='Métrique', | |
| color_discrete_map={ | |
| 'Prix Moyen': '#3498db', | |
| 'Prix Médian': '#2ecc71', | |
| 'Votre Prédiction': '#e74c3c' | |
| } | |
| ) | |
| fig.update_layout( | |
| template="plotly_dark", | |
| plot_bgcolor='rgba(0,0,0,0)', | |
| paper_bgcolor='rgba(0,0,0,0)', | |
| font=dict(color='#D4DCFF'), | |
| title_font_size=16, | |
| showlegend=False, | |
| title=dict( | |
| x=0.5, | |
| xanchor='center', | |
| y=0.95, | |
| yanchor='top', | |
| pad=dict(t=20, b=30, l=20, r=20) | |
| ) | |
| ) | |
| return fig, stats |