I expect "1" to be white, but it is red:
Xmat <- matrix(c(rep(1, 20), c(-10:9)+0.01), ncol = 2, byrow = FALSE)
dataVals <- sort(unique(as.numeric(Xmat)))
vals <- dataVals # seq(0, max(dataVals), min(diff(dataVals)))
ncolorlevels <- length(vals)
mypalette <- colorRampPalette(
c("#006837", "#f0df0b", "#f20b0b", "#000099"))(ncolorlevels)
names(mypalette) <- vals
mypalette
ind <- which(names(mypalette) == "1")
mypalette[ind] <- "#FFFFFF"
mypalette
image(t(Xmat), col = mypalette, xlab = "Columns", ylab = "Rows", xaxt = "n", yaxt = "n")
Why?
If I use Xmat <- matrix(c(rep(1, 20), c(-10:9)), ncol = 2, byrow = FALSE)
without +0.01
everything is fine. mypalette
looks fine to me:
mypalette
... 1 ...
... "#FFFFFF" ...
Concerning encoding - perhaps not the problem:
Xmat[1, 1] == as.integer(names(mypalette)[ind])
[1] TRUE # correct
all.equal(Xmat[1, 1], as.integer(names(mypalette)[ind]))
[1] TRUE # correct
Xmat == 1 # all correct
[,1] [,2]
[1,] TRUE FALSE
[2,] TRUE FALSE
[3,] TRUE FALSE
...
Better use breaks
, since image()
rather uses numerical binning instead of assigning colors based on their names or exact values. Something like this, so 1
falls within the white bin:
> mids <- head(vals, -1) + diff(vals)/2
> (breaks <- c(vals[1] - 0.5, mids, tail(vals, 1) + 0.5))
[1] -10.490 -9.490 -8.490 -7.490 -6.490 -5.490 -4.490 -3.490
[9] -2.490 -1.490 -0.490 0.505 1.005 1.510 2.510 3.510
[17] 4.510 5.510 6.510 7.510 8.510 9.510
>
> par(mar=c(3, 3, 2, 2))
> image(t(Xmat), col=mypal, breaks=breaks)
Data:
> Xmat <- matrix(c(rep(1, 20), c(-10:9) + 0.01), ncol=2, byrow=FALSE)
>
> vals <- sort(unique(as.vector(Xmat)))
> mypal <- colorRampPalette(
+ c("#006837", "#f0df0b", "#f20b0b", "#000099"))(length(vals)) |>
+ setNames(vals)
> mypal['1'] <- '#FFFFFF'