14 Escalas y guías
You are reading the work-in-progress third edition of the ggplot2 book. This chapter is currently a dumping ground for ideas, and we don’t recommend reading it.
La caja de herramientas de escalas en Capítulo 10 a Capítulo 12 proporciona una guía extensa sobre cómo trabajar con escalas, enfocándose en resolver problemas comunes de visualización de datos. Los objetivos prácticos de la caja de herramientas significan que los temas se introducen cuando son más relevantes: por ejemplo, las transformaciones de escala se analizan en relación con las escalas de posición continua (Sección 10.1.7) porque esa es la situación más común en la que es posible que desee transformar una escala. Sin embargo, debido a que ggplot2 tiene como objetivo proporcionar una gramática de gráficos, no hay nada que le impida transformar otros tipos de escalas (consulte Sección 14.6). Este capítulo tiene como objetivo ilustrar estos conceptos: discutiremos la teoría que sustenta las escalas y guías, y daremos ejemplos que muestran cómo los conceptos que hemos discutido específicamente para las escalas de posición o color también se aplican en otros lugares.
14.1 Teoría de escalas y guías.
Formalmente, cada escala es una función desde una región en el espacio de datos (el dominio de la escala) hasta una región en el espacio estético (el rango de la escala). El eje o leyenda es la función inversa, conocida como guía: le permite convertir propiedades visuales nuevamente en datos. Puede que le sorprenda que los ejes y las leyendas sean el mismo tipo de cosas, pero si bien se ven muy diferentes, tienen el mismo propósito: permitirle leer las observaciones de la gráfica y mapearlas a sus valores originales. Los puntos en común entre los dos se ilustran a continuación:
Nombre del argumento | Eje | Leyenda |
---|---|---|
name |
Etiqueta | Título |
breaks |
Marcas y líneas de cuadrícula | Entrada |
labels |
Etiqueta de marca | Etiqueta de entrada |
Sin embargo, las leyendas son más complicadas que los ejes y, en consecuencia, hay una serie de temas específicos de las leyendas:
Una leyenda puede mostrar múltiples estéticas (por ejemplo, color y forma), de múltiples capas (Sección 14.7.1), y el símbolo que se muestra en una leyenda varía según la geom utilizada en la capa (?sec-legend -glifo)
Los ejes siempre aparecen en el mismo lugar. Las leyendas pueden aparecer en diferentes lugares, por lo que necesitas alguna forma global de posicionarlas.
Las leyendas tienen más detalles que se pueden modificar: ¿deberían mostrarse vertical u horizontalmente? ¿Cuántas columnas? ¿Qué tamaño deben tener las llaves? Esto se comenta en (Sección 14.5)
14.1.1 Especificación de escala
Una propiedad importante de ggplot2 es el principio de que cada estética de su gráfica está asociada exactamente con una escala. Por ejemplo, cuando escribes esto
ggplot(mpg, aes(displ, hwy)) +
geom_point(aes(colour = class))
ggplot2 agrega una escala predeterminada para cada estética utilizada en la gráfica:
ggplot(mpg, aes(displ, hwy)) +
geom_point(aes(colour = class)) +
scale_x_continuous() +
scale_y_continuous() +
scale_colour_discrete()
La elección de la escala predeterminada depende de la estética y del tipo de variable. En este ejemplo, hwy
es una variable continua asignada a la estética y, por lo que la escala predeterminada es scale_y_continuous()
; de manera similar, class
es discreta, por lo que cuando se asigna a la estética del color, la escala predeterminada se convierte en scale_colour_discrete()
. Especificar estos valores predeterminados sería tedioso, por lo que ggplot2 lo hace por usted. Pero si desea anular los valores predeterminados, deberá agregar la escala usted mismo, de esta manera:
ggplot(mpg, aes(displ, hwy)) +
geom_point(aes(colour = class)) +
scale_x_continuous(name = "Una etiqueta del eje x realmente impresionante.") +
scale_y_continuous(name = "Una etiqueta del eje Y increíblemente genial.")
En la práctica, normalmente usarías labs()
para esto, lo cual se analiza en Sección 8.1, pero conceptualmente es útil comprender que las etiquetas de los ejes y los títulos de las leyendas son ejemplos de nombres de escala: consulta Sección 14.2.
El uso de +
para “agregar” escalas a una gráfica es un poco engañoso porque si proporcionas dos escalas para la misma estética, la última escala tiene prioridad. En otras palabras, cuando haces +
en una escala, en realidad no la agregas al gráfico, sino que anulas la escala existente. Esto significa que las dos especificaciones siguientes son equivalentes:
ggplot(mpg, aes(displ, hwy)) +
geom_point() +
scale_x_continuous(name = "Etiqueta 1") +
scale_x_continuous(name = "Etiqueta 2")
#> Scale for x is already present.
#> Adding another scale for x, which will replace the existing scale.
ggplot(mpg, aes(displ, hwy)) +
geom_point() +
scale_x_continuous(name = "Etiqueta 2")
Tenga en cuenta el mensaje cuando agrega varias escalas para la misma estética, lo que hace que sea más difícil sobrescribir accidentalmente una escala existente. Si ve esto en su propio código, debe asegurarse de agregar solo una escala a cada estética.
Si está haciendo pequeños ajustes a las escalas, puede continuar usando las escalas predeterminadas, proporcionando algunos argumentos adicionales. Si desea realizar cambios más radicales, anulará las escalas predeterminadas con alternativas:
ggplot(mpg, aes(displ, hwy)) +
geom_point(aes(colour = class)) +
scale_x_sqrt() +
scale_colour_brewer()
Aquí scale_x_sqrt()
cambia la escala para la escala del eje x, y scale_colour_brewer()
hace lo mismo para la escala de color.
14.1.2 Esquema de nombres
Todas las funciones de báscula destinadas a los usuarios siguen un esquema de nomenclatura común. Probablemente ya hayas descubierto el esquema, pero para ser concretos, se compone de tres piezas separadas por “_”:
scale
- El nombre de la estética primaria (e.g.,
colour
,shape
ox
) - El nombre de la escala (e.g.,
continuous
,discrete
,brewer
).
La estructura de nombres suele ser útil, pero a veces puede resultar ambigua. Por ejemplo, queda inmediatamente claro que las funciones scale_x_*()
se aplican a la estética x, pero se necesita un poco más de reflexión para reconocer que también gobiernan el comportamiento de otras estéticas que describen una posición horizontal (por ejemplo, la función xmin
, xmax
y xend
estética). De manera similar, si bien el nombre scale_colour_continuous()
se refiere claramente a la escala de colores asociada con variables continuas, es menos obvio que scale_colour_distiller()
es simplemente un método diferente para crear escalas de colores para variables continuas.
14.1.3 Tipos de escalas fundamentales
Es útil señalar que internamente todas las funciones de escala en ggplot2 pertenecen a uno de tres tipos fundamentales; escalas continuas, escalas discretas y escalas agrupadas. Cada tipo fundamental es manejado por una de las tres funciones constructoras de escala; continuous_scale()
, discrete_scale()
y binned_scale()
. Aunque nunca debería necesitar llamar a estas funciones constructoras, proporcionan la estructura organizativa para las escalas y es útil conocerlas.
14.2 Nombres de escala
Amplíar la discusión sobre labs()
en Sección 8.1.
14.3 Saltos de escala
Discusión sobre lo que unifica el concepto de breaks
en escalas continuas, discretas y agrupadas: son valores de datos específicos en los que la guía necesita mostrar algo. Incluya detalles adicionales sobre las funciones de descanso.
14.4 Límites de escala
Sección 14.1 introdujo el concepto de que una escala define un mapeo desde el espacio de datos al espacio estético. Los límites de escala son una extensión de esta idea: dictan la región del espacio de datos sobre la cual se define el mapeo. A nivel teórico esta región se define de forma diferente según el tipo de escala fundamental. Para escalas continuas y agrupadas, el espacio de datos es inherentemente continuo y unidimensional, por lo que los límites se pueden especificar mediante dos puntos finales. Sin embargo, para las escalas discretas, el espacio de datos no está estructurado y consta únicamente de un conjunto de categorías: como tal, los límites de una escala discreta sólo pueden especificarse enumerando el conjunto de categorías sobre las cuales se define el mapeo.
Los capítulos de la caja de herramientas describen los objetivos prácticos comunes para especificar los límites: para escalas de posición, los límites se utilizan para establecer los puntos finales del eje, por ejemplo. Esto lleva naturalmente a la pregunta de qué debería hacer ggplot2 si el conjunto de datos contiene valores “fuera de límites” que quedan fuera de los límites.
El comportamiento predeterminado en ggplot2 es convertir valores fuera de límites a NA
, la lógica para esto es que si un valor de datos no es parte de la región asignada, debe tratarse como faltante. En ocasiones, esto puede provocar un comportamiento inesperado, como se ilustra en Sección 10.1.2. Puede anular este valor predeterminado configurando el argumento oob
de la escala, una función que se aplica a todas las observaciones fuera de los límites de la escala. El valor predeterminado es scales::oob_censor()
que reemplaza cualquier valor fuera de los límites con NA
. Otra opción es scales::oob_squish()
que comprime todos los valores en el rango. A continuación se muestra un ejemplo que utiliza una escala de relleno:
df <- data.frame(x = 1:6, y = 8:13)
base <- ggplot(df, aes(x, y)) +
geom_col(aes(fill = x)) + # bar chart
geom_vline(xintercept = 3.5, colour = "red") # for visual clarity only
base
base + scale_fill_gradient(limits = c(1, 3))
base + scale_fill_gradient(limits = c(1, 3), oob = scales::squish)
A la izquierda se muestran los colores de relleno predeterminados, que van del azul oscuro al azul claro. En el panel central, los límites de escala para la estética del relleno se reducen de modo que los valores de las tres barras más a la derecha se reemplazan con NA
y se asignan a un tono gris. En algunos casos, este es el comportamiento deseado, pero a menudo no lo es: el panel derecho soluciona este problema modificando la función oob
de forma adecuada.
14.5 Guías de escala
Las guías de escala son más complejas que los nombres de escala: donde el argumento name
(y labs()
) toma texto como entrada, el argumento guide
(y guides()
) requieren un objeto guía creado por un ** función de guía** como guide_colourbar()
y guide_legend()
. Estos argumentos para estas funciones ofrecen un control preciso adicional sobre la guía.
La siguiente tabla resume las funciones de guía predeterminadas asociadas con diferentes tipos de báscula:
Tipo de escala | Tipo de guía predeterminado |
---|---|
escalas continuas para estética de color/relleno | barra de colores |
escalas agrupadas para estética de color/relleno | pasos de color |
escalas de posición (continua, agrupada y discreta) | ejes |
escalas discretas (excepto escalas de posición) | leyenda |
escalas agrupadas (excepto escalas de posición/color/relleno) | contenedores |
Cada uno de estos tipos de guía apareció anteriormente en la caja de herramientas:
-
guide_colourbar()
se discute en Sección 11.2.5 -
guide_coloursteps()
se discute en Sección 11.4.2 -
guide_axis()
se discute en Sección 10.3.2 -
guide_legend()
se discute en Sección 11.3.6 -
guide_bins()
se discute en Sección 12.1.2
Además de la funcionalidad analizada en esas secciones, las funciones de la guía tienen muchos argumentos que son equivalentes a la configuración del tema, como el color del texto, el tamaño, la fuente, etc., pero solo se aplican a una única guía. Para obtener información sobre esas configuraciones, consulte ?sec-polish.
Cosas nuevas: muestra ejemplos en los que se utiliza algo distinto a la guía predeterminada…
14.6 Transformación de escala
El uso más común de las transformaciones de escala es ajustar una escala de posición continua, como se explica en Sección 10.1.7. Sin embargo, a veces pueden resultar útiles cuando se aplican a otras estéticas. A menudo esto es puramente una cuestión de énfasis visual. A continuación se muestra un ejemplo de esto para el gráfico de densidad de Old Faithful. La escala mapeada linealmente a la izquierda hace que sea fácil ver los picos de la distribución, mientras que la representación transformada a la derecha hace que sea más fácil ver las regiones de densidad no despreciable alrededor de esos picos:
base <- ggplot(faithfuld, aes(waiting, eruptions)) +
geom_raster(aes(fill = density)) +
scale_x_continuous(NULL, NULL, expand = c(0, 0)) +
scale_y_continuous(NULL, NULL, expand = c(0, 0))
base
base + scale_fill_continuous(trans = "sqrt")
Transformar la estética del tamaño también es posible:
df <- data.frame(x = runif(20), y = runif(20), z = sample(20))
base <- ggplot(df, aes(x, y, size = z)) + geom_point()
base
base + scale_size(trans = "reverse")
En el gráfico de la izquierda, el valor z
se interpreta naturalmente como un “peso”: si cada punto corresponde a un grupo, el valor z
podría ser el tamaño del grupo. En el gráfico de la derecha, la escala de tamaño se invierte y z
se interpreta de forma más natural como una medida de “distancia”: las entidades distantes se escalan para que parezcan más pequeñas en el gráfico.
14.7 Leyenda fusionándose y dividiéndose
Siempre existe una correspondencia uno a uno entre las escalas de posición y los ejes. Pero la conexión entre las escalas sin posición y la leyenda es más compleja: una leyenda puede necesitar dibujar símbolos de múltiples capas (“fusión”), o una estética puede necesitar múltiples leyendas (“división”).
14.7.1 Fusionando leyendas
La fusión de leyendas ocurre con bastante frecuencia cuando se usa ggplot2. Por ejemplo, si ha asignado color tanto a puntos como a líneas, las claves mostrarán tanto los puntos como las líneas. Si has asignado el color de relleno, obtendrás un rectángulo. Tenga en cuenta la forma en que varía la leyenda en los gráficos siguientes:
De forma predeterminada, una capa solo aparecerá si la estética correspondiente se asigna a una variable con aes()
. Puede anular si una capa aparece o no en la leyenda con show.legend
: FALSE
para evitar que una capa aparezca en la leyenda; TRUE
lo obliga a aparecer cuando de otro modo no lo haría. Usar TRUE
puede ser útil junto con el siguiente truco para resaltar los puntos:
ggplot(toy, aes(up, up)) +
geom_point(size = 4, colour = "grey20") +
geom_point(aes(colour = txt), size = 2)
ggplot(toy, aes(up, up)) +
geom_point(size = 4, colour = "grey20", show.legend = TRUE) +
geom_point(aes(colour = txt), size = 2)
ggplot2 intenta utilizar la menor cantidad de leyendas para transmitir con precisión la estética utilizada en la gráfica. Lo hace combinando leyendas donde la misma variable se asigna a diferentes estéticas. La siguiente figura muestra cómo funciona esto para puntos: si tanto el color como la forma se asignan a la misma variable, entonces solo es necesaria una única leyenda.
base <- ggplot(toy, aes(const, up)) +
scale_x_continuous(NULL, breaks = NULL)
base + geom_point(aes(colour = txt))
base + geom_point(aes(shape = txt))
base + geom_point(aes(shape = txt, colour = txt))
Para que las leyendas se fusionen, deben tener el mismo “nombre”. Entonces, si cambia el nombre de una de las escalas, deberá cambiarlo para todas ellas. Una forma de hacer esto es usando la función auxiliar labs()
:
base <- ggplot(toy, aes(const, up)) +
geom_point(aes(shape = txt, colour = txt)) +
scale_x_continuous(NULL, breaks = NULL)
base
base + labs(shape = "Split legend")
base + labs(shape = "Merged legend", colour = "Merged legend")
14.7.2 Dividiendo leyendas
Dividir una leyenda es una tarea de visualización de datos mucho menos común. En general, no es recomendable asignar una estética (por ejemplo, color) a múltiples variables y, por lo tanto, de forma predeterminada, ggplot2 no le permite “dividir” la estética del color en múltiples escalas con leyendas separadas. Sin embargo, existen excepciones a esta regla general y es posible anular este comportamiento utilizando el paquete ggnewscale (Campitelli 2020). El comando ggnewscale::new_scale_colour()
actúa como una instrucción para ggplot2 para inicializar una nueva escala de color: los comandos de escala y guía que aparecen encima del comando new_scale_colour()
se aplicarán a la primera escala de color, y los comandos que aparecen A continuación se aplican a la segunda escala de colores.
Para ilustrar esto, el gráfico de la izquierda usa geom_point()
para mostrar un marcador grande para cada marca de vehículo en los datos de mpg
, con una escala de color única que se asigna al año. A la derecha, una segunda capa geom_point()
se superpone en el gráfico mediante pequeños marcadores: esta capa está asociada a una escala de colores diferente, que se utiliza para indicar si el vehículo tiene un motor de 4 cilindros.
base <- ggplot(mpg, aes(displ, hwy)) +
geom_point(aes(colour = factor(year)), size = 5) +
scale_colour_brewer("year", type = "qual", palette = 5)
base
base +
ggnewscale::new_scale_colour() +
geom_point(aes(colour = cyl == 4), size = 1, fill = NA) +
scale_colour_manual("4 cylinder", values = c("grey60", "black"))
Detalles adicionales, incluidas funciones que se aplican a otros tipos de básculas, están disponibles en el sitio web del paquete, https://github.com/eliocamp/ggnewscale.
14.8 Glifos clave de leyenda
En la mayoría de los casos, los glifos predeterminados que se muestran en la clave de leyenda serán apropiados para la capa y la estética. Los diagramas de líneas de diferentes colores aparecerán como líneas de diferentes colores en la leyenda, los diagramas de caja aparecerán como diagramas de caja pequeños en la leyenda, y así sucesivamente. Si necesita anular este comportamiento, el argumento key_glyph
se puede utilizar para asociar una capa particular con un tipo diferente de glifo. Por ejemplo:
base <- ggplot(economics, aes(date, psavert, color = "savings"))
base + geom_line()
base + geom_line(key_glyph = "timeseries")
Más precisamente, cada geom está asociada con una función como draw_key_boxplot()
o draw_key_path()
que es responsable de dibujar la clave cuando se crea la leyenda. Puede pasar directamente la función de dibujo clave deseada: por ejemplo, base + geom_line(key_glyph = draw_key_timeseries)
también produciría el gráfico que se muestra arriba a la derecha.