Contexto y Estructura del Gráfico


La importancia del contexto en visualizaciones

Un gráfico sin contexto es como una historia sin título: los lectores no saben qué están viendo ni por qué es importante. El contexto transforma datos en información comprensible mediante:

En esta lección aprenderemos a configurar:


Gráfico base

Continuaremos con nuestro gráfico de dispersión que ya tiene estilos y ejes configurados:

Ver código Plot.plot gráfico base
Plot.plot({
  x: {
    label: "Mortalidad infantil (por cada 1,000 nacidos vivos)",
    grid: true
  },
  y: {
    label: "Expectativa de vida (años)",
    grid: true
  },
  marks: [
    Plot.dot(datos, {
      x: "infant_mortality",
      y: "life_expectancy",
      fill: "steelblue",
      fillOpacity: 0.6,
      stroke: "darkblue",
      strokeWidth: 1.5
    })
  ]
})

El gráfico funciona bien, pero carece de contexto: ¿qué estamos viendo? ¿De dónde vienen los datos? ¿Qué conclusión deberíamos extraer?


Agregando un título: title

La propiedad title agrega un encabezado principal que comunica el mensaje central del gráfico.

Ver código Plot.plot con title
Plot.plot({
  title: "Relación entre mortalidad infantil y expectativa de vida",
  x: {
    label: "Mortalidad infantil (por cada 1,000 nacidos vivos)",
    grid: true
  },
  y: {
    label: "Expectativa de vida (años)",
    grid: true
  },
  marks: [
    Plot.dot(datos, {
      x: "infant_mortality",
      y: "life_expectancy",
      fill: "steelblue",
      fillOpacity: 0.6,
      stroke: "darkblue",
      strokeWidth: 1.5
    })
  ]
})

¿Qué cambió?

Se agregó:

Ahora el lector sabe inmediatamente qué está observando.


Mejores prácticas para títulos (Cairo, 2016)

Ser descriptivo y específico

Comunicar el hallazgo principal

Mantener brevedad

Usar mayúsculas apropiadamente


Agregando un subtítulo: subtitle

La propiedad subtitle proporciona información complementaria como el período temporal, la muestra o contexto adicional.

Ver código Plot.plot con subtitle
Plot.plot({
  title: "Relación entre mortalidad infantil y expectativa de vida",
  subtitle: "Datos de 195 países (2023)",
  x: {
    label: "Mortalidad infantil (por cada 1,000 nacidos vivos)",
    grid: true
  },
  y: {
    label: "Expectativa de vida (años)",
    grid: true
  },
  marks: [
    Plot.dot(datos, {
      x: "infant_mortality",
      y: "life_expectancy",
      fill: "steelblue",
      fillOpacity: 0.6,
      stroke: "darkblue",
      strokeWidth: 1.5
    })
  ]
})

¿Qué cambió?

Se agregó:

El subtítulo añade contexto temporal y de muestra.


Qué incluir en subtítulos

Período temporal

Tamaño de muestra

Región geográfica

Metodología relevante


Agregando nota al pie: caption

La propiedad caption se usa principalmente para citar la fuente de los datos y dar créditos.

Ver código Plot.plot con caption
Plot.plot({
  title: "Relación entre mortalidad infantil y expectativa de vida",
  subtitle: "Datos de 195 países (2023)",
  caption: "Fuente: World Data 2023 (Kaggle)",
  x: {
    label: "Mortalidad infantil (por cada 1,000 nacidos vivos)",
    grid: true
  },
  y: {
    label: "Expectativa de vida (años)",
    grid: true
  },
  marks: [
    Plot.dot(datos, {
      x: "infant_mortality",
      y: "life_expectancy",
      fill: "steelblue",
      fillOpacity: 0.6,
      stroke: "darkblue",
      strokeWidth: 1.5
    })
  ]
})

¿Qué cambió?

Se agregó:

La nota al pie completa la atribución y transparencia del gráfico.


Mejores prácticas para captions (Tufte, 2001)

Siempre citar la fuente

Incluir el autor si es relevante

Agregar notas metodológicas si son necesarias

Mantener concisión


Combinando título, subtítulo y caption

Veamos cómo funcionan juntos los tres elementos:

Ver código Plot.plot con title, subtitle y caption
Plot.plot({
  title: "Mayor mortalidad infantil se asocia con menor expectativa de vida",
  subtitle: "Análisis de 195 países a nivel mundial (2023)",
  caption: "Fuente: World Data 2023 (Kaggle) | Cada punto representa un país",
  x: {
    label: "Mortalidad infantil (por cada 1,000 nacidos vivos)",
    grid: true
  },
  y: {
    label: "Expectativa de vida (años)",
    grid: true
  },
  marks: [
    Plot.dot(datos, {
      x: "infant_mortality",
      y: "life_expectancy",
      fill: "steelblue",
      fillOpacity: 0.6,
      stroke: "darkblue",
      strokeWidth: 1.5
    })
  ]
})

Controlando las dimensiones: width y height

Las propiedades width y height definen el tamaño del gráfico en píxeles.

Ver código Plot.plot con width y height
Plot.plot({
  width: 800,
  height: 600,
  title: "Relación entre mortalidad infantil y expectativa de vida",
  subtitle: "Datos de 195 países (2023)",
  caption: "Fuente: World Data 2023 (Kaggle)",
  x: {
    label: "Mortalidad infantil (por cada 1,000 nacidos vivos)",
    grid: true
  },
  y: {
    label: "Expectativa de vida (años)",
    grid: true
  },
  marks: [
    Plot.dot(datos, {
      x: "infant_mortality",
      y: "life_expectancy",
      fill: "steelblue",
      fillOpacity: 0.6,
      stroke: "darkblue",
      strokeWidth: 1.5
    })
  ]
})

¿Qué cambió?

Se agregó:

Valor predeterminado: Si no se especifica, Plot usa 640×400 píxeles.


Guía de dimensiones

Gráficos pequeños (400-600px de ancho)

Gráficos medianos (640-900px de ancho)

Gráficos grandes (1000-1400px de ancho)


Proporción de aspecto


Controlando los márgenes

Los márgenes definen el espacio entre el borde del SVG y el área de graficado. Esto es importante cuando las etiquetas son largas o cuando se necesita más espacio visual.

Ver código Plot.plot con márgenes
Plot.plot({
  width: 800,
  height: 600,
  marginTop: 40,
  marginRight: 30,
  marginBottom: 50,
  marginLeft: 80,
  title: "Relación entre mortalidad infantil y expectativa de vida",
  subtitle: "Datos de 195 países (2023)",
  caption: "Fuente: World Data 2023 (Kaggle)",
  x: {
    label: "Mortalidad infantil (por cada 1,000 nacidos vivos)",
    grid: true
  },
  y: {
    label: "Expectativa de vida (años)",
    grid: true
  },
  marks: [
    Plot.dot(datos, {
      x: "infant_mortality",
      y: "life_expectancy",
      fill: "steelblue",
      fillOpacity: 0.6,
      stroke: "darkblue",
      strokeWidth: 1.5
    })
  ]
})

¿Qué cambió?

Se agregó:


Cuándo ajustar márgenes

Aumentar marginLeft cuando:

Aumentar marginBottom cuando:

Aumentar marginTop cuando:

Valores típicos:


Ejemplo para barras horizontales

Las barras horizontales a menudo necesitan más espacio a la izquierda para los nombres de países:

Ver código Plot.plot barras con marginLeft
Plot.plot({
  width: 800,
  height: 400,
  marginLeft: 150,
  marginBottom: 40,
  title: "Top 10 países con mayor expectativa de vida",
  subtitle: "Año 2023",
  caption: "Fuente: World Data 2023 (Kaggle)",
  x: {
    label: "Expectativa de vida (años)",
    grid: true
  },
  y: {
    label: null,
    domain: datos
      .filter(d => d["life_expectancy"] != null)
      .sort((a, b) => b["life_expectancy"] - a["life_expectancy"])
      .slice(0, 10)
      .map(d => d.country)
  },
  marks: [
    Plot.barX(
      datos
        .filter(d => d["life_expectancy"] != null)
        .sort((a, b) => b["life_expectancy"] - a["life_expectancy"])
        .slice(0, 10),
      {
        y: "country",
        x: "life_expectancy",
        fill: "forestgreen",
        fillOpacity: 0.8,
        stroke: "darkgreen",
        strokeWidth: 1
      }
    )
  ]
})

El marginLeft: 150 da espacio suficiente para los nombres completos de los países.

Se agregó .sort((a, b) => b["life_expectancy"] - a["life_expectancy"]) que permite colocar los datos de mayor a menor, en la barra X para seleccionar el top 10 y en el eje y para acomodar los países.


Estilos globales: style

La propiedad style permite aplicar estilos CSS personalizados al contenedor del gráfico.

Ver código Plot.plot con style
Plot.plot({
  width: 800,
  height: 600,
  style: {
    fontSize: "14px",
    fontFamily: "Georgia, serif",
    background: "#f9fafb",
    padding: "10px"
  },
  title: "Relación entre mortalidad infantil y expectativa de vida",
  subtitle: "Datos de 195 países (2023)",
  caption: "Fuente: World Data 2023 (Kaggle)",
  x: {
    label: "Mortalidad infantil (por cada 1,000 nacidos vivos)",
    grid: true
  },
  y: {
    label: "Expectativa de vida (años)",
    grid: true
  },
  marks: [
    Plot.dot(datos, {
      x: "infant_mortality",
      y: "life_expectancy",
      fill: "steelblue",
      fillOpacity: 0.6,
      stroke: "darkblue",
      strokeWidth: 1.5
    })
  ]
})

¿Qué cambió?

Se agregó:


Propiedades útiles en style

Tipografía:

Ver código style tipografía
style: {
  fontSize: "12px",
  fontFamily: "Arial, sans-serif",
  fontWeight: "normal"
}

Colores:

Ver código style colores
style: {
  background: "#ffffff",
  color: "#1f2937"
}

Bordes y padding:

Ver código style bordes y padding
style: {
  border: "1px solid #e5e7eb",
  borderRadius: "8px",
  padding: "20px"
}

Gráfico completo con todo el contexto

Veamos un gráfico con todas las propiedades de contexto y estructura aplicadas:

Ver código Plot.plot gráfico completo con contexto
Plot.plot({
  // Dimensiones
  width: 900,
  height: 550,

  // Márgenes
  marginTop: 50,
  marginRight: 40,
  marginBottom: 60,
  marginLeft: 80,

  // Contexto
  title: "Países con alta mortalidad infantil tienden a tener menor expectativa de vida",
  subtitle: "Análisis de 195 países a nivel mundial • Año 2023",
  caption: "Fuente: World Data 2023 (Kaggle) | Cada punto representa un país",

  // Estilos
  style: {
    fontSize: "13px",
    background: "#fafafa"
  },

  // Ejes
  x: {
    label: "Mortalidad infantil (por cada 1,000 nacidos vivos)",
    grid: true,
    nice: true
  },
  y: {
    label: "Expectativa de vida (años)",
    grid: true,
    nice: true
  },

  // Visualización
  marks: [
    Plot.dot(datos, {
      x: "infant_mortality",
      y: "life_expectancy",
      fill: "steelblue",
      fillOpacity: 0.6,
      stroke: "darkblue",
      strokeWidth: 1.5
    })
  ]
})

Este es un gráfico completo y profesional con:


Aplicando a otros tipos de gráficos

Histograma con contexto completo

Ver código Plot.plot histograma con contexto
Plot.plot({
  width: 800,
  height: 450,
  marginTop: 50,
  marginBottom: 50,
  title: "Distribución de la expectativa de vida a nivel mundial",
  subtitle: "La mayoría de países se concentra entre 70 y 80 años (2023)",
  caption: "Fuente: World Data 2023 (Kaggle) | n=195 países",
  x: {
    label: "Expectativa de vida (años)",
    grid: true
  },
  y: {
    label: "Número de países",
    grid: true
  },
  marks: [
    Plot.rectY(datos, Plot.binX({y: "count"}, {
      x: "life_expectancy",
      fill: "coral",
      fillOpacity: 0.7,
      stroke: "white",
      strokeWidth: 2
    }))
  ]
})

Barras con contexto completo

Ver código Plot.plot barras con contexto
Plot.plot({
  width: 900,
  height: 400,
  marginLeft: 50,
  marginBottom: 50,
  title: "Los 10 países con mayor expectativa de vida en 2023",
  subtitle: "Todos superan los 83 años de vida promedio",
  caption: "Fuente: World Data 2023 (Kaggle)",
  x: {
    label: "Expectativa de vida (años)",
    grid: true,
    domain: [75, 90],
    clamp: true
  },
  y: {
    label: null
  },
  marks: [
    Plot.barX(
      datos
        .filter(d => d["life_expectancy"] != null)
        .sort((a, b) => b["life_expectancy"] - a["life_expectancy"])
        .slice(0, 10),
      {
        y: "country",
        x: "life_expectancy",
        fill: "forestgreen",
        fillOpacity: 0.8,
        stroke: "darkgreen",
        strokeWidth: 1
      }
    )
  ]
})

Checklist de un gráfico profesional (Wilke, 2019)

Antes de considerar tu visualización completa, verifica que incluya:

Contexto textual

Configuración de ejes

Dimensiones y espaciado

Estética


Resumen de propiedades

Propiedad Tipo Función
title Texto Título principal del gráfico
subtitle Texto Información contextual adicional
caption Texto Fuente de datos y notas
width Número (px) Ancho del gráfico
height Número (px) Alto del gráfico
marginTop Número (px) Margen superior
marginRight Número (px) Margen derecho
marginBottom Número (px) Margen inferior
marginLeft Número (px) Margen izquierdo
style Objeto CSS Estilos globales del gráfico

Conclusiones de la lección

En esta lección se ha explorado cómo agregar contexto completo y estructura profesional a las visualizaciones en Observable Plot.


Conceptos clave

Elementos textuales

Dimensiones y espaciado

Estilos globales


Reflexión final

Un gráfico sin contexto puede ser técnicamente correcto pero comunicacionalmente fallido. Los elementos de contexto no son decorativos: son esenciales para que la visualización cumpla su propósito de transformar datos en conocimiento accesible.

La diferencia entre un gráfico amateur y uno profesional a menudo radica en estos detalles:

Invertir tiempo en estos elementos convierte visualizaciones en herramientas de comunicación efectivas.


Próximo paso: En la Visualización Multiple se explorará como mejorar la visualización de multiples variables en un mismo gráfico para mejorar su presentación, destacando las situaciones en las que es necesario o no utilizar multiples variables.


Bibliografía

Cairo, A. (2016). The Truthful Art: Data, Charts, and Maps for Communication (1a ed.). New Riders.
Tufte, E. (2001). The Visual Display of Quantitative Information (2a ed.). Graphics Press.
Wilke, C. (2019). Fundamentals of data visualization: a primer on making informative and compelling figures (First edition). O’Reilly.