De Scripts a Dashboards Interactivos: Visualización de Datos con Python y Streamlit
Contexto del Problema
Como desarrollador de Python, especialmente si trabajas con datos o IA, a menudo te encuentras con un desafío común: has realizado un análisis increíble, entrenado un modelo prometedor o procesado un conjunto de datos complejo en un script o un Jupyter Notebook. Los resultados son claros para ti, pero ¿cómo los compartes de manera efectiva con tu equipo, tus managers o clientes que no son técnicos? Enviar gráficos estáticos por correo electrónico o compartir archivos CSV no suele ser suficiente. Lo que necesitas es una forma de presentar tus hallaz-gos de una manera interactiva y accesible, permitiendo que otros exploren los datos por sí mismos. Aquí es donde la creación de una aplicación web se vuelve esencial, pero el desarrollo frontend tradicional (HTML, CSS, JavaScript) puede ser una barrera importante. Necesitas una herramienta que te permita construir una interfaz de usuario directamente desde Python, de forma rápida y sencilla.
Conceptos Clave
Aquí es donde entra en juego Streamlit. Streamlit es una biblioteca de código abierto que transforma scripts de datos en aplicaciones web interactivas en cuestión de minutos. Su filosofía es simple: si sabes escribir scripts de Python, puedes crear una app con Streamlit.
- ¿Qué es Streamlit? Es un framework de Python diseñado para que científicos de datos e ingenieros de machine learning creen y compartan aplicaciones web personalizadas sin necesidad de experiencia en desarrollo frontend.
- El Paradigma "Script-like": La belleza de Streamlit radica en su simplicidad. Escribes tu código de Python de arriba hacia abajo, como lo harías en un script normal. Streamlit se encarga de renderizar los elementos en una interfaz web.
- Modelo de Ejecución: Cada vez que un usuario interactúa con un widget en la aplicación (como mover un slider o hacer clic en un botón), Streamlit re-ejecuta todo el script de arriba a abajo. Esto mantiene el modelo de programación simple, pero también introduce la necesidad de optimizar el rendimiento, algo que abordaremos más adelante.
- Componentes (Widgets): Streamlit proporciona una amplia gama de funciones que actúan como widgets interactivos. Comandos como
st.title(),st.write(),st.slider(),st.button(), yst.selectbox()son los bloques de construcción fundamentales de cualquier aplicación Streamlit.
Implementación Paso a Paso
Vamos a empezar construyendo nuestra primera aplicación. El proceso es increíblemente directo.
1. Instalación
Primero, asegúrate de tener Python instalado. Luego, abre tu terminal o línea de comandos e instala Streamlit y Pandas (que usaremos para manejar datos).
pip install streamlit pandas
2. Tu Primera App: "Hola, Mundo"
Crea un nuevo archivo de Python llamado app.py. Este será el script de tu aplicación. Añade el siguiente código:
import streamlit as st
st.title("Mi Primera App con Streamlit")
st.write("¡Hola, mundo!")
Este código importa la biblioteca de Streamlit (convencionalmente con el alias st), establece un título para la página y escribe un texto simple.
3. Ejecución de la Aplicación
Para ejecutar tu aplicación, vuelve a la terminal, navega al directorio donde guardaste app.py y ejecuta el siguiente comando:
streamlit run app.py
Streamlit iniciará un servidor web local y abrirá automáticamente una nueva pestaña en tu navegador apuntando a tu aplicación. Deberías ver el título y el texto que definiste.
4. Añadiendo Interactividad
Ahora, hagamos que la app sea interactiva. Modifica app.py para incluir un slider. El valor del slider se almacenará en una variable que podremos usar en nuestro script.
import streamlit as st
st.title("App Interactiva con Slider")
# Crear un slider que va de 0 a 100, con un valor inicial de 25
x = st.slider("Selecciona un valor", 0, 100, 25)
st.write(f"El valor seleccionado es: {x}")
st.write(f"El cuadrado del valor es: {x * x}")
Guarda el archivo. Streamlit detectará el cambio y te ofrecerá re-ejecutar la aplicación en el navegador. Ahora, al mover el slider, verás cómo el texto se actualiza en tiempo real.
Mini Proyecto / Aplicación Sencilla
Construyamos algo más práctico: un dashboard para explorar el famoso conjunto de datos de pingüinos de Palmer. Este proyecto integrará la carga de datos, el filtrado interactivo y la visualización.
Para este proyecto, también necesitaremos plotly-express para gráficos interactivos. Instálalo con pip install plotly-express.
Código del Mini Proyecto (penguin_dashboard.py):
import streamlit as st
import pandas as pd
import plotly.express as px
# --- CONFIGURACIÓN DE LA PÁGINA ---
st.set_page_config(
page_title="Dashboard de Pingüinos",
page_icon="🐧",
layout="wide"
)
# --- CACHING DE DATOS ---
@st.cache_data # Decorador para cachear la carga de datos
def load_data():
# Usamos un enlace directo al CSV en GitHub para que sea reproducible
url = "https://raw.githubusercontent.com/allisonhorst/palmerpenguins/main/inst/extdata/penguins.csv"
df = pd.read_csv(url)
# Limpiar datos eliminando filas con valores nulos
df.dropna(inplace=True)
return df
df_penguins = load_data()
# --- TÍTULO PRINCIPAL ---
st.title("🐧 Dashboard Interactivo de Pingüinos de Palmer")
st.markdown("Explora la relación entre diferentes medidas de los pingüinos.")
# --- BARRA LATERAL (SIDEBAR) PARA FILTROS ---
st.sidebar.header("Opciones de Filtrado")
# Filtro por especie
species_list = ["Todas"] + sorted(df_penguins["species"].unique().tolist())
species_selected = st.sidebar.selectbox("Selecciona una Especie", species_list)
# Filtro por isla
island_list = ["Todas"] + sorted(df_penguins["island"].unique().tolist())
island_selected = st.sidebar.selectbox("Selecciona una Isla", island_list)
# Filtro por rango de masa corporal
min_mass, max_mass = int(df_penguins["body_mass_g"].min()), int(df_penguins["body_mass_g"].max())
mass_slider = st.sidebar.slider(
"Masa Corporal (g)",
min_value=min_mass,
max_value=max_mass,
value=(min_mass, max_mass) # Valor inicial es el rango completo
)
# --- APLICAR FILTROS AL DATAFRAME ---
df_filtered = df_penguins.copy()
if species_selected != "Todas":
df_filtered = df_filtered[df_filtered["species"] == species_selected]
if island_selected != "Todas":
df_filtered = df_filtered[df_filtered["island"] == island_selected]
df_filtered = df_filtered[
(df_filtered["body_mass_g"] >= mass_slider[0]) &
(df_filtered["body_mass_g"] <= mass_slider[1])
]
# --- VISUALIZACIÓN PRINCIPAL ---
# Métricas clave
col1, col2, col3 = st.columns(3)
col1.metric("Total Pingüinos Filtrados", f"{df_filtered.shape[0]}")
col2.metric("Masa Corporal Promedio (g)", f"{df_filtered['body_mass_g'].mean():.2f}")
col3.metric("Longitud Promedio del Pico (mm)", f"{df_filtered['bill_length_mm'].mean():.2f}")
st.markdown("---")
# Gráfico de dispersión interactivo
st.subheader("Relación entre Longitud y Profundidad del Pico")
fig = px.scatter(
df_filtered,
x="bill_length_mm",
y="bill_depth_mm",
color="species",
hover_name="species",
hover_data=["island", "sex", "body_mass_g"],
title="Longitud vs. Profundidad del Pico por Especie"
)
fig.update_layout(legend_title_text='Especie')
st.plotly_chart(fig, use_container_width=True)
# Mostrar tabla de datos filtrados (opcional)
if st.checkbox("Mostrar datos filtrados en una tabla"):
st.dataframe(df_filtered, use_container_width=True)
Para ejecutar este mini proyecto:
- Guarda el código como
penguin_dashboard.py. - Asegúrate de tener las dependencias:
pip install streamlit pandas plotly-express. - Ejecuta desde tu terminal:
streamlit run penguin_dashboard.py.
Ahora tendrás un dashboard funcional donde puedes filtrar los datos por especie, isla y masa corporal, y ver cómo el gráfico y las métricas se actualizan instantáneamente.
Errores Comunes y Depuración
Aunque Streamlit es fácil de usar, hay algunos conceptos clave que, si se malinterpretan, pueden llevar a problemas de rendimiento o comportamiento inesperado.
- Problema: La app es lenta en cada interacción.
Causa: El modelo de re-ejecución de Streamlit significa que cualquier operación costosa (como cargar un archivo grande, consultar una base de datos o entrenar un modelo) se repetirá con cada clic.
Solución: Caching. Streamlit ofrece decoradores de caché como@st.cache_datay@st.cache_resource. Al decorar una función con@st.cache_data, Streamlit solo la ejecutará la primera vez que se llame con un conjunto específico de argumentos. En las siguientes ejecuciones, si los argumentos no han cambiado, devolverá el resultado almacenado en caché, haciendo la app mucho más rápida. Lo usamos en nuestro mini proyecto para la funciónload_data(). - Problema: El estado se pierde entre interacciones.
Causa: Las variables locales se reinician en cada re-ejecución. Si necesitas que una variable persista (por ejemplo, un contador de clics o los resultados de un paso anterior en un formulario), no sobrevivirá a la siguiente interacción.
Solución: Estado de Sesión (Session State). Streamlit proporciona un objeto similar a un diccionario llamadost.session_state. Puedes usarlo para almacenar información que debe persistir a lo largo de la sesión de un usuario. Por ejemplo:st.session_state.mi_variable = 'valor'. - Problema: Despliegue y dependencias.
Causa: Para compartir tu app, necesitas un lugar donde alojarla. El Streamlit Community Cloud es una opción gratuita y fantástica, pero requiere que tu proyecto esté en un repositorio público de GitHub y que tengas un archivorequirements.txt.
Solución: Crea un archivorequirements.txten la raíz de tu proyecto que liste todas las dependencias (ej:streamlit,pandas,plotly-express). Sube tu código y este archivo a un repositorio de GitHub. Luego, desde el Streamlit Community Cloud, puedes apuntar a tu repositorio para desplegar la aplicación con unos pocos clics.
Aprendizaje Futuro / Próximos Pasos
Una vez que domines los conceptos básicos, el ecosistema de Streamlit tiene mucho más que ofrecer para crear aplicaciones aún más potentes:
- Widgets Avanzados: Explora
st.file_uploaderpara permitir a los usuarios subir sus propios datos,st.formpara agrupar varios widgets y enviarlos con un solo botón, yst.camera_inputpara aplicaciones de visión por computadora. - Layouts y Contenedores: Domina
st.columns,st.tabsyst.expanderpara organizar tu aplicación de manera más limpia y profesional. - Aplicaciones Multi-Página: Para proyectos más complejos, puedes estructurar tu aplicación en múltiples páginas. Simplemente crea una carpeta llamada
pagesen tu directorio raíz y añade un script de Python para cada página que desees. - Componentes Personalizados: Si necesitas una funcionalidad que no está disponible de forma nativa, puedes explorar la galería de componentes creados por la comunidad o incluso construir los tuyos propios utilizando HTML/JavaScript.
- Conexión a Bases de Datos: Utiliza
st.connectionpara conectarte de forma segura y eficiente a bases de datos SQL, APIs y más, aprovechando el cacheo integrado.
Streamlit es una herramienta increíblemente poderosa que reduce drásticamente la barrera entre el análisis de datos y la creación de herramientas interactivas. Al integrarlo en tu flujo de trabajo, no solo mejorarás la forma en que presentas tus resultados, sino que también empoderarás a otros para que exploren y obtengan valor de tus datos.