Mapper une réponse API sur un graphique
Scénario courant : interroger une API (ou un repository), récupérer des données sous forme de liste de dictionnaires, et les afficher dans un graphique. Cette page couvre le flux du endpoint au graphique dans Streamlit.
Du endpoint au graphique : le flux complet
Cinq étapes linéaires :
- Appel — requête HTTP ou appel direct au repository
- Données — réponse JSON (liste de dictionnaires)
- Conversion —
pd.DataFrame()pour obtenir un DataFrame - Graphique — Plotly Express consomme directement le DataFrame
- Affichage —
st.plotly_chart()intègre le graphique dans Streamlit
Conversion liste de dicts vers DataFrame
Depuis un repository (accès direct)
import pandas as pd
data = repo.get_par_region(annee=2024)
# data = [{"region": "IDF", "chiffre_affaires": 1250000}, ...]
df = pd.DataFrame(data)
Depuis une API REST (via requests)
import requests
response = requests.get("http://localhost:5000/api/v1/ventes/par-region?annee=2024")
df = pd.DataFrame(response.json()["data"])
Repository vs API
Dans ce cours, vous utilisez principalement le repository en accès direct (sans passer par HTTP). Le résultat est le même : une liste de dictionnaires convertie en DataFrame. L'approche API est montrée pour illustrer le pattern complet, mais dans votre dashboard Streamlit vous appelez directement les méthodes du repository.
Quelle fonction pandas permet de convertir une liste de dictionnaires en DataFrame ?
Cas concret : dashboard avec 3 graphiques
Un exemple intégrant trois graphiques dans un dashboard Streamlit. Ce pattern est celui des exercices.
Chargement centralisé des données
@st.cache_data(ttl=300)
def load_data(region, annee):
return {
"par_region": pd.DataFrame(repo.get_par_region(annee=annee)),
"evolution": pd.DataFrame(repo.get_evolution_mensuelle(region=region, annee=annee)),
"repartition": pd.DataFrame(repo.get_par_categorie(region=region, annee=annee))
}
data = load_data(region, annee)
Centraliser le chargement
Regrouper les appels de données dans une seule fonction cachée garantit la cohérence (mêmes filtres) et une invalidation de cache groupée quand les paramètres changent.
Disposition en colonnes avec graphiques
col1, col2 = st.columns([2, 1])
with col1:
fig_bar = px.bar(
data["par_region"],
x="region",
y="chiffre_affaires",
title="CA par région"
)
st.plotly_chart(fig_bar, use_container_width=True)
with col2:
fig_pie = px.pie(
data["repartition"],
names="categorie",
values="chiffre_affaires",
hole=0.4,
title="Répartition par catégorie"
)
st.plotly_chart(fig_pie, use_container_width=True)
fig_line = px.line(
data["evolution"],
x="mois",
y="chiffre_affaires",
title="Évolution mensuelle",
markers=True
)
st.plotly_chart(fig_line, use_container_width=True)
Organisation de la page
st.columns([2, 1]) crée deux colonnes de largeurs inégales :
- Gauche (ratio 2) : le bar chart, plus large car il affiche plusieurs barres
- Droite (ratio 1) : le donut, compact par nature
- Le line chart occupe toute la largeur en dessous
use_container_width=True
Ajoutez toujours use_container_width=True à st.plotly_chart(). Sans ce paramètre, le graphique utilise une largeur fixe par défaut qui ne s'adapte pas à la colonne. Le résultat est souvent un graphique trop étroit ou qui déborde.
Pourquoi est-il recommandé de regrouper les appels de données dans une seule fonction cachée ?
À retenir
Points clés
- Le flux standard est : API/Repository → liste de dicts → pd.DataFrame() → px.graphique() → st.plotly_chart()
pd.DataFrame(data)convertit directement une liste de dictionnaires- Centralisez le chargement dans une fonction unique décorée
@st.cache_data - Utilisez
st.columns()pour disposer plusieurs graphiques côte à côte - Toujours passer
use_container_width=Trueàst.plotly_chart()