taiyun / corrplot

A visual exploratory tool on correlation matrix
https://github.com/taiyun/corrplot
Other
316 stars 86 forks source link

the colour palette is white-blue and not the expected red-white-blue #148

Closed Sophia409 closed 3 years ago

Sophia409 commented 5 years ago

Same question as these guys(https://github.com/taiyun/corrplot/issues/122#issuecomment-371790268).The range is correct, but the colour palette is white-blue and not the expected red-white-blue corrplot(corr=cor(CorOb.av.exp),method = "color",order = "hclust",tl.col="black",addrect=4,addCoef.col = "grey",cl.lim = c(min, 1), is.corr=FALSE)

image @taiyun @yihui @COS-Editor

joseale2310 commented 4 years ago

Hi! I am still having this issue (version 0.84 in R 3.6.2). I wrote in #122 also. It seems that no matter what values are in the matrix, if they are positive it will use the first half of colors. If the matrix has negative values, it will use the second half. So cl.lim is not distributing the color palette to the min and max values of the matrix, the function is assigning them directly to negative and positive values. Does it have to do with the function

 assign.color <- function(dat = DAT, color = col) {
        newcorr <- (dat + 1)/2
        newcorr[newcorr <= 0] <- 0
        newcorr[newcorr >= 1] <- 1 - 1e-16
        color[floor(newcorr * length(color)) + 1]
    }

Or maybe when the corr matrix is being transformed somehow here when is.corr = F?

if (!is.corr) {
        c_max <- max(corr, na.rm = TRUE)
        c_min <- min(corr, na.rm = TRUE)
        if (c_max <= 0) {
            intercept <- -cl.lim[2]
            zoom <- 1/(diff(cl.lim))
        }
        else if (c_min >= 0) {
            intercept <- -cl.lim[1]
            zoom <- 1/(diff(cl.lim))
        }
        else {
            stopifnot(c_max * c_min < 0)
            stopifnot(c_min < 0 && c_max > 0)
            intercept <- 0
            zoom <- 1/max(abs(cl.lim))
        }
        if (zoom == Inf) {
            stopifnot(cl.lim[1] == 0 && cl.lim[2] == 0)
            zoom <- 0
        }
        corr <- (intercept + corr) * zoom
    }

Examples of the issue:

col1 <- colorRampPalette(c("red","white", "blue"))
ran <- round(matrix(runif(225, 100,200), 15))
corrplot(ran, is.corr = FALSE, method = "square", col = col1(200))

That will give only positive (blue to white) colors. However, if the matrix is negative:

col1 <- colorRampPalette(c("red","white", "blue"))
ran <- round(matrix(runif(225, -200,-100), 15))
corrplot(ran, is.corr = FALSE, method = "square", col = col1(200))

It will show only white to red colors. cl.lim option does not work when is.corr = F, it always gives and error, even when giving values in range of the matrix:

col1 <- colorRampPalette(c("red","white", "blue"))
ran <- round(matrix(runif(225, 100,200), 15))
corrplot(ran, is.corr = FALSE, method = "square", col = col1(200), cl.lim = c(125,175))
Error in corrplot(ran, is.corr = FALSE, method = "square", col = col1(200),  : 
  color limits should cover matrix
joseale2310 commented 4 years ago

Changing the part of the function that transforms the matrix if is.corr = F to a min-max normalization (min is -1 and max is 1) solves the colouring issue:

if (!is.corr) {
    c_max <- max(corr, na.rm = TRUE)
    c_min <- min(corr, na.rm = TRUE)

    slope <- 2/(c_max - c_min)
    inter <- 1- slope * c_max
    corr <- slope*corr + inter
  }

But the legend is messed up and the values inside the matrix are the new min-max normalized values. Rplot01

joseale2310 commented 4 years ago

Ok, @Sophia409 going through the code it seems there is a parameter called "full_col" that appears in the version 0.84 in github, but when you install it in R through install.packages, it seems it is not there. You can install the version in github by installing devtools and then the package directly from here

install.packages("devtools")
install_github("taiyun/corrplot")

@taiyun It seems CRAN did not get the actual version that there is in your latest github.

taiyun commented 3 years ago

Solved now. Please try the latest version on github.