st.table, st.metric con deltas y st.json

Básico
Streamlit
Streamlit
Actualizado: 26/04/2026

st.table: tabla estática

st.table muestra un DataFrame como una tabla HTML estática, sin interactividad ni scroll. A diferencia de st.dataframe, renderiza todas las filas visibles de una vez y se adapta automáticamente al ancho de su contenedor, ajustando la altura al número de filas sin mostrar barras de desplazamiento.

Esta característica la hace ideal para tablas de resumen cortas donde el usuario necesita ver todos los datos de un vistazo, como comparativas de modelos, configuraciones de parámetros o resultados de benchmarks:

import streamlit as st
import pandas as pd

df = pd.DataFrame({
    "Algoritmo": ["Random Forest", "XGBoost", "SVM", "Regresión logística"],
    "Accuracy": [0.9431, 0.9512, 0.9218, 0.8934],
    "AUC-ROC": [0.9821, 0.9863, 0.9645, 0.9234],
    "Tiempo (s)": [12.3, 8.7, 45.2, 1.1]
})

st.table(df)
flowchart TD
    A[Salida de datos en página] --> B{"Tipo?"}
    B -->|Tabla compacta sin scroll| C[st.table estática]
    B -->|Tabla interactiva ordenable| D[st.dataframe]
    B -->|KPI con cambio| E[st.metric value delta]
    B -->|Estructura JSON árbol| F[st.json expandible]
    C --> G[Renderiza todas las filas a la vez]
    D --> H[Scroll y orden]
    E --> I[Color verde positivo o rojo negativo]
    E --> J[Icono y label]
    F --> K[Plegado niveles del objeto]
    G --> L[Reportes ejecutivos]
    H --> M[Exploración datos masivos]
    I --> N[Dashboard KPI bancario]
    K --> O[Debug API responses]

st.table vs st.dataframe:

| Característica | st.table | st.dataframe | |---|---|---| | Interactividad | No | Sí (ordenar, redimensionar) | | Scroll | No (muestra todo) | Sí (altura fija) | | Edición | No | No (usa st.data_editor) | | Ideal para | Comparativas cortas, resúmenes | Conjuntos de datos medianos/grandes |

st.metric: métricas con indicador de cambio

st.metric es uno de los componentes más utilizados en dashboards ejecutivos. Muestra un valor destacado con tipografía grande, acompañado de una etiqueta descriptiva y, opcionalmente, un indicador de cambio (delta) que muestra la diferencia respecto a un período anterior. El delta incluye un color automático (verde para positivo, rojo para negativo) y una flecha direccional:

import streamlit as st

# Metric básico
st.metric("Ingresos del mes", "€ 45.230")

# Con delta (indicador de cambio)
st.metric("Ingresos del mes", "€ 45.230", delta="€ +3.210 vs mes anterior")

# Delta negativo
st.metric("Tasa de abandono", "2,3%", delta="-0,5%")

# Delta con color invertido (rojo cuando sube es malo)
st.metric("Costes operativos", "€ 28.100", delta="€ +1.500", delta_color="inverse")

# Delta desactivado (sin color)
st.metric("Usuarios registrados", "12.450", delta="+67", delta_color="off")

El color del delta se controla con delta_color:

  • "normal" (predeterminado): verde si positivo, rojo si negativo.
  • "inverse": rojo si positivo (útil para costes), verde si negativo.
  • "off": gris, sin indicación de bueno/malo.

El parámetro delta_color es especialmente importante en métricas operativas donde la semántica del "positivo" puede invertirse. Por ejemplo, un aumento en los costes se considera negativo, por lo que se usa delta_color="inverse" para que un delta positivo se muestre en rojo.

Panel de KPIs con st.metric

El patrón más habitual con st.metric es crear un panel de KPIs (Key Performance Indicators) distribuyendo las métricas en columnas. Este diseño es estándar en dashboards ejecutivos y permite captar el estado general de un vistazo:

import streamlit as st

st.title("Dashboard ejecutivo — Marzo 2026")

# Primera fila: métricas principales
col1, col2, col3, col4 = st.columns(4)
col1.metric("Ingresos", "€ 124.500", "+15,3%")
col2.metric("Clientes activos", "842", "+67")
col3.metric("Ticket medio", "€ 148", "+€ 12")
col4.metric("NPS", "72", "+5")

st.divider()

# Segunda fila: métricas operativas
col5, col6, col7, col8 = st.columns(4)
col5.metric("Costes totales", "€ 78.200", "€ +4.100", delta_color="inverse")
col6.metric("Margen bruto", "37,3%", "+2,1pp")
col7.metric("Tiempo respuesta", "45 ms", "-8 ms")
col8.metric("Tasa error", "0,32%", "-0,05%", delta_color="inverse")

st.json: datos estructurados JSON

st.json muestra datos Python (diccionarios, listas, objetos JSON) de forma estructurada y expandible en el navegador. Los datos se renderizan con resaltado de sintaxis, indentación automática y la posibilidad de expandir o colapsar secciones, lo que facilita la inspección de estructuras de datos complejas como respuestas de APIs, configuraciones de modelos o metadatos de datasets:

import streamlit as st

# Diccionario Python simple
st.json({
    "modelo": "RandomForestClassifier",
    "version": "1.2.0",
    "accuracy": 0.9431,
    "features": ["edad", "salario", "departamento", "antigüedad"],
    "hiperparametros": {
        "n_estimators": 200,
        "max_depth": 10,
        "min_samples_split": 5
    }
})

# JSON expandido a cierta profundidad
config_api = {
    "endpoint": "https://api.empresa.com/v2",
    "autenticacion": {
        "tipo": "Bearer",
        "expiracion": "3600s"
    },
    "limites": {
        "requests_por_minuto": 100,
        "tamaño_respuesta_max": "10MB"
    }
}

st.json(config_api, expanded=2)  # Expandido hasta profundidad 2

# collapsed=True para solo mostrar el primer nivel
st.json({"datos": [1, 2, 3, 4, 5], "metadatos": {"n": 5, "tipo": "entero"}}, expanded=False)

Combinación en un panel de resultados de API

import streamlit as st
import pandas as pd

st.title("Resultados de llamada a API")

# Simular respuesta de API
respuesta_api = {
    "status": "success",
    "codigo": 200,
    "datos": {
        "total_registros": 1250,
        "pagina": 1,
        "pagina_size": 50,
        "filtros_aplicados": ["region=ES", "año=2026"]
    },
    "tiempo_respuesta_ms": 234
}

col1, col2, col3 = st.columns(3)
col1.metric("Registros totales", f"{respuesta_api['datos']['total_registros']:,}")
col2.metric("Código HTTP", respuesta_api["codigo"])
col3.metric("Latencia", f"{respuesta_api['tiempo_respuesta_ms']} ms")

with st.expander("Respuesta completa de la API"):
    st.json(respuesta_api)

st.subheader("Muestra de datos")
df_muestra = pd.DataFrame({
    "ID": range(1, 6),
    "Producto": ["A", "B", "C", "D", "E"],
    "Precio": [100, 200, 150, 300, 250]
})
st.table(df_muestra)
Alan Sastre - Autor del tutorial

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

Usar st.table para tablas estáticas no interactivas en Streamlit. Crear métricas destacadas con indicadores de cambio positivo/negativo con st.metric. Controlar el color del delta con delta_color en st.metric. Visualizar datos estructurados JSON con st.json de forma expandible. Saber cuándo usar st.table vs st.dataframe según el caso de uso.