11  Escalas de colores y leyendas.

You are reading the work-in-progress third edition of the ggplot2 book. This chapter should be readable but is currently undergoing final polishing.

Después de la posición, la estética más utilizada es la basada en el color, y hay muchas formas de asignar valores a colores en ggplot2. Debido a que el color es complejo, el capítulo comienza con una discusión sobre la teoría del color (?sec-color-theory) con especial referencia al daltonismo (?sec-color-blindness). Reflejando la estructura de los capítulos anteriores, las siguientes tres secciones están dedicadas a escalas de color continuas (?sec-color-continuous), escalas de colores discretas (?sec-color-discrete) y escalas de colores agrupadas (?sec-binned-color). ). El capítulo concluye analizando las escalas de color de fecha/hora (?sec-date-color-scales), las escalas de transparencia (Sección 11.6) y la mecánica del posicionamiento de la leyenda (Sección 11.7).

11.1 Un poco de teoría del color.

Antes de ver los detalles, es útil aprender un poco de teoría del color. La teoría del color es compleja porque la biología subyacente del ojo y el cerebro es compleja, y esta introducción sólo tocará algunas de las cuestiones más importantes. Una exposición excelente y más detallada está disponible en línea en http://tinyurl.com/clrdtls.

A nivel físico, el color se produce por una mezcla de longitudes de onda de luz. Para caracterizar completamente un color, necesitamos conocer la mezcla completa de longitudes de onda. Afortunadamente para nosotros, el ojo humano sólo tiene tres receptores de color diferentes, por lo que podemos resumir la percepción de cualquier color en sólo tres números. Quizás esté familiarizado con la codificación RGB del espacio de color, que define un color según las intensidades de luz roja, verde y azul necesarias para producirlo. Un problema con este espacio es que no es perceptualmente uniforme: los dos colores que están separados por una unidad pueden parecer similares o muy diferentes dependiendo de dónde se encuentren en el espacio de color. Esto dificulta la creación de un mapeo de una variable continua a un conjunto de colores. Ha habido muchos intentos de crear espacios de color que sean más perceptualmente uniformes. Usaremos un intento moderno llamado espacio de color HCL, que tiene tres componentes: hue, chroma y lluminance:

  • Hue varía de 0 a 360 (un ángulo) y proporciona el “color” del color (azul, rojo, naranja, etc.).
  • Chroma es la “pureza” de un color, que va desde 0 (gris) hasta un máximo que varía con la luminancia.
  • Luminance es la luminosidad del color, que va de 0 (negro) a 1 (blanco).

Las tres dimensiones tienen propiedades diferentes. Los tonos están dispuestos alrededor de una rueda de colores y no se perciben como ordenados: p.e. el verde no parece “más grande” que el rojo, y el azul no parece estar “entre” el verde y el rojo. Por el contrario, tanto el croma como la luminancia se perciben como ordenados: el rosa se percibe entre el rojo y el blanco, y el gris entre el blanco y el negro.

La combinación de estos tres componentes no produce una forma geométrica simple. La siguiente figura intenta mostrar la forma tridimensional del espacio. Cada corte es una luminancia (brillo) constante con tono asignado al ángulo y croma al radio. Puedes ver que el centro de cada rebanada es gris y los colores se vuelven más intensos a medida que se acercan al borde.

La forma del espacio de color HCL. El tono se asigna al ángulo, el croma al radio y cada corte muestra una luminancia diferente. El espacio HCL tiene una forma bastante extraña, pero puedes ver que los colores cerca del centro de cada segmento son grises y, a medida que avanzas hacia los bordes, se vuelven más intensos. Se omiten los cortes para las luminancias 0 y 100 porque serían, respectivamente, un único punto negro y un único punto blanco.

11.1.1 Daltonismo

Una complicación adicional es que una minoría considerable de personas no posee el complemento habitual de receptores de color y, por tanto, puede distinguir menos colores que otros. Debido a esto, es importante considerar cómo se verá una paleta de colores para las personas con formas comunes de daltonismo. Una heurística simple es evitar los contrastes rojo-verde y verificar sus gráficos con sistemas que simulen el daltonismo. Además de las muchas herramientas en línea que pueden ayudar con esto (por ejemplo, https://www.vischeck.com/), existen varios paquetes de R que proporcionan herramientas que pueden resultarle útiles. El paquete dicromático (dichroma?) proporciona herramientas para simular el daltonismo y un conjunto de combinaciones de colores que se sabe que funcionan bien para las personas daltónicas. Otra herramienta útil es el paquete colorBlindness (Ou 2021) que proporciona una función displayAllColors() que le ayuda a aproximar la apariencia de un conjunto determinado de colores bajo diferentes formas de daltonismo. A modo de ilustración, revela rápidamente que los colores proporcionados por la paleta rainbow() no son apropiados si estás tratando de crear gráficos que sean legibles para personas daltónicas, ni se reproducen bien en escala de grises:

colorBlindness::displayAllColors(rainbow(6))

A modo de contraste, los colores proporcionados por viridis::viridis() son discriminables bajo las formas más comunes de daltonismo y se reproducen bien en escala de grises:

colorBlindness::displayAllColors(viridis::viridis(6))

Además del paquete viridis, existen otros paquetes R que proporcionan paletas que son explícitamente seguras para daltónicos y los verá en uso a lo largo del capítulo. Finalmente, también puedes ayudar a las personas con daltonismo de la misma manera que puedes ayudar a las personas con impresoras en blanco y negro: proporcionando asignaciones redundantes a otras estéticas como el tamaño, el tipo de línea o la forma.

11.2 Escalas de color continuas

Los degradados de color se utilizan a menudo para mostrar la altura de una superficie 2D. Los gráficos de esta sección utilizan la superficie de una estimación de densidad 2D del conjunto de datos faithful (Azzalini y Bowman 1990), que registra el tiempo de espera entre erupciones y durante cada erupción del géiser Old Faithful en el Parque Yellowstone. Ocultamos las leyendas y configuramos expand en 0, para centrarnos en la apariencia de los datos. Recuerde: aunque usamos la gráfica erupt para ilustrar conceptos usando una estética de relleno, las mismas ideas se aplican a las escalas de color. Cada vez que hacemos referencia a scale_fill_*() en esta sección, hay un scale_color_*() correspondiente para la estética del color (o scale_color_*() si prefiere la ortografía estadounidense).

erupt <- ggplot(faithfuld, aes(waiting, eruptions, fill = density)) +
  geom_raster() +
  scale_x_continuous(NULL, expand = c(0, 0)) + 
  scale_y_continuous(NULL, expand = c(0, 0)) + 
  theme(legend.position = "none")

11.2.1 Paletas particulares

Hay varias formas de especificar escalas de color continuas. Más adelante hablaremos sobre herramientas de uso general que puede utilizar para construir su propia paleta, pero esto suele ser innecesario ya que hay muchas paletas “seleccionadas a mano” disponibles. Por ejemplo, ggplot2 proporciona dos funciones de escala que agrupan paletas preespecificadas, scale_fill_viridis_c() y scale_fill_distiller(). Las escalas viridis (Garnier 2018) están diseñadas para ser perceptualmente uniformes tanto en color como cuando se reducen a blanco y negro, y para ser perceptibles para personas con diversas formas de daltonismo.

erupt
erupt + scale_fill_viridis_c()
erupt + scale_fill_viridis_c(option = "magma")

Para la mayoría de los casos de uso, las escalas viridis funcionarán mejor que otras escalas continuas integradas en ggplot2, pero existen otras opciones que son útiles en algunas situaciones. Un segundo grupo de escalas de color continuas integradas en ggplot2 se derivan de las escalas de ColorBrewer: scale_fill_brewer() proporciona estos colores como paletas discretas, mientras que scale_fill_distiller() y scale_fill_fermenter() son los análogos continuos y agrupados. Analizamos estas escalas en ?sec-color-discrete, pero con fines ilustrativos incluimos algunos ejemplos aquí:

erupt + scale_fill_distiller()
erupt + scale_fill_distiller(palette = "RdPu")
erupt + scale_fill_distiller(palette = "YlOrBr")

Hay muchos otros paquetes que proporcionan paletas de colores útiles. Por ejemplo, scico (Pedersen y Crameri 2020) proporciona más paletas que son perceptualmente uniformes y adecuadas para la visualización científica:

erupt + scico::scale_fill_scico(palette = "bilbao") # por defecto
erupt + scico::scale_fill_scico(palette = "vik")
erupt + scico::scale_fill_scico(palette = "lajolla")

Sin embargo, como hay muchos paquetes de paletas en R, un paquete particularmente útil es Paletteer (Hvitfeldt 2020), cuyo objetivo es proporcionar una interfaz común:

erupt + paletteer::scale_fill_paletteer_c("viridis::plasma")
erupt + paletteer::scale_fill_paletteer_c("scico::tokyo")

11.2.2 Recetas robustas

La escala predeterminada para escalas de relleno continuo es scale_fill_continuous() que a su vez por defecto es scale_fill_gradient(). Como consecuencia, estos tres comandos producen el mismo gráfico usando una escala de gradiente:

erupt
erupt + scale_fill_continuous()
erupt + scale_fill_gradient()

Las escalas de degradado proporcionan un método sólido para crear cualquier combinación de colores que desee. Todo lo que necesitas hacer es especificar dos o más colores de referencia y ggplot2 interpolará linealmente entre ellos. Hay tres funciones que puede utilizar para este propósito:

  • scale_fill_gradient() produce un degradado de dos colores
  • scale_fill_gradient2() produce un degradado de tres colores con un punto medio especificado
  • scale_fill_gradientn() produce un gradiente de n colores

The use of gradient scales is illustrated below. The first plot uses a scale that linearly interpolates from grey (hex code: "#bebebe") at the low end of the scale limits to brown ("#a52a2a") at the high end. The second plot has the same endpoints but uses scale_fill_gradient2() to interpolate first from grey to white (#ffffff) and then from white to brown. Note that the mid argument specifies the colour to be shown at the intermediate point, and midpoint is the value in the data at which this colour is used (the default is midpoint = 0). The third method is to use scale_fill_gradientn() which takes a vector of reference colours as its argument, and constructs a scale that linearly interpolates between the specified values. By default, the colours are presumed to be equally spaced along the scale, but if you prefer you can specify a vector of values that correspond to each of the reference colours.

El uso de escalas de gradiente se ilustra a continuación. El primer gráfico utiliza una escala que interpola linealmente desde el gris (código hexadecimal: "#bebebe") en el extremo inferior low de los límites de la escala hasta el marrón ("#a52a2a") en el extremo alto high. El segundo gráfico tiene los mismos puntos finales pero usa scale_fill_gradient2() para interpolar primero de gris a blanco (#ffffff) y luego de blanco a marrón. Tenga en cuenta que el argumento mid especifica el color que se mostrará en el punto intermedio, y midpoint es el valor de los datos en el que se utiliza este color (el valor predeterminado es midpoint = 0). El tercer método es utilizar scale_fill_gradientn() que toma un vector de colores de referencia como argumento y construye una escala que interpola linealmente entre los valores especificados. De forma predeterminada, se supone que los “colores” están igualmente espaciados a lo largo de la escala, pero si lo prefiere, puede especificar un vector de values que corresponda a cada uno de los colores de referencia.

erupt + scale_fill_gradient(low = "grey", high = "brown")
erupt + 
  scale_fill_gradient2(
    low = "grey", 
    mid = "white", 
    high = "brown", 
    midpoint = .02
  )
erupt + scale_fill_gradientn(colours = terrain.colors(7))

Crear buenas paletas de colores requiere cierto cuidado. Generalmente, para una escala de gradiente de dos puntos desea transmitir la impresión perceptiva de que los valores están ordenados secuencialmente, por lo que desea mantener el tono constante y variar el croma y la luminancia. El sistema de color Munsell es útil para esto, ya que proporciona una forma sencilla de especificar colores en función de su tono, croma y luminancia. El paquete munsell (Wickham 2018) proporciona fácil acceso a los colores Munsell, que luego se pueden usar para especificar una escala de gradiente:

munsell::hue_slice("5P") +  # Generar un ggplot con hue_slice()
  annotate(                 # Agregar flechas para anotaciones
    geom = "segment", 
    x = c(7, 7), 
    y = c(1, 10), 
    xend = c(7, 7), 
    yend = c(2, 9), 
    arrow = arrow(length = unit(2, "mm"))
  ) 
#> Warning: Removed 31 rows containing missing values or values outside the scale range
#> (`geom_text()`).

# Escala de construcción
erupt + scale_fill_gradient(
  low = munsell::mnsl("5P 2/12"), 
  high = munsell::mnsl("5P 7/12")
)

Las etiquetas en el gráfico de la izquierda son un poco difíciles de leer en esta escala, por lo que hemos usado annotate() para agregar flechas que resaltan la columna utilizada para construir la escala de la derecha. Para obtener más información sobre el paquete munsell, consulte https://github.com/cwickham/munsell/.

Las escalas de gradiente de tres puntos tienen criterios de diseño ligeramente diferentes. Normalmente, el objetivo de una escala de este tipo es transmitir la impresión perceptiva de que existe un punto medio natural (a menudo un valor cero) del cual divergen los demás valores. El gráfico de la izquierda a continuación muestra cómo crear una escala divergente “amarillo/azul”, aunque es un poco artificial en este ejemplo.

Finalmente, si tiene colores que son significativos para sus datos (por ejemplo, colores de carrocería negros o colores de terreno estándar), o desea utilizar una paleta producida por otro paquete, es posible que desee utilizar un degradado de n puntos. A modo de ilustración, los gráficos del centro y de la derecha a continuación utilizan el paquete colorspace (Zeileis, Hornik, y Murrell 2008). Para obtener más información sobre el paquete de espacio de color, consulte https://colorspace.r-forge.r-project.org/.

# ejemplo de munsell
erupt + scale_fill_gradient2(
  low = munsell::mnsl("5B 7/8"),
  high = munsell::mnsl("5Y 7/8"),
  mid = munsell::mnsl("N 7/0"),
  midpoint = .02
) 

# ejemplos de espacio de color
erupt + scale_fill_gradientn(colours = colorspace::heat_hcl(7))
erupt + scale_fill_gradientn(colours = colorspace::diverge_hcl(7))

11.2.3 Valores faltantes

Todas las escalas de colores continuos tienen un parámetro na.value que controla qué color se utiliza para los valores faltantes (incluidos los valores fuera del rango de los límites de la escala). Por defecto está configurado en gris, que resaltará cuando uses una escala de colores. Si usa una escala de blanco y negro, es posible que desee configurarla en otra cosa para que sea más obvia. Puedes configurar na.value = NA para hacer invisibles los valores faltantes, o elegir un color específico si lo prefieres:

df <- data.frame(x = 1, y = 1:5, z = c(1, 3, 2, NA, 5))
base <- ggplot(df, aes(x, y)) + 
  geom_tile(aes(fill = z), linewidth = 5) + 
  labs(x = NULL, y = NULL) +
  scale_x_continuous(labels = NULL)

base
base + scale_fill_gradient(na.value = NA)
base + scale_fill_gradient(na.value = "yellow")

11.2.4 Límites, rupturas y etiquetas

En el capítulo anterior discutimos cómo se puede controlar la apariencia de los ejes estableciendo los límites, limites (Sección 10.1.1), rupturas, breaks (Sección 10.1.4) y etiquetas, labels (@ argumento sec-position-continuous-labels) para la función de escala. El comportamiento de las escalas de color se puede controlar de forma análoga:

base <- ggplot(toy, aes(up, up, fill = big)) + 
  geom_tile() + 
  labs(x = NULL, y = NULL) 

base 
base + scale_fill_continuous(limits = c(0, 10000))

base + scale_fill_continuous(breaks = c(1000, 2000, 4000))
base + scale_fill_continuous(labels = scales::label_dollar())

(El conjunto de datos del juguete utilizado aquí es el mismo definido en Sección 10.1.4). Puede suprimir las pausas por completo configurándolas en NULL, lo que elimina las claves y las etiquetas.

11.2.5 Leyendas

Cada escala está asociada a una guía que muestra la relación entre la estética y los datos. En las escalas de posición, los ejes cumplen esta función. En el caso de las escalas de colores, este papel lo desempeña la leyenda, que se puede personalizar con la ayuda de una función de guía. Para escalas de colores continuas, la leyenda predeterminada toma la forma de una “barra de colores” que muestra un degradado continuo de colores:

base <- ggplot(mpg, aes(cyl, displ, colour = hwy)) +
  geom_point(size = 2)

base

La apariencia de la leyenda se puede controlar usando la función guide_colourbar(). Hay muchos argumentos para esta función, lo que le permite ejercer un control preciso sobre la leyenda. Los argumentos más importantes se ilustran a continuación:

  • reverse voltea la barra de colores para colocar los valores más bajos en la parte superior.

  • barwidth y barheight Le permite especificar el tamaño de la barra. Se trata de unidades de rejilla, p. unit(1, "cm").

  • direction especifica la dirección de la guía, "horizontal" o "vertical".

En Sección 10.3.2 introdujimos la función guides() que se utiliza para configurar leyendas y ejes personalizados. Cuando se aplica a escalas de colores, le permite crear leyendas personalizadas como estas:

base + guides(colour = guide_colourbar(reverse = TRUE))
base + guides(colour = guide_colourbar(barheight = unit(2, "cm")))
base + guides(colour = guide_colourbar(direction = "horizontal"))

Una forma alternativa de lograr el mismo objetivo es especificar el argumento guide para la función de escala. Estas dos especificaciones de la gráfica son idénticas:

base + guides(colour = guide_colourbar(reverse = TRUE))
base + scale_colour_continuous(guide = guide_colourbar(reverse = TRUE))

Puede obtener más información sobre las funciones de la guía en Sección 14.5.

11.3 Escalas de colores discretas

En muchas situaciones se producen escalas de color y relleno discretas. Un ejemplo típico es un gráfico de barras que codifica tanto la posición como el relleno en la misma variable. Muchos conceptos de ?sec-color-continuous se aplican a escalas discretas, que ilustraremos usando este gráfico de barras como ejemplo:

df <- data.frame(x = c("a", "b", "c", "d"), y = c(3, 4, 1, 2))
bars <- ggplot(df, aes(x, y, fill = x)) + 
  geom_bar(stat = "identity") + 
  labs(x = NULL, y = NULL) +
  theme(legend.position = "none")

La escala predeterminada para colores discretos es scale_fill_discrete() que a su vez por defecto es scale_fill_hue() entonces estas son gráficas idénticas:

bars
bars + scale_fill_discrete()
bars + scale_fill_hue()

Esta escala predeterminada tiene algunas limitaciones (que se analizan en breve), por lo que comenzaremos analizando las herramientas para producir paletas discretas más bonitas.

11.3.1 Básculas de cerveza

scale_colour_brewer() es una escala de color discreta que, junto con la escala analógica continua scale_colour_distiller() y analógico agrupado scale_colour_fermenter()—utiliza colores “ColorBrewer” cuidadosamente seleccionados tomados de https://colorbrewer2.org/. Estos colores han sido diseñados para funcionar bien en una amplia variedad de situaciones, aunque la atención se centra en los mapas, por lo que los colores tienden a funcionar mejor cuando se muestran en áreas grandes. Hay muchas opciones diferentes:

RColorBrewer::display.brewer.all()

El primer grupo de paletas son escalas secuenciales que son útiles cuando la escala discreta está ordenada (por ejemplo, clasificar datos) y están disponibles para datos continuos usando scale_colour_distiller(). Para datos categóricos desordenados, las paletas de mayor interés son las del segundo grupo. ‘Set1’ y ‘Dark2’ son particularmente buenos para los puntos, y ‘Set2’, ‘Pastel1’, ‘Pastel2’ y ‘Accent’ funciona bien para áreas.

bars + scale_fill_brewer(palette = "Set1")
bars + scale_fill_brewer(palette = "Set2")
bars + scale_fill_brewer(palette = "Accent")

Tenga en cuenta que ninguna paleta es uniformemente buena para todos los propósitos. Los diagramas de dispersión suelen utilizar marcadores de diagrama pequeños y los colores brillantes tienden a funcionar mejor que los sutiles:

# gráfico de dispersión
df <- data.frame(
  x = 1:3 + runif(30), 
  y = runif(30), 
  z = c("a", "b", "c")
)
point <- ggplot(df, aes(x, y)) +
  geom_point(aes(colour = z))  + 
  theme(legend.position = "none") +
  labs(x = NULL, y = NULL)

# tres paletas
point + scale_colour_brewer(palette = "Set1")
point + scale_colour_brewer(palette = "Set2")  
point + scale_colour_brewer(palette = "Pastel1")

Los gráficos de barras suelen contener grandes manchas de color y los colores brillantes pueden resultar abrumadores. Los colores sutiles tienden a funcionar mejor en esta situación:

# diagrama de barras
df <- data.frame(x = 1:3, y = 3:1, z = c("a", "b", "c"))
area <- ggplot(df, aes(x, y)) + 
  geom_bar(aes(fill = z), stat = "identity") + 
  theme(legend.position = "none") +
  labs(x = NULL, y = NULL)

# tres paletas
area + scale_fill_brewer(palette = "Set1")
area + scale_fill_brewer(palette = "Set2")
area + scale_fill_brewer(palette = "Pastel1")

11.3.2 Tono y escalas de grises

El esquema de color predeterminado selecciona tonos espaciados uniformemente alrededor de la rueda de colores HCL. Esto funciona bien con hasta ocho colores, pero después resulta difícil distinguir los diferentes colores. Puedes controlar el croma y la luminancia predeterminados, y el rango de tonos, con los argumentos h, c y l:

bars
bars + scale_fill_hue(c = 40)
bars + scale_fill_hue(h = c(180, 300))

Hay algunos problemas con este esquema predeterminado. Una es que, a diferencia de muchas de las otras paletas analizadas en este capítulo, no son seguras para los daltónicos (lo que se analiza en ?sec-color-blindness). La segunda es que, debido a que todos los colores tienen la misma luminancia y croma, todos aparecen con un tono de gris idéntico cuando se imprimen en blanco y negro. Si desea imprimir una escala de color discreta en blanco y negro, es mejor usar explícitamente scale_fill_grey() que asigna datos discretos a grises, de claro a oscuro:

bars + scale_fill_grey()
bars + scale_fill_grey(start = 0.5, end = 1)
bars + scale_fill_grey(start = 0, end = 0.5)

11.3.3 Básculas paletizadoras

Otra alternativa la proporciona el paquete Paletteer, discutido anteriormente en relación con las escalas de color continuas en Sección 11.2.1. Al proporcionar una interfaz unificada que abarca una gran cantidad de paquetes, Paletteer permite elegir entre una gran cantidad de paletas de manera consistente:

bars + paletteer::scale_fill_paletteer_d("rtist::vangogh")
bars + paletteer::scale_fill_paletteer_d("colorBlindness::paletteMartin")
bars + paletteer::scale_fill_paletteer_d("wesanderson::FantasticFox1")

11.3.4 Balanzas manuales

Si ninguna de las paletas preexistentes es adecuada, o si tiene sus propios colores preferidos, puede usar scale_fill_manual() para configurar los colores manualmente. Esto puede resultar útil si desea elegir colores que resalten una estructura de agrupación secundaria o llamen la atención sobre diferentes comparaciones:

bars + 
  scale_fill_manual(
    values = c("sienna1", "sienna4", "hotpink1", "hotpink4")
  )

bars + 
  scale_fill_manual(
    values = c("tomato1", "tomato2", "tomato3", "tomato4")
  )

bars + 
  scale_fill_manual(
    values = c("grey", "black", "grey", "grey")
  )

También puede utilizar un vector con nombre para especificar los colores que se asignarán a cada nivel, lo que le permite especificar los niveles en el orden que desee:

bars + 
  scale_fill_manual(
    values = c(
      "d" = "grey",
      "c" = "grey",
      "b" = "black",
      "a" = "grey"
    )
  )

Para obtener más información sobre básculas manuales, consulte Sección 12.5.

11.3.5 Límites, rupturas y etiquetas

Los límites de escala para escalas de colores discretas se pueden establecer usando el argumento limits para el argumento de escala, o usando la función auxiliar lims(). Esto puede ser importante cuando la misma variable se representa en diferentes gráficos y desea asegurarse de que los colores sean consistentes en todos los gráficos. Para demostrar esto, ampliaremos el ejemplo de Sección 10.1.1. El color representa el tipo de combustible, que puede ser rregular, etanol, ddiesel, premium o cgas natural comprimido.

mpg_99 <- mpg %>% filter(year == 1999)
mpg_08 <- mpg %>% filter(year == 2008)

base_99 <- ggplot(mpg_99, aes(displ, hwy, colour = fl)) + geom_point() 
base_08 <- ggplot(mpg_08, aes(displ, hwy, colour = fl)) + geom_point() 

base_99
base_08

Cada gráfica tiene sentido por sí sola, pero la comparación visual entre las dos es difícil. Los límites de los ejes son diferentes y, debido a que en los datos de 1998 sólo se representan los combustibles regular, premium y diésel, los colores se asignan de manera inconsistente. Para garantizar un mapeo consistente para la estética del color, podemos usar lims() para establecer los límites manualmente. Como se analiza en Sección 10.1.1, toma pares nombre-valor como entrada, donde el nombre especifica la estética y el valor especifica los límites:

base_99 + lims(colour = c("c", "d", "e", "p", "r"))
base_08 + lims(colour = c("c", "d", "e", "p", "r"))

Lo bueno de lims() es que podemos establecer límites para múltiples estéticas a la vez. Para garantizar que x, y y color utilicen límites consistentes, podemos hacer esto:

base_99 + 
  lims(
    x = c(1, 7), 
    y = c(10, 45), 
    colour = c("c", "d", "e", "p", "r")
  )

base_08 + 
  lims(
    x = c(1, 7), 
    y = c(10, 45), 
    colour = c("c", "d", "e", "p", "r")
  )

Hay dos limitaciones potenciales para estas gráficas. En primer lugar, si bien establecer los límites de la escala garantiza que los colores se representen de manera idéntica en ambos gráficos, también significa que el gráfico de los datos de 1999 muestra etiquetas para los cinco tipos de combustible, a pesar de que no se utilizaban etanol ni gas natural comprimido. En ese tiempo. Podemos solucionar esto configurando manualmente los saltos de escala, asegurándonos de que solo los tipos de combustible que aparecen en los datos se muestren en la leyenda. La segunda limitación es que las etiquetas no son particularmente útiles, lo que podemos solucionar especificándolas manualmente. Al configurar múltiples propiedades de una sola escala, puede ser más útil personalizar usando los argumentos de la función de escala en lugar de usar la función auxiliar lims():

base_99 + 
  scale_color_discrete(
    limits = c("c", "d", "e", "p", "r"), 
    breaks = c("d", "p", "r"),
    labels = c("diesel", "premium", "regular")
  )

Sin embargo, no hay nada que le impida usar lims() para controlar los límites estéticos de la posición, mientras usa scale_colour_discrete() para ejercer un control más detallado sobre la estética del color:

base_99 + 
  lims(x = c(1, 7), y = c(10, 45)) +
  scale_color_discrete(
    limits = c("c", "d", "e", "p", "r"), 
    breaks = c("d", "p", "r"),
    labels = c("diesel", "premium", "regular")
  )

base_08 + 
  lims(x = c(1, 7), y = c(10, 45)) +
  scale_color_discrete(
    limits = c("c", "d", "e", "p", "r"), 
    labels = c("compressed", "diesel", "ethanol", "premium", "regular")
  )

11.3.6 Leyendas

Las leyendas para escalas de colores discretas se pueden personalizar usando el argumento guide de la función de escala o con la función auxiliar guides(), descrita en ?sec-guide-colorbar. Para una escala discreta, la leyenda predeterminada muestra claves individuales en una tabla, que se puede personalizar usando guide_legend(). Las opciones más útiles son:

  • nrow o ncol que especifican las dimensiones de la mesa. byrow controla cómo se llena la tabla: FALSE la llena por columna (el valor predeterminado), TRUE la llena por fila.

    base <- ggplot(mpg, aes(drv, fill = factor(cyl))) + geom_bar() 
    
    base
    base + guides(fill = guide_legend(ncol = 2))
    base + guides(fill = guide_legend(ncol = 2, byrow = TRUE))

  • reverse invierte el orden de las claves:

    base
    base + guides(fill = guide_legend(reverse = TRUE))

  • override.aes es útil cuando desea que los elementos de la leyenda se muestren de manera diferente a las geomas del gráfico. Esto suele ser necesario cuando se ha utilizado transparencia o tamaño para tratar un sobretrazado moderado y también se ha utilizado color en el trazado.

    base <- ggplot(mpg, aes(displ, hwy, colour = drv)) +
      geom_point(size = 4, alpha = .2, stroke = 0)
    
    base + guides(colour = guide_legend())
    base + guides(colour = guide_legend(override.aes = list(alpha = 1)))

  • keywidth y keyheight (junto con default.unit) le permite especificar el tamaño de las claves. Se trata de unidades de rejilla, p. unit(1, "cm").

Puedes conocer más sobre las guías en Sección 14.5.

11.4 Escalas de colores agrupadas

Las escalas de colores también vienen en versiones agrupadas. La escala predeterminada es scale_fill_binned() que a su vez es scale_fill_steps(). Al igual que con las escalas de posición agrupadas analizadas en Sección 10.4, estas escalas tienen un argumento n.breaks que controla el número de categorías de color discretas creadas por la escala. Contrariamente a la intuición, debido a que el sistema visual humano es muy bueno para detectar bordes, esto a veces puede hacer que un gradiente de color continuo sea más fácil de percibir:

erupt + scale_fill_binned()
erupt + scale_fill_steps()
erupt + scale_fill_steps(n.breaks = 8)

En otros aspectos, scale_fill_steps() es análogo a scale_fill_gradient() y te permite construir tus propios degradados de dos colores. También hay una variante de tres colores scale_fill_steps2() y una variante de escala de n colores scale_fill_stepsn() que se comportan de manera similar a sus contrapartes continuas:

erupt + scale_fill_steps(low = "grey", high = "brown")
erupt + 
  scale_fill_steps2(
    low = "grey", 
    mid = "white", 
    high = "brown", 
    midpoint = .02
  )
erupt + scale_fill_stepsn(n.breaks = 12, colours = terrain.colors(12))

Las paletas viridis se pueden usar de la misma manera, llamando directamente a las funciones generadoras de paletas al especificar el argumento colors para scale_fill_stepsn():

erupt + scale_fill_stepsn(n.breaks = 9, colours = viridis::viridis(9))
erupt + scale_fill_stepsn(n.breaks = 9, colours = viridis::magma(9))
erupt + scale_fill_stepsn(n.breaks = 9, colours = viridis::inferno(9))

Alternativamente, también existe un análogo de cerveza para básculas agrupadas, y se llama scale_fill_fermenter():

erupt + scale_fill_fermenter(n.breaks = 9)
erupt + scale_fill_fermenter(n.breaks = 9, palette = "Oranges")
erupt + scale_fill_fermenter(n.breaks = 9, palette = "PuOr")

Tenga en cuenta que, al igual que el discreto scale_fill_brewer()—y a diferencia del continuo scale_fill_distiller()—la función agrupada scale_fill_fermenter() no interpola entre los colores de la cafetera, y si configura n.breaks Si es mayor que el número de colores de la paleta, aparecerá un mensaje de advertencia y algunos colores no se mostrarán.

11.4.1 Limits, breaks, and labels

In most respects setting limits, breaks, and labels for a binned scale follows the same logic that applies to continuous scales (Sección 10.1.4 and Sección 11.2.4). Like a continuous scale, the limits argument is typically a numeric vector of length two specifying the end points, breaks is a numeric vector specifying the break points, and labels is a character vector specifying the labels. All three arguments will accept functions as input (discussed in Sección 10.1). The main difference between binned and continuous scales is that the breaks argument defines the edges of the bins rather than simply specifying locations of tick marks. Límites, rupturas y etiquetas

En la mayoría de los aspectos, establecer límites, interrupciones y etiquetas para una escala agrupada sigue la misma lógica que se aplica a las escalas continuas (Sección 10.1.4 y ?sec-color-continuous-limits). Al igual que una escala continua, el argumento limits suele ser un vector numérico de longitud dos que especifica los puntos finales, breaks es un vector numérico que especifica los puntos de interrupción y labels es un vector de caracteres que especifica las etiquetas. Los tres argumentos aceptarán funciones como entrada (discutidas en Sección 10.1). La principal diferencia entre escalas agrupadas y continuas es que el argumento breaks define los bordes de las ubicaciones en lugar de simplemente especificar las ubicaciones de las marcas.

11.4.2 Leyendas

La leyenda predeterminada para escalas agrupadas utiliza pasos de color en lugar de una barra de colores y se puede personalizar usando la función guide_coloursteps(). Una leyenda de paso de color muestra el área entre cortes como un único color constante, en lugar de mostrar un degradado de color que varía suavemente a lo largo de la barra. Los argumentos de guide_coloursteps() en su mayoría reflejan los de guide_colourbar() (ver Sección 11.2.5), con argumentos adicionales que son relevantes para escalas agrupadas:

  • show.limits indica si los valores deben mostrarse en los extremos de la barra de color escalonada, de forma análoga al argumento correspondiente en guide_bins()

    base <- ggplot(mpg, aes(cyl, displ, colour = hwy)) +
      geom_point(size = 2) +
      scale_color_binned()
    
    base 
    base + guides(colour = guide_coloursteps(show.limits = TRUE))

  • ticks es una variable lógica que indica si las marcas deben mostrarse junto a las etiquetas de leyenda (el valor predeterminado es NULL, en cuyo caso el valor se hereda de la escala)

  • even.steps es una variable lógica que indica si los contenedores deben estar espaciados uniformemente (el valor predeterminado es TRUE) o su tamaño debe ser proporcional a su frecuencia en los datos.

11.5 Escalas de color de fecha y hora

Cuando una estética de color se asigna a un tipo de fecha/hora, ggplot2 usa scale_colour_date() o scale_colour_datetime() para especificar la escala. Están diseñados para manejar datos de fechas, de forma análoga a las escalas de fechas analizadas en Sección 10.2. Estas escalas tienen argumentos date_breaks y date_labels que hacen que sea un poco más fácil trabajar con estos datos, como lo ilustra el siguiente ejemplo ligeramente artificial:

base <- ggplot(economics, aes(psavert, uempmed, colour = date)) + 
  geom_point() 

base
base + 
  scale_colour_date(
    date_breaks = "142 months", 
    date_labels = "%b %Y"
  )

11.6 Escalas alfa

Las escalas alfa asignan la transparencia de una sombra a un valor en los datos. No suelen ser útiles, pero pueden ser una manera conveniente de restar importancia visual a observaciones menos importantes. scale_alpha() es un alias para scale_alpha_continuous() ya que ese es el uso más común de alpha y ahorra un poco de escritura. A continuación se muestra un ejemplo de una escala alfa utilizando los datos de las erupciones:

ggplot(faithfuld, aes(waiting, eruptions, alpha = density)) +
  geom_raster(fill = "maroon") +
  scale_x_continuous(expand = c(0, 0)) + 
  scale_y_continuous(expand = c(0, 0))

11.7 Posición de la leyenda

Una serie de configuraciones que afectan la visualización general de las leyendas se controlan a través del sistema de temas. Aprenderás más sobre eso en Sección 17.2, pero por ahora, todo lo que necesitas saber es que modificas la configuración del tema con la función theme().

La posición y justificación de las leyendas están controladas por la configuración del tema legend.position, que toma valores “right”, “left”, “top”, “bottom” o “none” (sin leyenda).

base <- ggplot(toy, aes(up, up)) + 
  geom_point(aes(colour = txt), size = 3) + 
  xlab(NULL) + 
  ylab(NULL)

base + theme(legend.position = "left")
base + theme(legend.position = "right") # el valor por defecto
base + theme(legend.position = "bottom")
base + theme(legend.position = "none")

Cambiar entre izquierda/derecha y arriba/abajo modifica cómo se distribuyen las claves en cada leyenda (horizontal o verticalmente) y cómo se apilan varias leyendas (horizontal o verticalmente). Si es necesario, puedes ajustar esas opciones de forma independiente:

  • legend.direction: disposición de elementos en leyendas (“horizontal” o “vertical”).

  • legend.box: disposición de múltiples leyendas (“horizontal” o “vertical”).

  • legend.box.just: justificación de cada leyenda dentro del cuadro delimitador general, cuando hay varias leyendas (“top”, “bottom”, “left”, o “right”).

Alternativamente, si hay mucho espacio en blanco en su gráfica, es posible que desee colocar la leyenda dentro de la gráfica. Puede hacer esto estableciendo legend.position en un vector numérico de longitud dos. Los números representan una ubicación relativa en el área del panel: c(0, 1) es la esquina superior izquierda y c(1, 0) es la esquina inferior derecha. Usted controla a qué esquina de la leyenda se refiere legend.position con legend.justification, que se especifica de manera similar. Desafortunadamente, colocar la leyenda exactamente donde la desea requiere mucho ensayo y error.

base <- ggplot(toy, aes(up, up)) + 
  geom_point(aes(colour = txt), size = 3)

base + 
  theme(
    legend.position = c(0, 1), 
    legend.justification = c(0, 1)
  )
#> Warning: A numeric `legend.position` argument in `theme()` was deprecated in ggplot2
#> 3.5.0.
#> ℹ Please use the `legend.position.inside` argument of `theme()` instead.

base + 
  theme(
    legend.position = c(0.5, 0.5), 
    legend.justification = c(0.5, 0.5)
  )

base + 
  theme(
    legend.position = c(1, 0), 
    legend.justification = c(1, 0)
  )

También hay un margen alrededor de las leyendas, que puedes suprimir con legend.margin = unit(0, "mm").

Azzalini, A., y A. W. Bowman. 1990. «A look at some data on the Old Faithful geyser.» Applied Statistics 39: 357-65.
Garnier, Simon. 2018. viridis: Default Color Maps from ’matplotlib’. https://CRAN.R-project.org/package=viridis.
Hvitfeldt, Emil. 2020. paletteer: Comprehensive Collection of Color Palettes. https://CRAN.R-project.org/package=paletteer.
Ou, Jianhong. 2021. colorBlindness: Safe Color Set for Color Blindness. https://CRAN.R-project.org/package=colorBlindness.
Pedersen, Thomas Lin, y Fabio Crameri. 2020. scico: Colour Palettes Based on the Scientific Colour-Maps. https://CRAN.R-project.org/package=scico.
Wickham, Charlotte. 2018. munsell: Utilities for Using Munsell Colours. https://CRAN.R-project.org/package=munsell.
Zeileis, Achim, Kurt Hornik, y Paul Murrell. 2008. «Escaping RGBland: Selecting Colors for Statistical Graphics». Computational Statistics & Data Analysis. http://statmath.wu-wien.ac.at/~zeileis/papers/Zeileis+Hornik+Murrell-2008.pdf.