ggplot() y aes(): el mapeo estético
¿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 decolor = "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 =engeom_linecon varios grupos. Si dibujas varias líneas y todas se juntan en una sola línea quebrada, te faltaaes(group = id)o un aesthetic categórico comocolor = id(que también agrupa automáticamente). - Pensar que
aes()tomadata$columna. No,aes()evalúa los nombres en el contexto del data frame que le pasaste aggplot(). Escribeaes(x = bill_length_mm), noaes(x = penguins$bill_length_mm). sizedeprecado para líneas. Desde ggplot2 3.4, el aesthetic para grosor de línea eslinewidth, nosize.sizesigue funcionando pero emite warning. Adoptalinewidthpara 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.