Skip to content
Snippets Groups Projects
Commit e6d79d3a authored by Hu Marilyne's avatar Hu Marilyne
Browse files

Mon commit

parent dffd235c
No related branches found
No related tags found
No related merge requests found
File added
File added
app.py 0 → 100644
import pandas as pd
import numpy as np
import streamlit as st
from matplotlib.colors import LinearSegmentedColormap, ListedColormap, to_hex
import matplotlib.patches as mpatches
from io import BytesIO
import utils_graph
from utils_graph import plot_graph
st.title('Logiciel cartographique')
upload_file = st.file_uploader('Charger vos données en format .csv ou .xlsx.')
if upload_file is not None :
# chargement des données
filename = upload_file.name
# vérifie la forme des données
if filename.endswith('.csv'):
df = pd.read_csv(upload_file)
st.success("Fichier CSV chargé avec succès.")
elif filename.endswith('.xlsx') or filename.endswith('.xls'):
df = pd.read_excel(upload_file)
st.success("Fichier Excel chargé avec succès.")
else:
st.error("Format de fichier non supporté. Veuillez charger un .csv ou un .xlsx.")
# visualisation des données
st.header('Visualisation des données :')
st.write(df.head(5)) # pour 5 lignes
# bloc sur les infos du dataframe
st.subheader('Information sur les données :')
with st.expander("📊 Aperçu du DataFrame"):
st.markdown(f"**Dimensions :** {df.shape[0]} lignes × {df.shape[1]} colonnes")
st.markdown("**Colonnes disponibles :**")
st.write(list(df.columns))
st.markdown("**Types de données :**")
st.write(df.dtypes)
st.subheader('Choix d\'option :')
if df.shape[0]>12 :
nb_line = st.number_input(
"Nombre de lignes à afficher",
min_value=1,
max_value=len(df),
value=5,
step=1,
format="%d" # ← force l'affichage et le retour d'un entier
)
# choix des colonnes à tracer
columns = df.columns.tolist()
col_x = st.selectbox('Choisir la colonne des valeurs (x)', columns)
col_y = st.selectbox('Choisir la colonne des catégories (y)', columns)
title_choice = st.checkbox("Voulez-vous mettre un titre au graphique ?")
if title_choice:
title = st.text_input("Entrez le titre du graphique :", key="title_input")
else:
title = None
x_choice = st.checkbox("Voulez-vous nommer l'axe des abscisses ?")
if x_choice:
xlabel = st.text_input("Entrez le nom de l'axe des abscisses :", key="xlabel_input")
else:
xlabel = None
y_choice = st.checkbox("Voulez-vous nommer l'axe des ordonnées ?")
if y_choice:
ylabel = st.text_input("Entrez le nom de l'axe des ordonnées :", key="ylabel_input")
else:
ylabel = None
model_graph = utils_graph.plot_graph(df = df.loc[:nb_line-1, :], x = col_x, y = col_y)
legend_choice = st.checkbox('Voulez-vous mettre une légende de couleurs ?')
if legend_choice:
col_color = st.selectbox('Choisir la colonne des numéros de couleurs', columns)
try :
# Premier tracé pour générer list_colors
model_graph.barh_subplot(colors=col_color, show=False, title= title, xlabel= xlabel, ylabel=ylabel)
colors_rgba = model_graph.list_colors
custom_colors = {}
legend_labels = []
legend_indices = []
st.markdown("Personnalisation des couleurs et des légendes :")
for i, rgba in enumerate(colors_rgba):
hex_color = to_hex(rgba)
col1, col2 = st.columns(2)
with col1:
picked_color = st.color_picker(f"Couleur {i+1}", hex_color)
with col2:
label = st.text_input(f"Légende {i+1}", key=f"legend_{i}")
if label.strip(): # légende non vide
legend_labels.append(label)
legend_indices.append(i)
custom_colors[i] = {"color": picked_color, "label": label}
# Retracer avec légendes non vides
barh = model_graph.barh_subplot(
colors=col_color,
legend_list=legend_labels,
title_legend="Légende",
legend_indices=legend_indices,
title= title,
xlabel= xlabel,
ylabel= ylabel
)
st.pyplot(barh)
except Exception as e:
st.warning("⚠️ Cette colonne ne semble pas contenir des numéros de couleurs valides.")
else:
# Tracer sans légende
barh = model_graph.barh_subplot(title= title, xlabel= xlabel, ylabel= ylabel)
st.pyplot(barh)
# Sauvegarde du graphique dans un buffer en mémoire
img_buffer = BytesIO()
barh.savefig(img_buffer, format='png', dpi=300, bbox_inches='tight')
img_buffer.seek(0) # Revenir au début du buffer
# Bouton de téléchargement
st.download_button(
label="📥 Télécharger le graphique",
data=img_buffer,
file_name="mon_graphique.png",
mime="image/png"
)
File added
File added
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
from matplotlib.colors import LinearSegmentedColormap, ListedColormap
import matplotlib.patches as mpatches
# partie sur les légendes à revoir
c_map = ['#000091', '#AB0345']
cmap = LinearSegmentedColormap.from_list("custom_cmap", c_map)
class plot_graph() :
def __init__(self,df, x, y, figsize = (10,6), ax = None, fig = None):
self.df = df
self.x = self.df[x]
self.y = self.df[y]
self.figsize = figsize
self.ax = ax
self.fig = fig
def barh_subplot(self, title = None, xlabel = None, ylabel = None,
path = None, yticklabels = None, xticklabels = None, colors = None,
legend_list = None, title_legend = None, show = True, force_new_fig= True,
legend_indices=None):
# couleurs des barres
if colors in self.df.columns and not self.df[colors].empty:
valid_colors = [c for c in self.df[colors] if not pd.isna(c)]
n_color = max(valid_colors) + 1
self.list_colors = cmap(np.linspace(0,1,n_color))
colors_bars = ['lightgray' if pd.isna(n) else self.list_colors[n] for n in self.df[colors]]
hatches = ['//' if pd.isna(n) else None for n in self.df[colors]]
elif colors is None :
self.list_colors = None
colors_bars = colors
hatches = None
# Tracer le graphique
if self.ax is None or self.fig is None or force_new_fig:
self.fig, self.ax = plt.subplots(figsize=self.figsize)
bars = self.ax.barh(self.y, self.x, color = colors_bars, hatch = hatches)
if legend_list and colors is not None:
legend_elements = []
# Toujours ajouter la légende pour les valeurs manquantes (None)
if any(pd.isna(c) or c is None for c in self.df[colors]):
legend_elements.append(mpatches.Patch(facecolor='lightgray', hatch='//', label='Indisponible'))
if legend_indices is None:
legend_indices = list(range(len(legend_list))) # toutes les légendes par défaut
for idx in legend_indices:
if idx < len(self.list_colors) and idx < len(legend_list):
legend_elements.append(mpatches.Patch(facecolor=self.list_colors[idx], label=legend_list[idx]))
self.ax.legend(handles=legend_elements, loc='best', title=title_legend)
if xticklabels is False :
self.ax.set_xticklabels([])
elif xticklabels is not None :
self.ax.set_xticklabels(xticklabels)
if yticklabels is False :
self.ax.set_yticklabels([])
elif yticklabels is not None :
self.ax.set_yticklabels(yticklabels)
self.ax.set_xlabel(xlabel)
self.ax.set_ylabel(ylabel)
self.ax.set_title(title, pad=30, color='black', fontsize=16)
self.ax.grid(axis='x', linestyle='-', alpha=0.2)
plt.tight_layout()
if show :
plt.show()
if path:
plt.savefig(path, dpi=500, bbox_inches='tight')
return self.fig
# partie à revoir selon les besoins des missions
def annotation(self) :
""" # Ajouter des annotations sur les barres
if pourcentage_list == False :
for n, bar in enumerate(bars):
width = bar.get_width()
if np.isnan(width):
# Gérer le cas où la largeur est NaN
text = "N/A"
elif nombre and slash :
text = f"{round(width)}/{self.df.loc[n,slash]}"
elif nombre and slash == False :
text = f"{round(width)}"
else:
if pourcentage and self.df.shape[0]<10:
text = f"{round((width / self.df['count'].sum()) * 100, 1)}% ({int(width)})"
elif pourcentage and self.df.shape[0]>=10:
text = f"{round((width / total) * 100, 1)}% ({int(width)})"
else :
text = f"{round(width)}%"
if width == 0 :
ax.text(2 if not np.isnan(width) else 0 , bar.get_y() + bar.get_height() / 2,
text,va='center', ha='left', color='gray', fontsize=9)
else :
ax.text(width * 1.01 if not np.isnan(width) else 0 , bar.get_y() + bar.get_height() / 2,
text, va='center', ha='left', color='gray', fontsize=9)
elif pourcentage_list != False:
for n,bar in enumerate(bars):
width = bar.get_width()
if np.isnan(width):
# Gérer le cas où la largeur est NaN
text = "N/A"
elif inverse :
text = f"{width}% ({self.df.loc[n,pourcentage_list]})"
else :
text = f"{self.df.loc[n,pourcentage_list]}% ({width})"
if width == 0 :
ax.text(2 if not np.isnan(width) else 0 , bar.get_y() + bar.get_height() / 2,
text,va='center', ha='left', color='gray', fontsize=9)
else :
ax.text(width * 1.01 if not np.isnan(width) else 0 , bar.get_y() + bar.get_height() / 2,
text, va='center', ha='left', color='gray', fontsize=9)"""
pass
def encadrer(self) :
"""iscod_index = self.df[self.df['denomination_cfa'] == 'ISCOD'].index.values[0]
bars[iscod_index].set_edgecolor('black') # Couleur de la bordure
bars[iscod_index].set_linewidth(2) # Épaisseur de la bordure """
pass
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment