Dashboards (Streamlit / Dash / Gradio)
Convierte notebooks en aplicaciones compartibles: Streamlit para dashboards de datos rápidos, Dash para productos centrados en Plotly, Gradio para demostraciones de modelos.
Receta
Tarjeta de receta de referencia rápida, lista para copiar y pegar.
# streamlit_app.py
import streamlit as st
import pandas as pd
@st.cache_data
def load():
return pd.read_parquet("sales.parquet")
df = load()
region = st.selectbox("Región", sorted(df["region"].unique()))
filtered = df[df["region"] == region]
st.line_chart(filtered.set_index("ordered_at")["revenue"])Cuándo usar esto:
- Los stakeholders necesitan filtros sin Jupyter
- El equipo de ML quiere una interfaz de puntuación rápida (Gradio)
- Dashboards de Plotly con callbacks y autenticación (Dash)
- Herramientas internas entregadas en días, no meses
Ejemplo de Trabajo
# Patrón mínimo de Streamlit + Plotly
import streamlit as st
import pandas as pd
import plotly.express as px
st.set_page_config(page_title="Explorador de Ingresos", layout="wide")
@st.cache_data(show_spinner="Cargando ventas...")
def load_sales() -> pd.DataFrame:
# Reemplazar con read_parquet en producción
return pd.DataFrame(
{
"ordered_at": pd.date_range("2025-01-01", periods=30, freq="D", tz="UTC"),
"region": ["East", "West"] * 15,
"revenue": range(30),
}
)
df = load_sales()
col1, col2 = st.columns(2)
with col1:
regions = st.multiselect("Regiones", sorted(df["region"].unique()), default=["East"])
with col2:
min_rev = st.slider("Ingresos mínimos", 0, int(df["revenue"].max()), 0)
filtered = df[df["region"].isin(regions) & (df["revenue"] >= min_rev)]
fig = px.line(filtered, x="ordered_at", y="revenue", color="region")
st.plotly_chart(fig, use_container_width=True)
st.dataframe(filtered, use_container_width=True)Lo que esto demuestra:
cache_dataevita recargar Parquet en cada cambio de widget- Diseño con columnas y configuración de página ancha
- Gráfico de Plotly incrustado con ancho responsivo
- Filtros compuestos con máscaras booleanas de pandas
Profundización
Cómo Funciona
- Streamlit vuelve a ejecutar el script de principio a fin en cada interacción; los widgets son declarativos.
- Dash usa callbacks de Flask + React; mejor para estado complejo y URLs.
- Gradio envuelve una función como bloques de E/S; ideal para
predict(image) -> label. - Los tres se ejecutan detrás de
uvicorn/servidor integrado; pon autenticación de proxy inverso en producción.
Selector de Framework
| Framework | Punto óptimo |
|---|---|
| Streamlit | pandas/gráficos + filtros en horas |
| Dash | Aplicaciones Plotly multipágina, empresariales |
| Gradio | Demostraciones de modelos de Hugging Face |
Notas de Python
# Esqueleto de Dash (app.py separada)
from dash import Dash, html, dcc, Input, Output
import plotly.express as px
app = Dash(__name__)
app.layout = html.Div([dcc.Graph(id="chart"), dcc.Dropdown(id="region")])
# @app.callback(Output("chart", "figure"), Input("region", "value")) ...Trampas
- Sin caché en cargas pesadas - cada tick del deslizador recarga Parquet. Solución:
@st.cache_data/dcc.Storede Dash. - Incrustar secretos en el repositorio - claves API solo en
st.secretso variables de entorno. Solución: nunca cometas credenciales. - Multiselección sin límites - seleccionar todas las regiones replotea fotogramas enormes. Solución: limita la selección o agrega del lado del servidor.
- Ciclos de callback de Dash - Outputs mutuos sin salvaguardas crean bucles. Solución: almacén de estado de única fuente de verdad.
- Gradio para dashboards de BI - herramienta incorrecta - el diseño y los filtros SQL son torpes. Solución: usa Streamlit/Dash en su lugar.
Alternativas
| Alternativa | Usar cuando | No usar cuando |
|---|---|---|
| Panel/HoloViz | Integración con el stack PyData | El equipo quiere la ruta más simple (Streamlit) |
| FastAPI + React | UX y autenticación personalizadas | Necesitas una aplicación en una tarde |
| Superset/Metabase | BI de almacén sobre SQL | Transformaciones pesadas de Python en la UI |
| Observable / Hex | Productos de notebook alojados | Requisito de Python autoalojado |
Preguntas Frecuentes
¿Streamlit o Dash primero?
- Streamlit para prototipos de análisis de equipos pequeños.
- Dash cuando necesites enrutamiento de URL, callbacks y patrones de despliegue gestionados por TI.
¿Cómo despliego Streamlit?
- Docker +
streamlit run app.py --server.port=8501. - Pon OAuth en el proxy inverso (nginx, Cloudflare Access).
¿Cómo comparto Gradio?
import gradio as gr
demo = gr.Interface(fn=predict, inputs="image", outputs="label")
demo.launch()- Usa
share=Truesolo para demostraciones, no para datos de producción.
¿Puedo usar Polars en Streamlit?
- Sí - convierte a pandas para
st.line_charto usa Plotly/Altair directamente.
¿Cómo pruebo dashboards?
- Streamlit AppTest (integrado) para flujos de widgets.
- Dash: pytest con fixtures de
dash.testing.
¿Cómo manejo la autenticación?
- Streamlit-Authenticator o proxy SSO.
- No implementes criptografía tú mismo.
¿Por qué mi aplicación es lenta?
- Perfila la carga de datos y cáchala.
- Agrega antes de graficar - no envíes dataframes de millones de filas al navegador.
¿Puede Dash usar pandas 2.2+?
- Sí - Dash es agnóstico a la biblioteca de DataFrames.
¿Cómo versiono la aplicación + los datos juntos?
- Fija la partición de datos en la configuración de la aplicación (
DATA_DT=2025-01-15). - Registra el SHA de git en el pie de página.
¿Gradio vs Streamlit para demos de LLM?
- Gradio por defecto para E/S de chat/imagen.
- Streamlit cuando los gráficos y los filtros SQL dominan.
Relacionados
- Plotly - gráficos en Dash y Streamlit
- Graficar Datos Grandes - mantén las aplicaciones responsivas
- Mejores Prácticas de Visualización - KPIs honestos en aplicaciones
- Conceptos Básicos de Análisis de Datos - preparación de datos aguas arriba
Versiones de Stack: Esta página fue escrita para Python 3.14.0 (estable 3.14, mantenimiento 3.13), FastAPI 0.115+, Django 5.2, Flask 3.1, Pydantic 2, PyTorch 2.6+, pandas 2.2+, Polars 1.x, ruff 0.9+, y uv 0.6+.