taiyun / corrplot

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

Adjusting cl.lim does not change range of colors #122

Closed MFreidank closed 6 years ago

MFreidank commented 6 years ago

Hello,

when the cl.lim parameter is restricted to a smaller range e.g. (0, 1) one would expect that for a given color palette, e.g. col3 <- colorRampPalette(c("red", "white", "blue")) all colors are still used to visualize points in the new range. However, the default range (-1, 1) is still used, which leads people to prepend unused colors in order to visualize things in their desired color range, as in: https://stackoverflow.com/a/30744267/9434598 https://stackoverflow.com/a/38876691/9434598

This is problematic if e.g. all correlation values are high, because one needs to prepend a large amount of colors in this way to see differences in the correlations.

I have ideas for a fix and some candidate code ready, but would first like to get your opinion on whether this is an issue you would like to address or whether I am overlooking something.

I hope we can collaborate on this and find a good solution for everyone.

Best, MFreidank

lars20070 commented 6 years ago

@taiyun @caijun @vsimko We have been using corrplot for a while now. Thanks for the great package.

We now came across datasets with a very narrow range of correlations, for example (0.8 ... 0.97). The current API does not allow us to adjust the colour pallet correctly. Could we suggest some changes in a pull request? Thanks.

taiyun commented 6 years ago

@lars20070

corrplot(abs(cor(mtcars)), cl.lim=c(0,1))
corrplot(50*abs(cor(mtcars)), cl.lim=c(0,50), is.corr=FALSE)
lars20070 commented 6 years ago

@taiyun is.corr=FALSE solves our problem. Thanks! (@MFreidank please close the issue.)

lars20070 commented 6 years ago

@taiyun Sorry. We still have problems. Here an example.

d <- 0.2*abs(cor(mtcars))+0.6
colmat <- colorRampPalette(c("red", "white", "blue"))
corrplot(d, cl.lim=c(min(d),max(d)), col = colmat(200), is.corr=FALSE)

The range (0.61, 0.8) is correct, but the colour palette is white-blue and not the expected red-white-blue.

screen shot 2018-03-09 at 12 47 34
vsimko commented 6 years ago

fixed in pull request #127

MFreidank commented 6 years ago

Thank you @vsimko :)

JarretChao commented 5 years ago

cl<- c("#56A36C","#5E8579","#77C34F","#2E68AA","#7E884F","#7C8489","#4fB3A4","#F5B977") col2 <- colorRampPalette(cl) corrplot(sim, method="color", type="full",is.corr = FALSE,col = col2(8) ,cl.lim = c(0.8,1)) ## sim is correlation matrix this way i got a legend with four color (this arguement: col=col2(8)) , my correlation range is 0.8-1, and this method give a color by 0.05, so I got four color

timedreamer commented 5 years ago

Hi, I still have this problem. How can I fix this?

The version is corrplot_0.85. Thank you!

@taiyun Sorry. We still have problems. Here an example.

d <- 0.2*abs(cor(mtcars))+0.6
colmat <- colorRampPalette(c("red", "white", "blue"))
corrplot(d, cl.lim=c(min(d),max(d)), col = colmat(200), is.corr=FALSE)

The range (0.61, 0.8) is correct, but the colour palette is white-blue and not the expected red-white-blue.

screen shot 2018-03-09 at 12 47 34
JarretChao commented 5 years ago

Sorry, it seems only accept two color if cl.lim is positive. 2019-01-11 08:43:02>"Ji Huang" 写道:

Hi, I still have this problem. How can I fix this?

The version is corrplot_0.85. Thank you!

@taiyun Sorry. We still have problems. Here an example.

d <- 0.2*abs(cor(mtcars))+0.6 colmat <- colorRampPalette(c("red", "white", "blue")) corrplot(d, cl.lim=c(min(d),max(d)), col = colmat(200), is.corr=FALSE)

The range (0.61, 0.8) is correct, but the colour palette is white-blue and not the expected red-white-blue.

— You are receiving this because you commented. Reply to this email directly, view it on GitHub, or mute the thread.

lars20070 commented 5 years ago

Problem persists with corrplot 0.84 in R 3.2.2.

CodeInTheSkies commented 5 years ago

Hello there, I am facing the same problem as @lars20070. Any improvements or solutions for this issue?

@lars20070 , did you find a workaround, or alternatives? Would be great to hear about it!

Sophia409 commented 5 years ago

Same question as these guys.The range is correct, but the colour palette is white-blue and not the expected red-white-blue. @taiyun

xyw1 commented 4 years ago

@lars20070

corrplot(abs(cor(mtcars)), cl.lim=c(0,1))
corrplot(50*abs(cor(mtcars)), cl.lim=c(0,50), is.corr=FALSE)

Thanks!

joseale2310 commented 4 years ago

Hi! I am still having this issue (version 0.84 in R 3.6.2). 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
JarretChao commented 4 years ago

Hi! Actually, I finally used the geom_tile function from the ggplot2 package instead. It is more friendly to adjusting the correlation coefficient interval.

2020-04-20 18:18:49"joseale2310" notifications@github.com写道:

Hi! I am still having this issue (version 0.84 in R 3.6.2). 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

— You are receiving this because you commented. Reply to this email directly, view it on GitHub, or unsubscribe.

taiyun commented 3 years ago

Solved now. Please try the latest version on github.

AtomicNess123 commented 1 year ago

cl.lim is now col.lim. Correct?

zh9118 commented 1 month ago

It does not seem solved. I still have this issue happening. The color was scaled based on [-1,1], rather than the col.lim even setting is.corr FALSE.

corrplot(corr, method = "color", shade.col = NA, addCoef.col = "black", tl.col = "black", tl.srt = 90, type = "full", tl.pos = "lt", is.corr = FALSE, order = "original", col.lim = c(-0.4, 1), col = COL2('PiYG'))

A quick test, seems when the corr has values < 0, it's not working. If all values >=0, it worked fine.

And if I set parameter transKeepSign = F, it worked.