2011-09-14 41 views
6

Sto cercando un modo più elegante per fare questo:Creare una scala di colori arcobaleno sulla base di un vettore, in ordine di quel vettore

#Create Dataset 
set.seed(1) 
x <- runif(100) 
y <- runif(100) 
z <- y*x 

#Assign colors, based on z vector  
Data <- data.frame(Order=1:length(z),z=z) 
Data <- Data[order(Data$z),] 
Data$col <- rainbow(length(z)) 
orderedcolors <- Data[order(Data$Order),'col'] 

#Plot x vs y, colored by z 
plot(x,y,col=orderedcolors) 

Fondamentalmente, voglio assegnare un colore ad ogni punto nel vettore z e voglio che quei colori varino su una scala arcobaleno dai valori più bassi di z ai valori più alti.

risposta

10

Non hai detto come gestire i legami, ma sarebbe questo lavoro:

plot(x,y,col = rainbow(length(z))[rank(z)]) 

che sembra generare la stessa uscita per me, mettendo in pratica i colori in ordine di z utilizzando indicizzazione e rank .

6

Si può solo creare l'arcobaleno di colori e poi indice in modo creativo

orderedcolors2 <- rainbow(length(z))[order(order(z))] 

che dà lo stesso insieme di colori come vostro codice originale

> identical(orderedcolors2, orderedcolors) 
[1] TRUE 
+2

Tu dici 'ordine (ordine())', io dico 'rango()'. Pomodoro, tom-ah-to. – joran

+0

Quando ho visto la tua risposta, mi sono reso conto che 'rank()' aveva più senso concettualmente; Non ci ho pensato! –

12

La soluzione assegna il colore al rango dei tuoi dati. Se è quello che avevi in ​​mente, allora è grandioso.

Tuttavia, se davvero aveva in mente che il valore di dei dati dovrebbe determinare il colore, allora ecco una soluzione:

In primo luogo, il tuo codice:

#Create Dataset 
set.seed(1) 
x <- runif(100) 
y <- runif(100) 
z <- y*x 

par(mfrow=c(1,2)) 
#Assign colors, based on z vector  
Data <- data.frame(Order=1:length(z),z=z) 
Data <- Data[order(Data$z),] 
Data$col <- rainbow(length(z)) 
orderedcolors <- Data[order(Data$Order),'col'] 
plot(x,y,col=orderedcolors, main="Yours") 

successivo, il mio codice. Io uso la funzione colorRamp che crea una funzione che interpola linearmente tra i colori dati l'input della funzione. Poiché l'input su colorRamp deve essere compreso nell'intervallo [0; 1], in primo luogo ho definisco un po funzione di supporto range01 scalabile di dati tra 0 e 1. Infine, dal momento che colorRamp dà uscita in valori RGB, io uso apply e rgb per ottenere questi valori tornare in colori che plot capisce:

range01 <- function(x)(x-min(x))/diff(range(x)) 
rainbow(7) 
cRamp <- function(x){ 
    cols <- colorRamp(rainbow(7))(range01(x)) 
    apply(cols, 1, function(xt)rgb(xt[1], xt[2], xt[3], maxColorValue=255)) 
} 

#Plot x vs y, colored by z 
plot(x,y,col=cRamp(z), main="Mine") 

I risultati. Si noti la diversa distribuzione a colori vicino agli assi.

enter image description here

Problemi correlati