st.altair_chart, st.vega_lite_chart y st.graphviz_chart

Intermedio
Streamlit
Streamlit
Actualizado: 26/04/2026

Altair: gramática de gráficos declarativa

Altair es una biblioteca de visualización basada en la gramática de gráficos de Vega-Lite. Su filosofía es declarativa: en lugar de especificar cómo dibujar el gráfico paso a paso (como en Matplotlib), se describe qué datos mostrar y qué codificaciones visuales aplicar (ejes, colores, formas, tamaños). Altair genera internamente una especificación JSON que el navegador renderiza como un gráfico interactivo.

La principal ventaja de Altair frente a Plotly es su sistema de selecciones interactivas vinculadas: se pueden conectar múltiples gráficos para que la selección en uno filtre automáticamente los demás, sin necesidad de callbacks manuales:

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

np.random.seed(42)
df = pd.DataFrame({
    "x": range(50),
    "y": np.cumsum(np.random.randn(50)) + 10,
    "categoria": np.random.choice(["A", "B", "C"], 50)
})

# Gráfico de dispersión básico
chart = alt.Chart(df).mark_circle(size=60).encode(
    x=alt.X("x:Q", title="Índice"),
    y=alt.Y("y:Q", title="Valor"),
    color=alt.Color("categoria:N", title="Categoría"),
    tooltip=["x", "y", "categoria"]
).properties(
    title="Gráfico de dispersión con Altair",
    width="container",
    height=350
)

st.altair_chart(chart, use_container_width=True)

En la codificación de Altair, los sufijos de tipo (:Q para cuantitativo, :N para nominal, :O para ordinal, :T para temporal) indican cómo debe interpretar Altair cada campo del DataFrame, determinando automáticamente la escala y el eje adecuados.

flowchart TD
    A[Visualización declarativa] --> B{"Caso?"}
    B -->|Datos tabulares| C[Altair gramatica encode mark]
    B -->|Especificación JSON| D[st.vega_lite_chart spec]
    B -->|Grafo de nodos| E[st.graphviz_chart DOT]
    C --> F[mark_circle mark_bar mark_line]
    F --> G[encode x y color tooltip]
    G --> H[selection_point selection_interval]
    H --> I[Vincular gráficos con add_params]
    D --> J[Pasa dict directamente al renderer]
    E --> K[Lenguaje DOT con flecha A B]
    K --> L[Visualiza dependencias o flujo]
    I --> M[Dashboard interactivo declarativo]
    J --> M
    L --> M

Tipos de marcas (marks) en Altair

Las marcas definen la representación visual de cada dato. Altair soporta mark_point, mark_circle, mark_bar, mark_line, mark_area, mark_rect, mark_tick y mark_text, entre otras. Un patrón habitual es combinar múltiples marcas con el operador + para superponer capas:

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

df = pd.DataFrame({
    "mes": range(1, 13),
    "ventas": np.random.randint(5000, 15000, 12),
    "objetivo": [10000] * 12
})

# Gráfico de barras con línea de objetivo
barras = alt.Chart(df).mark_bar(color="#FF4B4B", opacity=0.8).encode(
    x=alt.X("mes:O", title="Mes"),
    y=alt.Y("ventas:Q", title="Ventas (€)"),
    tooltip=["mes", "ventas"]
)

objetivo = alt.Chart(df).mark_line(
    color="#1F77B4", strokeDash=[5, 5], strokeWidth=2
).encode(
    x="mes:O",
    y="objetivo:Q"
)

# Combinar gráficos con el operador +
st.altair_chart(barras + objetivo, use_container_width=True)

Selecciones interactivas

Una de las características más diferenciadoras de Altair es la vinculación interactiva entre gráficos. Las selecciones permiten al usuario arrastrar un rectángulo, hacer clic en un punto o seleccionar valores de un eje, y que esa selección se propague automáticamente a otros gráficos vinculados:

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

np.random.seed(42)
df = pd.DataFrame({
    "x": np.random.randn(200),
    "y": np.random.randn(200),
    "categoria": np.random.choice(["Tipo A", "Tipo B", "Tipo C"], 200),
    "valor": np.random.uniform(10, 100, 200)
})

# Selector de intervalo interactivo
seleccion = alt.selection_interval()

# Gráfico de dispersión con selección
scatter = alt.Chart(df).mark_circle().encode(
    x=alt.X("x:Q"),
    y=alt.Y("y:Q"),
    color=alt.condition(
        seleccion,
        alt.Color("categoria:N"),
        alt.value("lightgray")
    ),
    size=alt.Size("valor:Q"),
    tooltip=["x", "y", "categoria", "valor"]
).add_params(seleccion).properties(
    title="Selecciona una región",
    width=400, height=300
)

# Histograma vinculado que se filtra con la selección
histograma = alt.Chart(df).mark_bar().encode(
    x=alt.X("categoria:N"),
    y=alt.Y("count()"),
    color=alt.Color("categoria:N")
).transform_filter(seleccion).properties(
    title="Distribución de la selección",
    width=400, height=300
)

# Mostrar lado a lado
st.altair_chart(scatter | histograma, use_container_width=True)

st.vega_lite_chart: especificación JSON directa

Para usuarios que conocen la especificación JSON de Vega-Lite, st.vega_lite_chart permite pasarla directamente:

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

df = pd.DataFrame({"x": range(10), "y": np.random.randn(10).cumsum()})

st.vega_lite_chart(df, {
    "mark": {"type": "line", "point": True},
    "encoding": {
        "x": {"field": "x", "type": "quantitative"},
        "y": {"field": "y", "type": "quantitative"}
    },
    "title": "Gráfico con Vega-Lite directo"
}, use_container_width=True)

El operador | (pipe) coloca los gráficos uno al lado del otro horizontalmente, mientras que & los apila verticalmente. Esto permite crear paneles de análisis exploratorio conectados sin necesidad de gestionar el layout manualmente.

st.graphviz_chart: grafos y diagramas de dependencias

st.graphviz_chart renderiza grafos de nodos y aristas descritos en el lenguaje DOT de Graphviz. Es la herramienta adecuada para visualizar pipelines de datos, árboles de decisión, diagramas de arquitectura, grafos de dependencias y cualquier estructura que se represente naturalmente como un conjunto de nodos conectados por aristas:

import streamlit as st

# Pipeline de ML como grafo de dependencias
st.graphviz_chart("""
digraph pipeline_ml {
    rankdir=LR
    node [shape=box, style=filled]

    Datos [fillcolor="#E3F2FD"]
    Limpieza [fillcolor="#E8F5E9"]
    Features [fillcolor="#E8F5E9"]
    Entrenamiento [fillcolor="#FFF3E0"]
    Validacion [fillcolor="#FFF3E0"]
    Despliegue [fillcolor="#FCE4EC"]
    Monitoreo [fillcolor="#FCE4EC"]

    Datos -> Limpieza
    Limpieza -> Features
    Features -> Entrenamiento
    Entrenamiento -> Validacion
    Validacion -> Despliegue [label="AUC > 0.90"]
    Validacion -> Entrenamiento [label="AUC ≤ 0.90", style=dashed]
    Despliegue -> Monitoreo
    Monitoreo -> Entrenamiento [label="Drift detectado", style=dashed]
}
""")

# Árbol de herencia de clases
st.graphviz_chart("""
digraph herencia {
    node [shape=record]

    Animal [label="{Animal|+ nombre: str\\n+ edad: int|+ sonido()\\n+ moverse()}"]
    Mamifero [label="{Mamifero|+ pelaje: str|+ amamantar()}"]
    Ave [label="{Ave|+ envergadura: float|+ volar()}"]
    Perro [label="{Perro||+ ladrar()}"]
    Gato [label="{Gato||+ maullar()}"]

    Animal -> Mamifero
    Animal -> Ave
    Mamifero -> Perro
    Mamifero -> Gato
}
""")

Examen de visualización con todas las herramientas

import streamlit as st
import altair as alt
import plotly.express as px
import matplotlib.pyplot as plt
import seaborn as sns
import pandas as pd

st.title("Comparativa de bibliotecas de visualización")

herramienta = st.segmented_control(
    "Biblioteca",
    ["Altair", "Plotly", "Matplotlib/Seaborn"],
    default="Plotly"
)

df = px.data.iris()

if herramienta == "Altair":
    chart = alt.Chart(df).mark_circle().encode(
        x="sepal_length:Q", y="sepal_width:Q",
        color="species:N", tooltip=list(df.columns)
    ).properties(title="Iris — Altair", width="container")
    st.altair_chart(chart, use_container_width=True)

elif herramienta == "Plotly":
    fig = px.scatter(df, x="sepal_length", y="sepal_width",
                     color="species", title="Iris — Plotly")
    st.plotly_chart(fig, use_container_width=True)

else:
    fig, ax = plt.subplots(figsize=(8, 5))
    sns.scatterplot(data=df, x="sepal_length", y="sepal_width",
                    hue="species", ax=ax)
    ax.set_title("Iris — Matplotlib/Seaborn")
    st.pyplot(fig)
    plt.close(fig)
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

Crear gráficos interactivos declarativos con Altair y st.altair_chart. Usar la gramática de gráficos de Altair con mark_point, mark_bar y mark_line. Implementar selecciones interactivas y vinculación entre gráficos con Altair. Renderizar especificaciones Vega-Lite directamente con st.vega_lite_chart. Visualizar grafos de nodos y aristas con st.graphviz_chart y lenguaje DOT.