I’m reaching out to seek assistance regarding a specific issue in my Streamlit application.
My application is local for the time being.
Problem Description: Upon selecting a specific type (“revendeur”) and then reverting to “Tous,” I’ve observed a discrepancy in the displayed data. Some products appear in the chart without any evolution data, although they were not present before selecting the specific type.
Detailed Problem Statement:
- I’ve carefully examined the data filtering logic and ensured correct implementation.
- The issue seems to arise specifically when transitioning from a filtered type back to displaying all data (“Tous”).
- Products without evolution data are unexpectedly included in the chart after this transition.
- If I insert a st.write() with the dataframe filtered right before the graph creation, the unexpected products not appear in the dataframe
Request for Insights: I’m seeking insights from the community to understand whether this might be indicative of a Streamlit bug or if there are aspects of my implementation that I may have overlooked.
Code Highlights: For your reference, I’ve included relevant portions of my Python code below:
my function:
def graph_articles_plus_grande_evolution_trimestre(selected_type_vente):
"""construit le graphique en barre des articles ayant eu le plus d'évolutions par trimestre
Args:
selected_type_vente (string): type de vente sélectionné
Returns:
plotly objects: graphique en barre
str: nom du dernier trimestre du dataframe
"""
df_trimestre = pd.read_csv("data/vente_par_articles.csv")
# filtre sur le type de vente sélectionné
if selected_type_vente != "Tous":
df_trimestre = df_trimestre[df_trimestre["Type de vente"] == selected_type_vente]
# Group by pour éviter les valeurs dupliquées
df_filtre_trimestre = df_trimestre.groupby(['Nom du Produit', 'trimestre'])['Montant total HT'].sum().reset_index()
# Tri par client et trimestre pour garantir l'ordre correct
df_filtre_trimestre = df_filtre_trimestre.sort_values(by=['Nom du Produit', 'trimestre'])
# Calculer le pourcentage d'évolution
df_filtre_trimestre['Pourcentage Evolution'] = df_filtre_trimestre.groupby('Nom du Produit')['Montant total HT'].pct_change() * 100
# pivote les lignes en colonnes
df_pivot_trimestre = df_filtre_trimestre.pivot(index='Nom du Produit', columns='trimestre', values='Pourcentage Evolution').reset_index()
# Ajouter une colonne pour le graphique
df_pivot_trimestre['Evolution'] = df_pivot_trimestre.apply(lambda row: [0 if pd.isnull(value) else value for value in row.values[1:-1]], axis=1)
# remplace les valeurs nan par des 0
df_pivot_trimestre.fillna(0, inplace=True)
# Trouver le nom de la colonne du dernier trimestre
dernier_trimestre = df_pivot_trimestre.columns[-2]
# Exclure les valeurs à zéro
df_trie_trimestre = df_pivot_trimestre[(df_pivot_trimestre[dernier_trimestre] != 0) & (df_pivot_trimestre[dernier_trimestre].notna())]
# Trier le DataFrame par la colonne du dernier trimestre
df_trie_trimestre = df_trie_trimestre.sort_values(by=dernier_trimestre, ascending=False).head(15)
# Créer le graphique en barres avec Plotly Express
fig = px.bar(df_trie_trimestre, y='Nom du Produit', x=dernier_trimestre,
template='plotly_white')
# Inverser l'ordre des barres pour que les plus grandes soient en haut
fig.update_layout(hovermode=False,dragmode=False, barmode='stack', yaxis={'categoryorder': 'total ascending'})
# Changer la couleur des barres en fonction de leur valeur
fig.update_traces(marker_color=['rgb(69, 197, 127)' if val >= 0 else 'red' for val in df_trie_trimestre[dernier_trimestre]])
# Ajouter des étiquettes de texte pour chaque valeurs différentes de 0
for index, row in df_trie_trimestre.iterrows():
value = row[dernier_trimestre]
fig.add_annotation(
x=value,
y=row['Nom du Produit'],
text=f"{value:.2f}%",
showarrow=False,
font=dict(size=12, color='rgb(69, 197, 127)' if value >= 0 else 'red'),
xshift=30 if value > 0 else -30 )
return fig, dernier_trimestre
the page:
import streamlit as st
import pandas as pd
from bibliotheque.lib import *
config_pages_menu("wide")
formatage_de_la_page("style.css")
df = pd.read_csv("data/vente_par_articles.csv")
# Composants situés dans la barre des filtres
st.sidebar.header("Menu")
type_vente_liste = ["Tous"] + sorted(df['Type de vente'].unique().tolist())
selected_type_vente = st.sidebar.selectbox("Choisir un type de vente", type_vente_liste)
# TITRE
st.title("Evolution des montant de vente par clients par trimestres")
col1, col2 = st.columns(2)
graph_trimestre, trimestre = graph_articles_plus_grande_evolution_trimestre(selected_type_vente)
col1.write(f"<h4>Pourcentage d'évolution du montant de vente par articles en {trimestre}</h4>", unsafe_allow_html=True)
col1.plotly_chart(graph_trimestre, use_container_width=True)
graph_annee, annee = graph_articles_plus_grande_evolution_annee(selected_type_vente)
col2.write(f"<h4>Pourcentage d'évolution du montant de vente par articles en {annee}</h4>", unsafe_allow_html=True)
col2.plotly_chart(graph_annee, use_container_width=True)
df_style, nombre_lignes = calcul_dataframe_evolution_vente_par_articles(selected_type_vente)
column_config = {
"Evolution": st.column_config.LineChartColumn(
"Evolution par trimestre",
width="medium",
help="L'évolution du chiffre d'affaires par trimestre",
y_min=df["Montant total HT"].min(),
y_max=df["Montant total HT"].max(),
),
}
st.dataframe(df_style.format(precision=2), height=36 * nombre_lignes, column_config=column_config, hide_index=True)
To illustrate my problem, here’s what it looks like with a diagram:v
Additional Context: This is not the first time I’ve encountered this problem, but in previous instances, I attributed it to issues in my code.
Seeking Community Wisdom: If anyone has encountered a similar behavior or has suggestions on how to troubleshoot this discrepancy effectively, I would greatly appreciate your guidance. Your expertise is invaluable in resolving this issue.
Thank you for your time and consideration