st.set_page_config: configuración global de la página
st.set_page_config debe ser la primera llamada de Streamlit en el script. Configura el título de la pestaña del navegador, el ícono, el layout y el estado inicial del sidebar:
import streamlit as st
st.set_page_config(
page_title="Mi Dashboard",
page_icon="📊", # Emoji o URL de imagen
layout="wide", # "centered" (por defecto) o "wide"
initial_sidebar_state="expanded", # "auto", "expanded", "collapsed"
menu_items={
"Get Help": "https://docs.streamlit.io",
"Report a bug": "https://github.com/streamlit/streamlit/issues",
"About": "## Mi Dashboard\nVersión 1.0.0"
}
)
Si se llama st.set_page_config después de otras llamadas a Streamlit, se produce un error. Colocarlo siempre al principio del script.
Arquitectura de una app Streamlit
Cada app combina cuatro piezas que conviene tener claras desde el principio: el script Python, los widgets (que leen y escriben valores en el front-end), st.session_state para persistir datos entre reruns y la cache para evitar recomputaciones. El servidor Streamlit orquesta estas piezas en cada interacción:
flowchart TB
Browser[Navegador del usuario] -->|WebSocket| Server[Streamlit Server]
Server -->|Ejecuta script| Script[app.py]
Script --> Widgets["Widgets: button, selectbox, slider"]
Script --> State["(st.session_state)"]
Script --> Cache["("@st.cache_data / @st.cache_resource")"]
Widgets -->|Valor nuevo| Server
State -->|Persiste entre reruns| Script
Cache -->|Salta computo costoso| Script
Script -->|Delta UI| Browser
st.write: la función más versátil
st.write es la navaja suiza de Streamlit. Acepta prácticamente cualquier tipo de dato Python y lo renderiza de la forma más adecuada:
import streamlit as st
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
# Texto plano y Markdown
st.write("Hola, este es texto plano.")
st.write("**Negrita**, *cursiva* y `código inline` con Markdown.")
# Números y listas
st.write(42)
st.write([1, 2, 3, 4, 5])
st.write({"clave": "valor", "número": 100})
# DataFrames de Pandas
df = pd.DataFrame({"A": [1, 2, 3], "B": [4, 5, 6]})
st.write(df)
# Figuras de Matplotlib
fig, ax = plt.subplots()
ax.plot([1, 2, 3], [4, 5, 6])
st.write(fig)
# Magic: st.write se puede omitir en ciertas versiones
# simplemente escribiendo la variable al final de una línea
df # Esto también muestra el DataFrame (Streamlit Magic)
Primera aplicación completa
Construyamos una aplicación de análisis de datos paso a paso:
import streamlit as st
import pandas as pd
import numpy as np
st.set_page_config(
page_title="Análisis de ventas",
page_icon="📈",
layout="wide"
)
st.title("Dashboard de Análisis de Ventas")
st.markdown("Esta aplicación muestra el análisis de ventas con datos de ejemplo.")
# Generar datos de ejemplo
@st.cache_data
def generar_datos():
np.random.seed(42)
meses = ["Ene", "Feb", "Mar", "Abr", "May", "Jun",
"Jul", "Ago", "Sep", "Oct", "Nov", "Dic"]
return pd.DataFrame({
"mes": meses,
"ventas": np.random.randint(8000, 20000, 12),
"costes": np.random.randint(5000, 12000, 12),
"clientes": np.random.randint(50, 200, 12)
})
df = generar_datos()
# Métricas destacadas
col1, col2, col3 = st.columns(3)
col1.metric("Ventas totales", f"€ {df['ventas'].sum():,.0f}")
col2.metric("Coste total", f"€ {df['costes'].sum():,.0f}")
col3.metric("Media clientes/mes", f"{df['clientes'].mean():.0f}")
st.divider()
# Gráfico interactivo
st.subheader("Evolución mensual de ventas y costes")
st.line_chart(df.set_index("mes")[["ventas", "costes"]])
# Tabla de datos
st.subheader("Datos detallados")
st.dataframe(df, use_container_width=True, hide_index=True)
El flujo top-down en acción
El modelo de re-ejecución de Streamlit se hace evidente con widgets:
import streamlit as st
import pandas as pd
import numpy as np
st.title("Generador de datos configurables")
# Cada vez que el usuario cambia estos widgets, todo el script se re-ejecuta
n_filas = st.slider("Número de filas", 10, 1000, 100)
semilla = st.number_input("Semilla aleatoria", value=42, step=1)
incluir_negativo = st.checkbox("Incluir valores negativos", value=False)
# Este código se ejecuta con los valores actuales de los widgets
np.random.seed(int(semilla))
if incluir_negativo:
datos = np.random.randn(n_filas) # Normal estándar (-∞ a +∞)
else:
datos = np.abs(np.random.randn(n_filas)) # Solo positivos
df = pd.DataFrame({"valor": datos})
col1, col2 = st.columns(2)
with col1:
st.write(f"Filas generadas: **{len(df)}**")
st.write(f"Mínimo: **{df['valor'].min():.4f}**")
st.write(f"Máximo: **{df['valor'].max():.4f}**")
st.write(f"Media: **{df['valor'].mean():.4f}**")
with col2:
st.line_chart(df)
Cuando el usuario mueve el slider de n_filas, Streamlit:
- Re-ejecuta el script completo de arriba a abajo.
n_filastoma el nuevo valor del slider.datosydfse recalculan con el nuevon_filas.- Las métricas y el gráfico se actualizan en pantalla.
Este comportamiento es completamente automático: no hay que gestionar eventos ni callbacks.
Diferencia entre st.write y funciones específicas
st.write es conveniente para prototipos, pero para código de producción conviene usar las funciones específicas porque son más explícitas y tienen más parámetros:
# st.write genérico
st.write("## Mi título")
st.write(df)
# Funciones específicas con más control
st.header("Mi título") # Solo texto, no DataFrames
st.dataframe(df, use_container_width=True) # Tabla con opciones avanzadas
st.line_chart(df) # Solo gráficos
La regla práctica: usa st.write para exploración rápida y funciones específicas para código que va a producción.
Añadir interactividad básica
Una aplicación completamente estática no aprovecha Streamlit. Añadir un widget transforma el dashboard en una herramienta interactiva:
import streamlit as st
import pandas as pd
import numpy as np
st.title("Filtro interactivo de datos")
# Widget de filtro
umbral = st.slider("Mostrar valores mayores que", 0, 100, 50)
# Los datos se filtran en tiempo real
datos = pd.DataFrame({"valor": np.random.randint(0, 100, 200)})
filtrado = datos[datos["valor"] > umbral]
st.write(f"Mostrando {len(filtrado)} de {len(datos)} registros (umbral: {umbral})")
st.bar_chart(filtrado["valor"].value_counts().sort_index())
Con estas bases, ya puedes construir aplicaciones Streamlit funcionales. Los siguientes módulos profundizan en cada tipo de elemento: texto enriquecido, widgets avanzados, gráficos, layouts y gestión del estado.
Alan Sastre
Ingeniero de Software y formador, CEO en CertiDevs
Ingeniero de software especializado en Full Stack y en Inteligencia Artificial. Como CEO de CertiDevs, Streamlit es una de sus áreas de expertise. Con más de 15 años programando, 6K seguidores en LinkedIn y experiencia como formador, Alan se dedica a crear contenido educativo de calidad para desarrolladores de todos los niveles.
Más tutoriales de Streamlit
Explora más contenido relacionado con Streamlit y continúa aprendiendo con nuestros tutoriales gratuitos.
Aprendizajes de esta lección
Crear una aplicación Streamlit funcional desde cero con st.write. Configurar la página con st.set_page_config (título, icono, layout). Comprender el modelo de re-ejecución top-down con ejemplos prácticos. Usar st.write para mostrar distintos tipos de datos (texto, DataFrames, gráficos). Combinar widgets con lógica Python para crear interactividad real.