Spaces:
Sleeping
Sleeping
| """plot_utils.py | |
| Ce module contient des fonctions utilitaires pour la visualisation des données, notamment des graphiques linéaires, histogrammes, boxplots, scatterplots et heatmaps de corrélation, ainsi que des fonctions spécifiques pour visualiser les résultats d'une analyse en composantes principales (ACP). | |
| Les fonctions incluent : | |
| - lineplot_graphic : pour visualiser les tendances de plusieurs variables au fil du temps ou d'une autre variable | |
| - histrogram_graphic : pour visualiser la distribution d'une variable | |
| - boxplot_graphic : pour visualiser la distribution d'une variable en fonction d'une autre variable | |
| - scatterplot_graphic : pour visualiser la relation entre deux variables | |
| - pearson_heatmap_graphic : pour visualiser la corrélation entre les variables d'un dataframe en utilisant la méthode de Pearson | |
| - spearman_heatmap_graphic : pour visualiser la corrélation entre les variables d'un dataframe en utilisant la méthode de Spearman | |
| 'un dataframe en utilisant la méthode de Spearman | |
| - heatmap_by_group : pour visualiser la corrélation entre les variables d'un dataframe en fonction d'une variable de regroupement | |
| - plot_pca_projection : pour visualiser la projection des données dans le plan défini par les composantes principales | |
| - plot_scree : pour visualiser l'éboulis des valeurs propres (scree plot) pour l'ACP | |
| - plot_correlation_circle : pour visualiser le cercle des corrélations pour les composantes principales | |
| """ | |
| import matplotlib.pyplot as plt | |
| import seaborn as sns | |
| import pandas as pd | |
| import numpy as np | |
| def lineplot_graphic(df: pd.DataFrame, x: str, y_list: list, title: str, xlabel: str, ylabel: str, hue: str=None): | |
| """ | |
| graphiques linéaire pour visualiser le pourcentage des valeurs pour un axe x et plusieurs axes y | |
| df: dataframe contenant les données à visualiser | |
| x: nom de la colonne à utiliser pour l'axe x | |
| y_list: liste des colonnes à utiliser pour les axes y | |
| hue: nom de la colonne à utiliser pour colorer les points (optionnel) | |
| title: titre du graphique | |
| xlabel: label de l'axe x | |
| ylabel: label de l'axe y | |
| """ | |
| try: | |
| plt.figure(figsize=(12, 6)) | |
| for y in y_list: | |
| if hue is not None: | |
| sns.lineplot(data=df, x=x, y=y, hue=hue) | |
| else: | |
| sns.lineplot(data=df, x=x, y=y, label=y) | |
| plt.title(title) | |
| plt.xlabel(xlabel) | |
| plt.ylabel(ylabel) | |
| plt.legend() | |
| plt.show() | |
| except ImportError as e: | |
| print("Erreur d'importation : ", e) | |
| return | |
| def histrogram_graphic(df: pd.DataFrame, x: str, title: str, xlabel: str, ylabel: str): | |
| """ | |
| graphique histogramme pour visualiser la distribution d'une variable | |
| df: dataframe contenant les données à visualiser | |
| x: nom de la colonne à utiliser pour l'axe x | |
| title: titre du graphique | |
| xlabel: label de l'axe x | |
| ylabel: label de l'axe y | |
| """ | |
| try: | |
| plt.figure(figsize=(12, 6)) | |
| sns.histplot(data=df, x=x, kde=True) | |
| plt.title(title) | |
| plt.xlabel(xlabel) | |
| plt.ylabel(ylabel) | |
| plt.show() | |
| except ImportError as e: | |
| print("Erreur d'importation : ", e) | |
| return | |
| def boxplot_graphic(df: pd.DataFrame, x: str, y: str=None, title: str="", xlabel: str="", ylabel: str=""): | |
| """ | |
| graphique boxplot pour visualiser la distribution d'une variable en fonction d'une autre variable | |
| df: dataframe contenant les données à visualiser | |
| x: nom de la colonne à utiliser pour l'axe x | |
| y: nom de la colonne à utiliser pour l'axe y optionnel | |
| title: titre du graphique | |
| xlabel: label de l'axe x | |
| ylabel: label de l'axe y | |
| """ | |
| try: | |
| plt.figure(figsize=(12, 6)) | |
| sns.boxplot(data=df, x=x, y=y) | |
| plt.title(title) | |
| plt.xlabel(xlabel) | |
| plt.ylabel(ylabel) | |
| plt.show() | |
| except ImportError as e: | |
| print("Erreur d'importation : ", e) | |
| return | |
| def scatterplot_graphic(df: pd.DataFrame, x: str, y: str, title: str, xlabel: str, ylabel: str, hue: str=None): | |
| """ | |
| graphique scatterplot pour visualiser la relation entre deux variables | |
| df: dataframe contenant les données à visualiser | |
| x: nom de la colonne à utiliser pour l'axe x | |
| y: nom de la colonne à utiliser pour l'axe y | |
| title: titre du graphique | |
| xlabel: label de l'axe x | |
| ylabel: label de l'axe y | |
| hue: nom de la colonne à utiliser pour colorer les points (optionnel) | |
| """ | |
| try: | |
| plt.figure(figsize=(12, 6)) | |
| sns.scatterplot(data=df, x=x, y=y, hue=hue) | |
| plt.title(title) | |
| plt.xlabel(xlabel) | |
| plt.ylabel(ylabel) | |
| plt.show() | |
| except ImportError as e: | |
| print("Erreur d'importation : ", e) | |
| return | |
| def spearman_heatmap_graphic(df: pd.DataFrame, cols: list, title: str): | |
| """ | |
| graphique heatmap pour visualiser la corrélation entre les variables d'un dataframe | |
| df: dataframe contenant les données à visualiser | |
| cols: liste des colonnes à utiliser pour le calcul de la corrélation | |
| title: titre du graphique | |
| """ | |
| try: | |
| plt.figure(figsize=(12, 6)) | |
| corr = df[cols].corr(method='spearman') | |
| sns.heatmap(corr, annot=True, cmap='coolwarm', vmin=-1, vmax=1, mask=np.triu(corr)) | |
| plt.title(title) | |
| plt.show() | |
| except ImportError as e: | |
| print("Erreur d'importation : ", e) | |
| return | |
| def pearson_heatmap_graphic(df: pd.DataFrame, cols: list, title: str): | |
| """ | |
| graphique heatmap pour visualiser la corrélation entre les variables d'un dataframe | |
| df: dataframe contenant les données à visualiser | |
| cols: liste des colonnes à utiliser pour le calcul de la corrélation | |
| title: titre du graphique | |
| """ | |
| try: | |
| plt.figure(figsize=(12, 6)) | |
| corr = df[cols].corr(method='pearson') | |
| sns.heatmap(corr, annot=True, cmap='coolwarm', vmin=-1, vmax=1, mask=np.triu(corr)) | |
| plt.title(title) | |
| plt.show() | |
| except ImportError as e: | |
| print("Erreur d'importation : ", e) | |
| return | |
| def heatmap_by_group(df, group_col, cols, method="pearson"): | |
| """ Affiche une heatmap de corrélation pour chaque groupe défini par group_col | |
| df: dataframe contenant les données à visualiser | |
| group_col: nom de la colonne à utiliser pour regrouper les données | |
| cols: liste des colonnes à utiliser pour le calcul de la corrélation | |
| method: méthode de corrélation ("pearson" ou "spearman") | |
| """ | |
| groups = df[group_col].unique() | |
| n = len(groups) | |
| fig, axes = plt.subplots(nrows=n//2 + n%2, ncols=2, figsize=(14, 5*n//2)) | |
| axes = axes.flatten() | |
| for i, group in enumerate(groups): | |
| df_group = df[df[group_col] == group] | |
| corr = df_group[cols].corr(method=method) | |
| sns.heatmap( | |
| corr, | |
| ax=axes[i], | |
| annot=True, | |
| cmap="coolwarm", | |
| vmin=-1, | |
| vmax=1, | |
| mask=np.triu(corr) | |
| ) | |
| axes[i].set_title(f"{method.capitalize()} - {group}") | |
| # supprime les axes vides | |
| for j in range(i+1, len(axes)): | |
| fig.delaxes(axes[j]) | |
| plt.tight_layout() | |
| plt.show() | |
| def plot_pca_projection(X_pca, df, label_col="item", hue_col=None, pc1=1, pc2=2, title=None): | |
| """ | |
| affiche la projection des données dans le plan défini par les composantes principales spécifiées. | |
| arguments: | |
| - X_pca : array-like, les données transformées dans l'espace des composantes principales | |
| - df : pd.DataFrame, le DataFrame original contenant les données | |
| - label_col : str, le nom de la colonne à utiliser pour les étiquettes des points (par défaut "item") | |
| - hue_col : str, le nom de la colonne à utiliser pour la coloration des points (par défaut None) | |
| - pc1 : int, le numéro de la première composante principale à afficher (par défaut 1) | |
| - pc2 : int, le numéro de la deuxième composante principale à afficher (par défaut 2) | |
| - title : str, le titre du graphique (par défaut None, affichera un titre générique) | |
| """ | |
| try: | |
| pca_df = pd.DataFrame({ | |
| f"PC{pc1}": X_pca[:, pc1 - 1], | |
| f"PC{pc2}": X_pca[:, pc2 - 1], | |
| label_col: df[label_col].values | |
| }) | |
| if hue_col is not None: | |
| pca_df[hue_col] = df[hue_col].values | |
| plt.figure(figsize=(10, 7)) | |
| if hue_col is not None: | |
| # détecter si numérique | |
| if pd.api.types.is_numeric_dtype(pca_df[hue_col]): | |
| sc = plt.scatter( | |
| pca_df[f"PC{pc1}"], | |
| pca_df[f"PC{pc2}"], | |
| c=pca_df[hue_col], | |
| cmap="viridis", | |
| alpha=0.7 | |
| ) | |
| cbar = plt.colorbar(sc) | |
| cbar.set_label(hue_col) | |
| else: | |
| # catégoriel | |
| sns.scatterplot( | |
| data=pca_df, | |
| x=f"PC{pc1}", | |
| y=f"PC{pc2}", | |
| hue=hue_col, | |
| alpha=0.7 | |
| ) | |
| plt.legend(bbox_to_anchor=(1.05, 1), loc='upper left') | |
| else: | |
| # fallback : label_col | |
| sns.scatterplot( | |
| data=pca_df, | |
| x=f"PC{pc1}", | |
| y=f"PC{pc2}", | |
| hue=label_col, | |
| alpha=0.7 | |
| ) | |
| plt.legend(bbox_to_anchor=(1.05, 1), loc='upper left') | |
| plt.title(title if title else f"Projection ACP - PC{pc1} vs PC{pc2}") | |
| plt.xlabel(f"PC{pc1}") | |
| plt.ylabel(f"PC{pc2}") | |
| plt.grid(True) | |
| plt.tight_layout() | |
| plt.show() | |
| except Exception as e: | |
| print(f"Erreur lors de la projection ACP : {e}") | |
| def plot_scree(explained_var, cumulative_var): | |
| """ | |
| Affiche l'éboulis des valeurs propres (scree plot) pour visualiser la variance expliquée par chaque composante principale. | |
| arguments: | |
| - explained_var : array-like, pourcentage de variance expliquée par chaque composante principale | |
| - cumulative_var : array-like, pourcentage de variance cumulée expliquée par les composantes principales | |
| """ | |
| # Graphique | |
| plt.figure(figsize=(8,5)) | |
| # Barres (variance individuelle) | |
| plt.bar(range(1, len(explained_var)+1), explained_var, alpha=0.7) | |
| # Ligne (variance cumulée) | |
| plt.plot(range(1, len(cumulative_var)+1), cumulative_var, marker='o', color='red') | |
| # Labels | |
| plt.xlabel("Rang de l'axe d'inertie") | |
| plt.ylabel("Pourcentage d'inertie") | |
| plt.title("Éboulis des valeurs propres") | |
| plt.xticks(range(1, len(explained_var)+1)) | |
| plt.ylim(0, 100) | |
| plt.grid(True) | |
| plt.show() | |
| def plot_correlation_circle(pca, features): | |
| """ | |
| Affiche le cercle des corrélations pour les deux premières composantes principales. | |
| arguments: | |
| - pca : objet PCA après ajustement | |
| - features : liste des noms des variables utilisées dans la PCA | |
| """ | |
| x, y = 0,1 | |
| fig, ax = plt.subplots(figsize=(10, 9)) # On peut ajuster la taille du graphique selon les besoins | |
| # Affichage des flèches pour chaque variable | |
| for i in range(0, pca.components_.shape[1]): | |
| ax.arrow(0, | |
| 0, # Start the arrow at the origin | |
| pca.components_[0, i], #0 for PC1 | |
| pca.components_[1, i], #1 for PC2 | |
| head_width=0.07, | |
| head_length=0.07, | |
| width=0.02, ) | |
| # Affichage des noms des variables à la fin de chaque flèche | |
| plt.text(pca.components_[0, i] + 0.05, | |
| pca.components_[1, i] + 0.05, | |
| features[i]) | |
| # affichage des lignes horizontales et verticales | |
| plt.plot([-1, 1], [0, 0], color='grey', ls='--') | |
| plt.plot([0, 0], [-1, 1], color='grey', ls='--') | |
| # nom des axes, avec le pourcentage d'inertie expliqué | |
| plt.xlabel('F{} ({}%)'.format(x+1, round(100*pca.explained_variance_ratio_[x],1))) | |
| plt.ylabel('F{} ({}%)'.format(y+1, round(100*pca.explained_variance_ratio_[y],1))) | |
| plt.title("Cercle des corrélations (F{} et F{})".format(x+1, y+1)) | |
| an = np.linspace(0, 2 * np.pi, 100) | |
| plt.plot(np.cos(an), np.sin(an)) # Add a unit circle for scale | |
| plt.axis('equal') | |
| plt.show(block=False) |