python - brewer - ¿Qué es una paleta "buena" para colores divergentes en R?(o: ¿se pueden combinar viridis y magma?)
viridis python (4)
Estoy interesado en tener una paleta de colores divergentes "buena". Obviamente, uno podría usar solo rojo, blanco y azul:
img <- function(obj, nam) {
image(1:length(obj), 1, as.matrix(1:length(obj)), col=obj,
main = nam, ylab = "", xaxt = "n", yaxt = "n", bty = "n")
}
rwb <- colorRampPalette(colors = c("red", "white", "blue"))
img(rwb(100), "red-white-blue")
Como recientemente me enamoré de las paletas de colores viridis , esperaba combinar viridis y magma para formar colores tan divergentes (por supuesto, las personas ciegas al color solo verían el valor absoluto del color, pero a veces eso está bien).
Cuando intenté combinar viridis y magma, descubrí que no "terminan" (o "comienzan") en el mismo lugar, así que obtengo algo como esto (estoy usando R, pero probablemente esto sería lo mismo para usuarios de python):
library(viridis)
img(c(rev(viridis(100, begin = 0)), magma(100, begin = 0)), "magma-viridis")
Podemos ver que cuando está cerca de cero, viridis es púrpura, mientras que el magma es negro. Me gustaría que ambos comenzaran en (más o menos) el mismo lugar, así que intenté usar 0.3 como punto de partida:
img(c(rev(viridis(100, begin = 0.3)), magma(100, begin = 0.3)), "-viridis-magma(0.3)")
Esto es realmente mejor, pero me pregunto si hay una mejor solución.
(También estoy "etiquetando" a los usuarios de Python, ya que viridis es originalmente de matplotlib
, por lo que alguien que lo use puede saber de tal solución)
¡Gracias!
El paquete scico
(Paletas para R basado en los mapas de color científicos) tiene varias paletas divergentes buenas que son perceptualmente uniformes y seguras para el color (por ejemplo, vik
, roma
, berlin
).
También disponible para Python, MatLab, GMT, QGIS, Plotly, Paraview, VisIt, Mathematica, Surfer, d3, etc. here
Documento : Crameri, F. (2018), Diagnóstico geodinámico, visualización científica y StagLab 3.0, Geosci. Modelo Dev., 11, 2541-2562, doi:10.5194/gmd-11-2541-2018
Edit : scico
está ahora en CRAN. Ejecute install.packages(''scico'')
para instalar
# install.packages("devtools")
# devtools::install_github("thomasp85/scico")
library(scico)
scico_palette_show()
Otro gran paquete es cmocean (Python). Sus oce están disponibles en R a través del paquete pals
o el paquete de oce .
Documento : Thyng, KM, Greene, CA, Hetland, RD, Zimmerle, HM y DiMarco, SF (2016). Los verdaderos colores de la oceanografía. Oceanografía, 29 (3), 10, http://dx.doi.org/10.5670/oceanog.2016.66 .
Charla : PLOTCON 2016: Kristen Thyng, mapas personalizados para su campo .
### install.packages("devtools")
### devtools::install_github("kwstat/pals")
library(pals)
pal.bands(ocean.balance, ocean.delta, ocean.curl, main = "cmocean")
Creado en 2018-10-15 por el paquete reprex (v0.2.1.9000)
La biblioteca RColorBrewer
proporciona hermosas paletas para = <13 colores. Por ejemplo, la paleta BrBG
muestra colores divergentes de marrón a verde.
library(RColorBrewer)
display.brewer.pal(11, "BrBG")
Que se puede expandir a una paleta menos informativa mediante la creación de paletas desde y hacia un color de punto medio.
brbg <- brewer.pal(11, "BrBG")
cols <- c(colorRampPalette(c(brbg[1], brbg[6]))(51),
colorRampPalette(c(brbg[6], brbg[11]))(51)[-1])
Analógicamente, utilizando su elección de paletas de viridis
y magma
, puede intentar encontrar una similitud entre ellas. Este podría ser un punto, donde unir las paletas espalda con espalda.
select.col <- function(cols1, cols2){
x <- col2rgb(cols1)
y <- col2rgb(cols2)
sim <- which.min(colSums(abs(x[,ncol(x)] - y)))
message(paste("Your palette will be", sim, "colors shorter."))
cols.x <- apply(x, 2, function(temp) rgb(t(temp)/255))
cols.y <- apply(y[,sim:ncol(y)], 2, function(temp) rgb(t(temp)/255))
return(c(cols.x,cols.y))
}
img(select.col(rev(viridis(100,0)),magma(100,0)), "")
# Your palette will be 16 colors shorter.
Ya ha habido algunas sugerencias buenas y útiles, pero permítanme agregar algunas observaciones:
- Las paletas viridis y magma son paletas secuenciales con múltiples tonalidades. Por lo tanto, a lo largo de la escala aumentas de colores muy claros a colores más bien oscuros. Al mismo tiempo, aumenta el color y el tono cambia de amarillo a azul (ya sea a través de verde o rojo).
- Las paletas divergentes se pueden crear combinando dos paletas secuenciales. Normalmente, te unes a ellos en los colores claros y luego los dejas divergir a diferentes colores oscuros.
- Generalmente, uno usa paletas secuenciales de un solo tono que divergen de un gris claro neutro a dos colores oscuros diferentes. Sin embargo, se debe tener en cuenta que los diferentes "brazos" de la paleta están equilibrados con respecto a la luminancia (luz-oscuridad) y el croma (colorfuness).
Por lo tanto, combinar magma y viridis no funciona bien. Podría dejarlos divergir de un color amarillento similar pero divergiría a colores azulados similares. También con los tonos cambiantes, sería más difícil juzgar en qué brazo de la paleta se encuentra.
Como lo mencionaron otros, ColorBrewer.org proporciona buenas paletas divergentes. El enfoque de Moreland también es útil. Otra solución general es nuestra función diverge_hcl()
en el paquete de colorspace
. Se describe en un documento de CSDA ( http://dx.doi.org/10.1016/j.csda.2008.11.033 ) y otras recomendaciones orientadas a la meteorología, pero aplicables más allá, están disponibles en un documento de BAMS ( http://dx.doi.org/10.1175/BAMS-D-13-00155.1 ).
La ventaja de nuestra solución en el espacio HCL (hue-chroma-luminance) es que puede interpretar las coordenadas con relativa facilidad. Se necesita algo de práctica pero no es tan opaco como otras soluciones. También proporcionamos un GUI hclwizard()
(ver más abajo) que ayuda a comprender la importancia de las diferentes coordenadas.
La mayoría de las paletas en la pregunta y las otras respuestas se pueden emparejar bastante cerca por diverge_hcl()
siempre que los dos matices (argumento h
), el chroma máximo ( c
), y la luminancia mínima / máxima ( l
) se elijan apropiadamente. Además, uno puede tener que modificar el argumento de power
que controla la rapidez con la que aumentan el croma y la luminancia, respectivamente. Típicamente, el croma se agrega bastante rápido ( power[1] < 1
) mientras que la luminancia se incrementa más lentamente ( power[2] > 1
).
La paleta "frío-cálido" de Moreland, por ejemplo, utiliza un tono azul ( h = 250
) y rojo ( h = 10
) pero con un contraste de luminancia relativamente pequeño ( l = 37
vs. l = 88
):
coolwarm_hcl <- colorspace::diverge_hcl(11,
h = c(250, 10), c = 100, l = c(37, 88), power = c(0.7, 1.7))
que se ve bastante similar (ver más abajo) a:
coolwarm <- Rgnuplot:::GpdivergingColormap(seq(0, 1, length.out = 11),
rgb1 = colorspace::sRGB( 0.230, 0.299, 0.754),
rgb2 = colorspace::sRGB( 0.706, 0.016, 0.150),
outColorspace = "sRGB")
coolwarm[coolwarm > 1] <- 1
coolwarm <- rgb(coolwarm[, 1], coolwarm[, 2], coolwarm[, 3])
En contraste, la paleta BrBG de ColorBrewer.org tiene un contraste de luminancia mucho más alto ( l = 20
vs. l = 95
):
brbg <- rev(RColorBrewer::brewer.pal(11, "BrBG"))
brbg_hcl <- colorspace::diverge_hcl(11,
h = c(180, 50), c = 80, l = c(20, 95), power = c(0.7, 1.3))
Las paletas resultantes se comparan a continuación con la versión basada en HCL debajo del original. Usted ve que estos no son idénticos sino más bien cercanos. En el lado derecho también he combinado viridis y plasma con paletas basadas en HCL.
Si prefiere la paleta frío-cálido o BrBG, puede depender de su gusto personal pero también, lo que es más importante, de lo que desea resaltar en su visualización. El bajo contraste de luminancia en frío-calor será más útil si el signo de la desviación es lo más importante. Un alto contraste de luminancia será más útil si desea resaltar el tamaño de las desviaciones (extremas). Una guía más práctica está en el documento BAMS, mientras que los cálculos se explican con más detalle en el documento CSDA.
El resto del código de replicación para la figura anterior es:
viridis <- viridis::viridis(11)
viridis_hcl <- colorspace::heat_hcl(11,
h = c(300, 75), c = c(35, 95), l = c(15, 90), power = c(0.8, 1.2))
plasma <- viridis::plasma(11)
plasma_hcl <- colorspace::heat_hcl(11,
h = c(-100, 100), c = c(60, 100), l = c(15, 95), power = c(2, 0.9))
pal <- function(col, border = "transparent") {
n <- length(col)
plot(0, 0, type="n", xlim = c(0, 1), ylim = c(0, 1),
axes = FALSE, xlab = "", ylab = "")
rect(0:(n-1)/n, 0, 1:n/n, 1, col = col, border = border)
}
par(mar = rep(0, 4), mfrow = c(4, 2))
pal(coolwarm)
pal(viridis)
pal(coolwarm_hcl)
pal(viridis_hcl)
pal(brbg)
pal(plasma)
pal(brbg_hcl)
pal(plasma_hcl)
Puede explorar nuestros colores propuestos interactivamente en una aplicación brillante: http://hclwizard.org:64230/hclwizard/ . Para los usuarios de R, también puede iniciar la aplicación brillante localmente en su computadora (que se ejecuta algo más rápido que desde nuestro servidor) o puede ejecutar una versión de Tcl / Tk (que es aún más rápida):
colorspace::hclwizard(gui = "shiny")
colorspace::hclwizard(gui = "tcltk")
Si desea comprender cómo se ven las rutas de las paletas en las coordenadas RGB y HCL, el colorspace::specplot()
es útil. Véase, por ejemplo, colorspace::specplot(coolwarm)
.
La propuesta de Kenneth Moreland me parece bastante útil. Se implementa en el paquete Rgnuplot
( install.packages("Rgnuplot")
es suficiente, no es necesario instalar el gráfico GNU). Para usarlo como los mapas de color habituales, necesita convertirlo de esta manera:
cool_warm <- function(n) {
colormap <- Rgnuplot:::GpdivergingColormap(seq(0,1,length.out=n),
rgb1 = colorspace::sRGB( 0.230, 0.299, 0.754),
rgb2 = colorspace::sRGB( 0.706, 0.016, 0.150),
outColorspace = "sRGB")
colormap[colormap>1] <- 1 # sometimes values are slightly larger than 1
colormap <- grDevices::rgb(colormap[,1], colormap[,2], colormap[,3])
colormap
}
img(red_blue_diverging_colormap(500), "Cool-warm, (Moreland 2009)")
Así es como se ve en acción en comparación con un "ColorBrew" de RColorBrewer interpolado: