2014-01-07 4 views
6

Ich verwende den Befehl image, um eine Matrix zu plotten, die Matrix enthält einige NA Werte. Ich verwende image wieSo weisen Sie einer NA in einem Bild eine bestimmte Farbe zu

image(figData, zlim = zRange, col = colors, useRaster=TRUE) 

zRange kleiner ist als die tatsächliche Reichweite des figData. Ich bin mit dem Top-colormap in der folgenden Gruppe, die mit Rot-Grün-Farbwahrnehmung Mangel kompatibel:

http://www.mathworks.com/matlabcentral/fx_files/31761/6/thumbnail_184481.jpg

ich für NA Werte in figData eine bestimmte Farbe auswählen mag, die außerhalb ist colors (zB , gray). NA Werte werden nun dem letzten Element von colors (white) zugeordnet und daher kann ich sie nicht von Werten außerhalb des Bereichs unterscheiden.

Idealerweise möchte ich eine Lösung, die funktioniert, egal welche Farbpalette ich verwende.

Ich möchte etwas ähnlich wie die na.color Option in heatmap.2, wie kann ich es tun? Ich bin bereit, den image Quellcode zu ändern, um dies zu erreichen, aber image scheint die rasterImage Funktion zu nennen, deren Quellcode ich nicht finden kann.


Nach Jealie Antwort akzeptieren ich bin auch hier den Code zu berücksichtigen unterschiedlich für Werte unterhalb und oberhalb des Bereichs:

image.nan <- function(z, zlim, col, na.color='gray', outside.below.color='black', outside.above.color='white',...) 
{ 
    zstep <- (zlim[2] - zlim[1])/length(col); # step in the color palette 
    newz.below.outside <- zlim[1] - zstep # new z for values below zlim 
    newz.above.outside <- zlim[2] + zstep # new z for values above zlim 
    newz.na <- zlim[2] + 2 * zstep # new z for NA 

    z[which(z<zlim[1])] <- newz.below.outside # we affect newz.below.outside 
    z[which(z>zlim[2])] <- newz.above.outside # we affect newz.above.outside 
    z[which(is.na(z>zlim[2]))] <- newz.na # same for newz.na 

    zlim[1] <- zlim[1] - zstep # extend lower limit to include below value 
    zlim[2] <- zlim[2] + 2 * zstep # extend top limit to include the two new values above and na 

    col <- c(outside.below.color, col, outside.above.color, na.color) # we construct the new color range by including: na.color and na.outside 

    image(z=z, zlim=zlim, col=col, ...) # we finally call image(...) 
} 

Antwort

2

Kleine Korrektur: außerhalb Werte werden nicht auf das letzte Element von col abgebildet , aber sie werden überhaupt nicht geplottet (und keine Farbe sieht weiß aus ...).

Andernfalls, um Ihre Frage zu beantworten, ist die einfachste Möglichkeit, einen Wrapper um mit zwei neuen Argumenten zu schreiben: na.color und outside.color. Hier ist mein Vorschlag, der standardmäßig gray für NA-Werte und white für Werte außerhalb zlim:

my.image <- function(figData, zlim, col, na.color='gray', outside.color='white', ...) 
{ 
    newz.na <- zlim[2]+(zlim[2]-zlim[1])/length(col) # new z for NA 
    newz.outside <- zlim[2]+2*(zlim[2]-zlim[1])/length(col) # new z for values outside zlim 

    figData$z[which(is.na(figData$z>zlim[2]))] <- newz.na # we affect newz.outside 
    figData$z[which(figData$z<zlim[1] | figData$z>zlim[2])] <- newz.outside # same for newz.na 


    zlim[2] <- zlim[2]+2*(zlim[2]-zlim[1])/length(col) # we finally extend the z limits to include the two new values 

    col <- c(col, na.color, outside.color) # we construct the new color range by including: na.color and outside.color 

    image(figData, zlim=zlim, col=col, ...) # we finally call image(...) 
} 
+0

Vielen Dank für die Klärung, Lösung und Codebeispiel. Jetzt verstehe ich, warum einige Bereiche, von denen ich erwartet habe, schwarz zu sein, wo tatsächlich weiß, umgeben von einer Linie, die ich vermute, der Übergang von weißer Farbe zu transparent ist. Um dies zu vermeiden, habe ich eine neue Version Ihres Codes erstellt, einschließlich der Unterscheidung zwischen unter und über den Grenzwerten. Ich füge es am Ende meiner bearbeiteten Frage ein. – nesuribe

2

Da die Farbintervalle wie (*bottom*, *top*] definiert sind, die Werte in z, die gleich sind ZGRENZ [1] wird mit einfärben outside.below.color (weil der Bereich von outside.below.color (*zlim[1] - zstep* , *zlim[1]* ] ist).

Die folgende Version behebt diesen Fehler:

image.nan.better <- function(z, zlim, col, na.color='gray', outside.below.color='black', outside.above.color='white',...) 
{ 
     zstep <- (zlim[2] - zlim[1])/length(col); # step in the color palette 
     newz.below.outside <- zlim[1] - 2 * zstep # new z for values below zlim 
     newz.above.outside <- zlim[2] + zstep # new z for values above zlim 
     newz.na <- zlim[2] + 2 * zstep # new z for NA 

     z[which(z<zlim[1])] <- newz.below.outside # we affect newz.below.outside 
     z[which(z>zlim[2])] <- newz.above.outside # we affect newz.above.outside 
     z[which(is.na(z>zlim[2]))] <- newz.na # same for newz.na 

     zlim[1] <- zlim[1] - 2 * zstep # extend lower limit to include below value 
     zlim[2] <- zlim[2] + 2 * zstep # extend top limit to include the two new values above and na 

     col <- c(outside.below.color, col[1], col, outside.above.color, na.color) #correct by including col[1] at bottom of range 

     image(z=z, zlim=zlim, col=col, ...) # we finally call image(...) 
} 

vergleichen:

f = matrix(abs(rnorm(300)),nrow=50) 
f[which(f>1)]=1 

f[44,4] = 0 
f[41,4] = NA 
f[42,4] = NA 
f[43,4] = NA 
f[44,3] = -1 
f[44,5] = 2 

image(as.matrix(f),col=c('green3','green2','blue1','blue3'),zlim=c(0,1)) 

image.nan(as.matrix(f),col=c('green3','green2','blue1','blue3'),zlim=c(0,1),outside.below.color='red',outside.above.color='brown',na.color='yellow') 

image.nan.better(as.matrix(f),col=c('green3','green2','blue1','blue3'),zlim=c(0,1),outside.below.color='red',outside.above.color='brown',na.color='yellow') 
+0

Vielen Dank dafür! – aaiezza

+0

Kleiner Tweak, um Prototyp zu funktionieren, um es einfacher zu machen: image.nan.better <- Funktion (Matte, zlim = Bereich (Matte, na.rm = T), col = heat.colors (100), na.color = 'grau', outside.below.color = 'schwarz', outside.above.color = 'white', ...) { – Chris

Verwandte Themen