ggplot() y aes(): el mapeo estético

r
visualizacion
ggplot2
Qué significa mapear una variable a una propiedad visual. La diferencia entre mapeo estético y argumento fijo, los aesthetics más útiles y los errores que casi todo el mundo comete.

¿Qué es un mapeo estético?

En la gramática de Wilkinson, un aesthetic es una propiedad visual del gráfico que depende de los datos. La operación clave es el mapping: declarar “esta variable del data frame controla esta propiedad visual”.

Ejemplos:

Aesthetic Variable mapeada produce…
x Posición horizontal
y Posición vertical
color Color del trazo (puntos, líneas)
fill Color del relleno (áreas: barras, polígonos)
shape Forma del marcador
size Tamaño
alpha Transparencia
linetype Tipo de línea (continua, discontinua, punteada)

Cuando escribes:

ggplot(penguins, aes(x = bill_length_mm, y = flipper_length_mm, color = species))

Estás diciendo: “toma cada fila del data frame. Usa su valor de bill_length_mm para la posición X, el de flipper_length_mm para la Y, y el de species para decidir el color”.

Cada punto del gráfico es una fila del data frame. Cada propiedad visual es el resultado de un mapeo.

La diferencia entre aes() y argumento fijo

Esta es la confusión más extendida en quien aprende ggplot2. Lee esto despacio:

# Caso 1: color depende de los datos
ggplot(penguins, aes(x = bill_length_mm, y = flipper_length_mm)) +
  geom_point(aes(color = species))     # color DENTRO de aes()

# Caso 2: todos los puntos del mismo color
ggplot(penguins, aes(x = bill_length_mm, y = flipper_length_mm)) +
  geom_point(color = "steelblue")      # color FUERA de aes()

La diferencia es brutal:

  • Dentro de aes() → mapeo: “el color depende de esta variable”. ggplot2 escoge una paleta y genera una leyenda automáticamente.
  • Fuera de aes() → constante: “todos los marcadores son de este color exacto”. Sin mapeo, sin leyenda.

El error clásico:

geom_point(aes(color = "red"))   # ¡no funciona como esperas!

Lo que ggplot2 entiende aquí: “crea una nueva variable que en todas las filas vale 'red', y mapea su color a algo”. Como hay un único valor, escoge un color cualquiera de su paleta por defecto (típicamente salmón) y añade una leyenda con la etiqueta red. Ridículo.

La regla mental: si quieres un color literal, va FUERA de aes(). Si quieres que dependa de los datos, dentro.

Mapeo en ggplot() vs en geom_

Los aesthetics pueden vivir en el ggplot() base o en cada geom:

# Versión A: aesthetics en ggplot()
ggplot(penguins, aes(x = bill_length_mm, y = flipper_length_mm,
                     color = species)) +
  geom_point() +
  geom_smooth(method = "lm")

# Versión B: aesthetics repartidos
ggplot(penguins, aes(x = bill_length_mm, y = flipper_length_mm)) +
  geom_point(aes(color = species)) +
  geom_smooth(method = "lm")

La diferencia:

  • En ggplot() → los aesthetics se heredan a todos los geoms. En la versión A, tanto los puntos como la línea de smooth están coloreados por especie (tres líneas, una por especie).
  • En el geom → los aesthetics aplican solo a ese geom. En la versión B, los puntos están coloreados por especie pero el smooth es una única línea para todo el dataset.

Es una decisión deliberada. Si quieres comportamiento global, sube los aesthetics al ggplot(). Si quieres aplicarlos solo a un geom específico, ponlos en su llamada.

Aesthetics típicos por tipo de gráfico

Cada geom tiene aesthetics que entiende y aesthetics que ignora. Los más universales:

Geom Aesthetics frecuentes
geom_point x, y, color, size, shape, alpha
geom_line x, y, color, linetype, linewidth, group
geom_col / geom_bar x, y, fill, color
geom_histogram x, fill, color (sin y, lo calcula él)
geom_boxplot x, y, fill, color
geom_text x, y, label, color, size

fill vs color es una distinción importante: color es el borde, fill es el interior. Para geom_point da igual (no hay borde distinguible salvo en formas específicas como shape = 21, que sí tiene borde y relleno separados). Para barras, áreas y polígonos, sí importa.

Trampas habituales

  • aes(color = "red") en lugar de color = "red": el error número 1 de ggplot2. Si tu leyenda muestra una etiqueta con un nombre de color, sabes exactamente qué pasó.
  • Olvidar group = en geom_line con varios grupos. Si dibujas varias líneas y todas se juntan en una sola línea quebrada, te falta aes(group = id) o un aesthetic categórico como color = id (que también agrupa automáticamente).
  • Pensar que aes() toma data$columna. No, aes() evalúa los nombres en el contexto del data frame que le pasaste a ggplot(). Escribe aes(x = bill_length_mm), no aes(x = penguins$bill_length_mm).
  • size deprecado para líneas. Desde ggplot2 3.4, el aesthetic para grosor de línea es linewidth, no size. size sigue funcionando pero emite warning. Adopta linewidth para código nuevo.

En la siguiente entrega

Has aprendido a mapear variables a propiedades visuales. La siguiente pieza es el geom: la forma geométrica que dibuja cada fila. Vemos los tres geoms que cubren el 80 % de los gráficos, geom_point, geom_line, geom_col, y el patrón de combinarlos en capas.