st.dataframe interactivo con st.column_config

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

st.dataframe: tabla interactiva

st.dataframe renderiza un DataFrame de Pandas como una tabla HTML interactiva con ordenación de columnas, redimensionamiento, scroll y búsqueda. Es la forma principal de mostrar datos tabulares en Streamlit, ya que permite al usuario explorar los datos directamente en la interfaz sin necesidad de escribir código adicional.

La tabla generada soporta interacciones avanzadas como ordenar columnas al hacer clic en el encabezado, redimensionar el ancho de columna arrastrando los bordes y navegar por conjuntos de datos grandes con scroll vertical y horizontal:

import streamlit as st
import pandas as pd
import numpy as np

df = pd.DataFrame({
    "producto": ["Laptop Pro", "Monitor 27", "Teclado", "Ratón", "Auriculares"],
    "precio": [1299.99, 349.50, 129.00, 49.90, 89.99],
    "stock": [25, 12, 78, 156, 43],
    "activo": [True, True, True, False, True],
    "web": ["https://ejemplo.com/p1", "https://ejemplo.com/p2", None, None, "https://ejemplo.com/p5"]
})

st.dataframe(
    df,
    use_container_width=True,
    hide_index=True,
    height=250
)

El parámetro hide_index=True oculta la columna de índice de Pandas, que en la mayoría de dashboards es un detalle técnico que no aporta valor al usuario final. El parámetro height fija la altura del widget en píxeles, evitando que tablas con muchas filas expandan la página de forma descontrolada.

flowchart TD
    A[DataFrame Pandas] --> B[st.dataframe argumentos]
    B --> C[use_container_width hide_index height]
    B --> D[column_config dict]
    B --> E[on_select rerun]
    D --> F[NumberColumn formato divisa]
    D --> G[ProgressColumn barra valor]
    D --> H[LinkColumn url]
    D --> I[ImageColumn miniatura]
    D --> J[SelectboxColumn editable]
    E --> K[Selecciona filas múltiple]
    K --> L[selection.rows en session_state]
    L --> M[Lógica downstream basada en selección]
    F --> N[Tabla interactiva ordenable buscable]
    G --> N
    H --> N

st.column_config: personalización de columnas

st.column_config permite especificar el tipo de renderizado de cada columna, transformando datos en bruto en representaciones visuales ricas. Cada tipo de columna renderiza los datos de forma diferente: barras de progreso para porcentajes, checkboxes para booleanos, enlaces clicables para URLs, mini gráficos para listas de valores, entre otros:

import streamlit as st
import pandas as pd

df = pd.DataFrame({
    "nombre": ["Ana García", "Luis Martín", "María López"],
    "email": ["ana@emp.com", "luis@emp.com", "maria@emp.com"],
    "salario": [45000, 62000, 38000],
    "rendimiento": [0.87, 0.92, 0.79],
    "activo": [True, True, False],
    "contratacion": ["2021-03-15", "2019-08-22", "2023-01-10"],
    "web": ["https://linkedin.com", None, "https://github.com"]
})

st.dataframe(
    df,
    use_container_width=True,
    hide_index=True,
    column_config={
        "nombre": st.column_config.TextColumn("Nombre completo", width="medium"),
        "email": st.column_config.TextColumn("Correo electrónico"),
        "salario": st.column_config.NumberColumn(
            "Salario anual",
            format="€%,.0f",
            min_value=0,
            max_value=200000
        ),
        "rendimiento": st.column_config.ProgressColumn(
            "Rendimiento",
            format="%.0f%%",
            min_value=0,
            max_value=1
        ),
        "activo": st.column_config.CheckboxColumn("Activo"),
        "contratacion": st.column_config.DateColumn("Fecha de contratación", format="DD/MM/YYYY"),
        "web": st.column_config.LinkColumn("Perfil online", display_text="Ver perfil")
    }
)

Tipos de column_config disponibles

Streamlit proporciona un amplio catálogo de tipos de columna, cada uno diseñado para un tipo de dato específico. A continuación se listan los principales tipos con su constructor:

import streamlit as st

# Todos los tipos de configuración de columna
ejemplos = {
    "TextColumn": st.column_config.TextColumn("Texto", max_chars=50),
    "NumberColumn": st.column_config.NumberColumn("Número", format="€%.2f"),
    "DateColumn": st.column_config.DateColumn("Fecha", format="YYYY-MM-DD"),
    "DatetimeColumn": st.column_config.DatetimeColumn("Fecha y hora"),
    "TimeColumn": st.column_config.TimeColumn("Hora"),
    "CheckboxColumn": st.column_config.CheckboxColumn("Booleano"),
    "ProgressColumn": st.column_config.ProgressColumn("Progreso", min_value=0, max_value=1),
    "ImageColumn": st.column_config.ImageColumn("Imagen"),
    "LinkColumn": st.column_config.LinkColumn("Enlace"),
    "ListColumn": st.column_config.ListColumn("Lista"),
    "SelectboxColumn": st.column_config.SelectboxColumn("Selección", options=["A", "B", "C"]),
    "BarChartColumn": st.column_config.BarChartColumn("Mini gráfico de barras"),
    "LineChartColumn": st.column_config.LineChartColumn("Mini gráfico de líneas"),
    "AreaChartColumn": st.column_config.AreaChartColumn("Mini gráfico de área"),
}

Los tipos BarChartColumn, LineChartColumn y AreaChartColumn son especialmente interesantes porque permiten incrustar mini gráficos (sparklines) dentro de las celdas de la tabla, mostrando tendencias sin ocupar espacio adicional en el layout.

Selección de filas con on_select

El parámetro on_select convierte el dataframe en un componente interactivo que permite al usuario seleccionar filas. Al seleccionar, se devuelve un objeto con los índices de las filas marcadas, lo que permite construir flujos donde la tabla actúa como filtro para otros componentes de la aplicación:

import streamlit as st
import pandas as pd

df = pd.DataFrame({
    "nombre": ["Ana García", "Luis Martín", "María López", "Carlos Ruiz"],
    "departamento": ["Ventas", "IT", "RRHH", "Marketing"],
    "salario": [45000, 62000, 38000, 51000]
})

evento = st.dataframe(
    df,
    use_container_width=True,
    hide_index=True,
    on_select="rerun",      # "ignore" (por defecto) o "rerun"
    selection_mode="multi-row"  # "single-row", "multi-row", "single-column", "multi-column"
)

if evento.selection.rows:
    filas_sel = df.iloc[evento.selection.rows]
    st.write(f"**{len(filas_sel)} fila(s) seleccionada(s):**")
    st.dataframe(filas_sel, hide_index=True)
    st.metric("Salario medio de la selección", f"€ {filas_sel['salario'].mean():,.0f}")

Resaltado de celdas con Pandas Styler

import streamlit as st
import pandas as pd
import numpy as np

df = pd.DataFrame(np.random.randn(5, 4), columns=["A", "B", "C", "D"])

def color_negativo(val):
    color = "#FFCCCC" if val < 0 else "#CCFFCC"
    return f"background-color: {color}"

styled = df.style.applymap(color_negativo).format("{:.3f}")
st.dataframe(styled, use_container_width=True)

Columnas ocultas y orden de columnas

import streamlit as st
import pandas as pd

df = pd.DataFrame({
    "id": range(1, 6),
    "nombre": ["Ana", "Luis", "María", "Carlos", "Elena"],
    "interno_id": ["INT001", "INT002", "INT003", "INT004", "INT005"],  # No mostrar
    "ventas": [45000, 62000, 38000, 51000, 29000]
})

st.dataframe(
    df,
    use_container_width=True,
    hide_index=True,
    column_order=["nombre", "ventas"],  # Solo mostrar estas columnas en este orden
    column_config={
        "nombre": st.column_config.TextColumn("Vendedor"),
        "ventas": st.column_config.NumberColumn("Ventas anuales", format="€%,.0f")
    }
)

Contexto: el componente estrella para datos tabulares

st.dataframe es, probablemente, el componente más usado en aplicaciones Streamlit orientadas a ciencia de datos. A diferencia de st.table, que renderiza una tabla HTML estática, st.dataframe genera una tabla interactiva con virtualización de filas: solo se pintan las filas visibles en pantalla, lo que permite mostrar datasets de cientos de miles de filas sin bloquear el navegador.

Por debajo, el componente usa glide-data-grid, la misma biblioteca que impulsa notebooks como Observable y herramientas de BI modernas. Esto le da soporte nativo para ordenación por columna al hacer clic en el encabezado, búsqueda rápida con Ctrl+F, redimensionado de columnas arrastrando los separadores, y selección de celdas con arrastre del ratón. Todas estas interacciones se obtienen gratis sin añadir una sola línea de código.

Explicación línea por línea del ejemplo con column_config

  1. Se crea un DataFrame con columnas de distintos tipos: texto, email, número, progreso, booleano, fecha y URL.
  2. column_config mapea cada columna a un tipo específico de renderizado.
  3. NumberColumn con format="€%,.0f" muestra el salario con separador de miles, símbolo de euro y sin decimales.
  4. ProgressColumn con format="%.0f%%" dibuja una barra de progreso dentro de la celda y muestra el porcentaje encima.
  5. CheckboxColumn renderiza True/False como una casilla real (visualmente, aunque no editable en st.dataframe).
  6. DateColumn con format="DD/MM/YYYY" convierte el string ISO a formato europeo legible.
  7. LinkColumn con display_text="Ver perfil" muestra texto personalizado en lugar de la URL cruda, haciéndola clicable.

Tabla completa de parámetros de st.dataframe

| Parámetro | Descripción | |-----------|-------------| | data | DataFrame, Series, Styler, numpy array o dict | | width | Ancho en píxeles | | height | Alto en píxeles | | use_container_width | Ajusta al ancho del contenedor padre | | hide_index | Oculta la columna de índice | | column_order | Lista con el orden (y filtrado) de columnas | | column_config | Diccionario con la configuración por columna | | key | Identificador para sincronización con session_state | | on_select | "ignore" o "rerun" para activar selección | | selection_mode | "single-row", "multi-row", "single-column", "multi-column" |

Errores comunes

Datos con tipos incoherentes. Si una columna numérica contiene strings accidentales (por ejemplo, "N/A"), pandas la convierte a object y NumberColumn no puede aplicar el formato. Limpia con pd.to_numeric(col, errors="coerce") antes de pasarla al dataframe.

Ordenación por defecto que confunde. Los usuarios esperan que las tablas arranquen ordenadas por la primera columna, pero st.dataframe respeta el orden del DataFrame. Si necesitas un orden específico, aplica df.sort_values(...) antes de pasarlo al componente.

Selección que no rerun. Si usas on_select="rerun" pero accedes a evento.selection.rows antes del widget, obtendrás un error. La variable devuelta por st.dataframe(...) debe asignarse primero y usarse después.

Styler con muchas reglas. Los estilos aplicados con Pandas Styler se convierten a CSS inline, lo que puede ralentizar el renderizado en tablas muy grandes. Limita los estilos a columnas críticas y usa column_config siempre que sea posible.

Formatos numéricos con porcentajes. Para mostrar 0.87 como 87 % en NumberColumn, usa format="%.0f%%" y multiplica el valor por 100. Para ProgressColumn, los valores deben estar en el rango min_value/max_value especificado.

Mejores prácticas

  • Usa siempre hide_index=True salvo que el índice aporte información al usuario (series temporales con fechas).
  • Limita la altura con height para evitar que tablas largas expandan la página y obliguen al usuario a hacer scroll.
  • Para datasets de más de 10 000 filas, considera paginar o aplicar filtros previos: aunque el componente virtualice, los datos se envían íntegros al navegador.
  • Combina ProgressColumn con una columna de texto para mostrar valores absolutos junto al indicador visual.
  • Usa column_order para reordenar y ocultar columnas sin modificar el DataFrame original, manteniendo la lógica del dashboard separada de la estructura de datos.
  • Para exportar los datos mostrados, añade un st.download_button que genere un CSV del DataFrame filtrado.
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

Renderizar DataFrames interactivos con st.dataframe y sus opciones de visualización. Personalizar el tipo y formato de cada columna con st.column_config. Habilitar la selección de filas con on_select para interactividad avanzada. Ocultar columnas, fijar el índice y controlar el ancho con parámetros de st.dataframe. Resaltar valores con estilos de Pandas antes de pasarlos a st.dataframe.