2012-08-02 11 views
5

Estoy intentando crear un gráfico donde el color representa la combinación de varios valores. En el siguiente ejemplo, estoy aplicando valores crecientes para el rojo asociado con la coordenada xy valores crecientes para el azul en asociación con la coordenada y.¿Cómo se pueden mezclar 2 o más paletas de colores para mostrar un valor de color combinado?

#required function 'val2col' from: http://www.menugget.blogspot.de/2011/09/converting-values-to-color-levels.html 

val2col<-function(z, zlim, col = heat.colors(12), breaks){ 
if(!missing(breaks)){ 
    if(length(breaks) != (length(col)+1)){stop("must have one more break than colour")} 
} 
if(missing(breaks) & !missing(zlim)){ 
    zlim[2] <- zlim[2]+c(zlim[2]-zlim[1])*(1E-3)#adds a bit to the range in both directions 
    zlim[1] <- zlim[1]-c(zlim[2]-zlim[1])*(1E-3) 
    breaks <- seq(zlim[1], zlim[2], length.out=(length(col)+1)) 
} 
if(missing(breaks) & missing(zlim)){ 
    zlim <- range(z, na.rm=TRUE) 
    zlim[2] <- zlim[2]+c(zlim[2]-zlim[1])*(1E-3)#adds a bit to the range in both directions 
    zlim[1] <- zlim[1]-c(zlim[2]-zlim[1])*(1E-3) 
    breaks <- seq(zlim[1], zlim[2], length.out=(length(col)+1)) 
} 
colorlevels <- col[((as.vector(z)-breaks[1])/(range(breaks)[2]-range(breaks)[1]))*(length(breaks)-1)+1] # assign colors to heights for each point 
colorlevels 
} 


#data 
x <- seq(100) 
y <- seq(100) 
grd <- expand.grid(x=x,y=y) 

#assign colors to grd levels 
pal1 <- colorRampPalette(c("white", rgb(1,0,0)), space = "rgb") 
col1 <- val2col(x, col=pal1(10)) 
pal2 <- colorRampPalette(c("white", rgb(0,0,1)), space = "rgb") 
col2 <- val2col(y, col=pal2(10)) 
col3 <- NA*seq(nrow(grd)) 
for(i in seq(nrow(grd))){ 
    xpos <- grd$x[i] 
    ypos <- grd$y[i] 
    coltmp <- (col2rgb(col1[xpos])/2) + (col2rgb(col2[ypos])/2) 
    col3[i] <- rgb(coltmp[1], coltmp[2], coltmp[3], maxColorValue = 255) 
} 

    #plot 
png("2_color_scales.png", width=6, height=4, units="in", res=200) 
layout(matrix(c(1,2,3), nrow=1, ncol=3), widths=c(4,1,1), heights=4, respect=T) 
par(mar=c(4,4,2,2)) 
plot(grd,col=col3, pch=19) 
par(mar=c(4,0,2,5)) 
image(x=1, y=x, z=t(as.matrix(x)), col=pal1(10), xaxt="n", yaxt="n", xlab="", ylab="") 
box() 
axis(4) 
mtext("x", side=4, line=3, cex=0.7) 
par(mar=c(4,0,2,5)) 
image(x=1, y=y, z=t(as.matrix(y)), col=pal2(10), xaxt="n", yaxt="n", xlab="", ylab="") 
box() 
axis(4) 
mtext("y", side=4, line=3, cex=0.7) 
dev.off() 

enter image description here

El resultado es técnicamente correcto en que cuando x = 1 e y = 10, la mezcla de colores "blanco" y "azul", respectivamente, devuelve el tono más claro de azul. Sin embargo, preferiría que esta posición se viera tan "azul" como el azul más oscuro de la barra de color y. Me imagino que esto requeriría que uno use transparencia para valores más bajos en lugar del color blanco. ¿Alguien tiene sugerencias sobre cómo se podría lograr esto? Agregar dos colores, incluida su transparencia, me supera ... ¿Pensé que uno podría usar el valor de transparencia como ponderación en el paso de mezcla?

Gracias por su ayuda.

Respuesta

6

Como estoy más familiarizado con ggplot, mostraré una solución usando ggplot. Esto tiene el beneficio adicional de que, dado que el código ggplot es muy simple, podemos centrar la discusión en el tema de la gestión del color, en lugar del código R.

  1. de inicio mediante el uso de expand.grid para crear una trama de datos dat que contiene la cuadrícula de valores de entrada de rojo y azul.
  2. Utilice la función rgb() para crear la combinación de colores y asígnelo a dat$mix
  3. Parcela.

El código:

dat <- expand.grid(blue=seq(0, 100, by=10), red=seq(0, 100, by=10)) 
dat <- within(dat, mix <- rgb(green=0, red=red, blue=blue, maxColorValue=100)) 

library(ggplot2) 
ggplot(dat, aes(x=red, y=blue)) + 
    geom_tile(aes(fill=mix), color="white") + 
    scale_fill_identity() 

enter image description here


Usted notará que la escala de colores es diferente de lo que usted sugiere, pero posiblemente más intuitiva.

Al mezclar la luz, la ausencia de cualquier color produce negro, y la presencia de todos los colores produce blanco.

Esto está claramente indicado por la trama, que me resulta bastante intuitiva de interpretar.

+0

+1 Gracias Andre - es bastante intuitivo. Código muy compacto también. ¿Le sería fácil agregar las escalas de color correspondientes a dicho diagrama? Supongo que pensé que un modelo de color sustractivo Cyan-Magenta-Amarillo (es decir, igual al blanco cuando no se aplican colores) podría ser mejor para imprimir que un modelo de color RGB aditivo. –

+0

@Marcinthebox Mi sospecha es que cualquier intento de mezclar dos elementos en una sola escala de colores será bastante difícil de interpretar. ¿Qué estás tratando de trazar? ¿Puedes usar alguna otra estética, por ejemplo, tamaño o forma para indicar un segundo elemento? – Andrie

+0

Estaba pensando en usar una gráfica así en la presentación de tres concentraciones de nutrientes en aguas superficiales (es decir, espacialmente). Esperaba que ese mapa fuera una forma intuitiva de ver estos patrones espaciales. Imaginé que la clave de color correspondiente sería un tri-gráfico que muestra el gradiente de color para las 3 concentraciones de nutrientes. –

Cuestiones relacionadas