2012-08-02 11 views
5

Sto provando a creare un grafico in cui il colore rappresenta la combinazione di più valori. Nell'esempio seguente, sto applicando valori crescenti per il rosso associati alla coordinata x e valori crescenti per il blu associati alla coordinata y.Come si possono mescolare 2 o più tavolozze di colori per mostrare un valore di colore combinato

#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

Il risultato è tecnicamente corretto dal fatto che quando x = 1 ey = 10, la miscelazione dei colori "bianco" e "blu", rispettivamente, restituisce la tonalità più chiara di blu. Tuttavia, preferirei che questa posizione fosse "blu" come il blu più scuro della barra dei colori y. Immagino che ciò richiederebbe l'uso della trasparenza per valori inferiori piuttosto che il colore bianco. Qualcuno ha suggerimenti su come questo potrebbe essere realizzato? L'aggiunta di due colori, inclusa la trasparenza, è al di là di me ... Pensavo che si potesse utilizzare il valore di trasparenza come ponderazione nel passaggio di miscelazione?

Grazie per il vostro aiuto.

risposta

6

Poiché ho più familiarità con ggplot, mostrerò una soluzione utilizzando ggplot. Questo ha il vantaggio che, dal momento che il codice ggplot è molto semplice, possiamo concentrare la discussione sull'argomento della gestione del colore, piuttosto che sul codice R.

  1. Avviare utilizzando expand.grid per creare un frame di dati dat contenente la griglia di valori di ingresso rossi e blu.
  2. utilizzare la funzione rgb() per creare il mix di colori, e assegnarlo a dat$mix
  3. Plot.

Il codice:

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


Si noterà che la scala colore è diverso da quello che lei ha suggerito, ma forse più intuitivo.

Quando si mescola la luce, l'assenza di qualsiasi colore diventa nera e la presenza di tutti i colori diventa bianca.

Questo è chiaramente indicato dalla trama, che trovo piuttosto intuitiva da interpretare.

+0

+1 Grazie Andre - è abbastanza intuitivo. Anche codice molto compatto. Sarebbe facile per te aggiungere le corrispondenti scale di colori a tale trama? Suppongo di aver pensato che un modello di colore sottrattivo di tipo ciano-magenta-giallo (cioè che equivale al bianco quando non vengono applicati i colori) potrebbe essere migliore per la stampa rispetto a un modello di colore RGB aggiuntivo. –

+0

@Marcinthebox Il mio sospetto è che qualsiasi tentativo di mixare due elementi in un'unica scala di colori sarà piuttosto difficile da interpretare. Cosa stai cercando di tracciare? Puoi usare qualche altra estetica, ad es. dimensione o forma per indicare un secondo elemento? – Andrie

+0

Stavo pensando di usare una tale trama nella presentazione di tre concentrazioni di nutrienti nelle acque superficiali (cioè spazialmente). Speravo che una mappa del genere potesse essere un modo intuitivo per vedere questi schemi spaziali. Ho immaginato che la corrispondente chiave di colore fosse una trama tridimensionale che mostra il gradiente di colore per le 3 concentrazioni di nutrienti. –