I'm in the process of converting number matrices to color matrices; however, the colors aren't displaying correctly, e.g., the color matrix displays the incorrect color relative to the assigned number in the number matrix.
I first assigned colors to a set of numerical values.
cols <- c(
'0' = "#FFFFFF",
'1' = "#9AFC7F",
'2' = "#77F255",
'3' = "#60DF3D",
'4' = "#49C925",
'5' = "#37B215",
'6' = "#219900"
)
Then generated a couple matrices.
Map1 <- read.table(text="
1 1 1 0 0 1 1 0 2 1
1 1 1 1 0 1 1 1 2 1
0 1 1 0 2 2 1 1 1 1
0 1 1 1 1 1 2 1 2 2
1 1 2 1 1 1 1 1 2 2
1 1 1 1 1 2 2 1 2 2
1 2 0 1 1 2 1 2 1 2
0 2 2 0 1 1 1 1 1 1
0 1 1 0 0 1 2 2 1 0
0 1 1 1 1 1 1 1 1 0
")
Map2 <- read.table(text="
1 2 1 1 1 1 1 0 2 1
1 1 1 1 1 1 1 1 1 1
0 2 1 1 1 2 1 1 1 1
0 0 1 2 2 1 2 2 3 2
0 1 2 2 1 1 2 2 2 2
1 1 0 2 1 1 3 2 3 3
1 1 2 2 1 2 2 2 1 2
0 1 2 2 1 2 2 2 1 2
1 1 2 1 1 1 1 2 1 1
1 1 1 1 1 1 1 1 1 1
")
After plotting the matrices, I find the colors don't match up with the value they should have been assigned.
image(1:nrow(Map1), 1:ncol(Map1), t(apply(Map1, 2, rev)), col=cols, xaxt='n', yaxt='n', ann=FALSE, bty='n', asp = 1)
image(1:nrow(Map2), 1:ncol(Map2), t(apply(Map2, 2, rev)), col=cols, xaxt='n', yaxt='n', ann=FALSE, bty='n', asp = 1)
I've been stumped trying to figure out why the numbers and colors aren't aligning. Plotting the numbers assigned in to cols
generates the correct sequence.
d <- read.table(text="0 1 2 3 4 5 6")
image(1:nrow(d), 1:ncol(d), t(apply(d, 2, rev)), col=cols, xaxt='n', yaxt='n', ann=FALSE, bty='n', asp = 1)
There aren't any 6
values in the first number matrix, so there shouldn't be any dark squares in the first color matrix. It appears as though values of 2
are given the color assigned to 6
in the first matrix, and 3
to 6
in the second.
Adding a 3
into the first number matrix seems to shift the other values down the color scale, i.e., the largest number in the matrix is assigned the darkest color, rather than the color it was assigned in cols
.
Map1.2 <- read.table(text="
1 1 1 0 0 1 1 0 2 1
1 1 1 1 0 1 1 1 2 1
3 1 1 0 2 2 1 1 1 1
0 1 1 1 1 1 2 1 2 2
1 1 2 1 1 1 1 1 2 2
1 1 1 1 1 2 2 1 2 2
1 2 0 1 1 2 1 2 1 2
0 2 2 0 1 1 1 1 1 1
0 1 1 0 0 1 2 2 1 0
0 1 1 1 1 1 1 1 1 0
")
image(1:nrow(Map1), 1:ncol(Map1), t(apply(Map1, 2, rev)), col=cols, xaxt='n', yaxt='n', ann=FALSE, bty='n', asp = 1)
image(1:nrow(Map1.2), 1:ncol(Map1.2), t(apply(Map1.2, 2, rev)), col=cols, xaxt='n', yaxt='n', ann=FALSE, bty='n', asp = 1)
The only difference between the number matrices which generated these two color matrices is the 0
in the first column, third row was changed to a 3
.
I think you're having a problem with mapping of numbers to characters. If x
is numeric then cols[x]
will reference the vector by number, not by name ...
I changed the first colour to red (instead of white) to make the values a little more obvious.
cols <- c('0' = "#FF0000",'1' = "#9AFC7F",'2' = "#77F255",'3' = "#60DF3D",
'4' = "#49C925",'5' = "#37B215",'6' = "#219900")
Check colour definitions:
plot(0:6,rep(1,7),col=cols,pch=16,cex=5,ylim=c(0.9,1.1),
axes=FALSE,ann=FALSE,mar=c(0,0,0,0))
m <- matrix(0:5,ncol=2)
image(m,col=cols[m]) ## index by number
Now index by name:
image(m,col=cols[as.character(m)])
The problem, as you noted, is that the colours are being determined by the values in the matrix. This is because image()
automatically spreads the values in the matrix across the range of colours provided. To spread them as you intended, you need to set the zlim
argument to cover the length of your vector. Take a look at the help page (?image
) for more details about this.
So, to correct your image, you can do the following:
cols <- c("#FFFFFF", "#9AFC7F", "#77F255", "#60DF3D", "#49C925", "#37B215", "#219900")
Map1 <- read.table(text="
1 1 1 0 0 1 1 0 2 1
1 1 1 1 0 1 1 1 2 1
0 1 1 0 2 2 1 1 1 1
0 1 1 1 1 1 2 1 2 2
1 1 2 1 1 1 1 1 2 2
1 1 1 1 1 2 2 1 2 2
1 2 0 1 1 2 1 2 1 2
0 2 2 0 1 1 1 1 1 1
0 1 1 0 0 1 2 2 1 0
0 1 1 1 1 1 1 1 1 0
")
image(1:ncol(Map1), 1:nrow(Map1), t(sapply(Map1, rev)),
zlim = c(0, length(cols) - 1), # This will spread you numbers properly
col = cols, xaxt='n', yaxt='n', ann=FALSE, bty='n', asp = 1)
Here's another example:
cols <- c("#FFFFFF", "#9AFC7F", "#77F255", "#60DF3D", "#49C925", "#37B215", "#219900")
set.seed(123)
d <- as.data.frame(matrix(sample(c(0, 1, 5, 6), 20, replace = TRUE), ncol = 4))
image(1:ncol(d), 1:nrow(d), t(sapply(d, rev)),
zlim = c(0, length(cols) - 1),
col = cols, xaxt='n', yaxt='n', ann=FALSE, bty='n', asp = 1)
Some side notes:
cols
) does not require names. The order is sufficient.zlim = c(1, length(cols))
.apply(Map1, 2, rev)
with sapply(Map1, rev)
.1:ncol()
and 1:nrow()
, as the original order did not work with a rectangular table.If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With