Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
MFreidank opened this issue Mar 2, 2018 · 19 comments
Closed

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

MFreidank opened this issue Mar 2, 2018 · 19 comments

Comments

@MFreidank
Copy link

MFreidank commented Mar 2, 2018

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
Copy link

@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
Copy link
Owner

taiyun commented Mar 6, 2018

@lars20070

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

@lars20070
Copy link

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

@MFreidank MFreidank reopened this Mar 9, 2018
@lars20070
Copy link

lars20070 commented Mar 9, 2018

@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
Copy link
Collaborator

vsimko commented May 17, 2018

fixed in pull request #127

@vsimko vsimko closed this as completed May 17, 2018
vsimko added a commit to vsimko/corrplot that referenced this issue May 17, 2018
vsimko added a commit that referenced this issue May 17, 2018
@MFreidank
Copy link
Author

Thank you @vsimko :)

@JarretChao
Copy link

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
Copy link

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
Copy link

JarretChao commented Jan 11, 2019 via email

@lars20070
Copy link

Problem persists with corrplot 0.84 in R 3.2.2.

@CodeInTheSkies
Copy link

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
Copy link

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
Copy link

xyw1 commented Nov 18, 2019

@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
Copy link

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
Copy link

JarretChao commented Apr 21, 2020 via email

@taiyun
Copy link
Owner

taiyun commented May 11, 2021

Solved now. Please try the latest version on github.

@AtomicNess123
Copy link

cl.lim is now col.lim. Correct?

@zh9118
Copy link

zh9118 commented Sep 13, 2024

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.

@paulitikka
Copy link

paulitikka commented Nov 14, 2024

I have a work-around to this. One needs to put the (color legend) value limits in the corrplot high enough, preferably above -1 or 1 in the positive side and make sure that the negative value's limit is the same (but abs) in magnitude in the positive side.

Something like:

#So these are the key lines, so as not to blur values between -1 and 0:
heps=abs(round((min(resulta1)),1)); hepsa=abs(round((max(resulta1)),1))
heps2=abs(round((max(resulta1)-0.01),3));heps3=abs(round((min(resulta1)+0.01),3));

if (hepsa-heps >=0 ) {resulta1[resulta1 >= heps2] = hepsa; resulta1[resulta1 <= -heps3] = -hepsa; heps=hepsa} else
if (hepsa-heps < 0 ) {resulta1[resulta1 <= -heps3] = -heps; resulta1[resulta1 >= heps2] = heps}

#Check if you have just positive or negative values or both:
col=colorRampPalette(c('blue', 'white','orange'), alpha = TRUE)(150)
if (neg=='no') {col=colorRampPalette(c( 'white','orange'), alpha = TRUE)(150)} else if (neg=='yes')
{col=colorRampPalette(c('blue', 'white'), alpha = TRUE)(150)} else {col=col}

#Now just to plot you need some values for corrplot, including corr=F if you do not have values exactly between -1 and 1:
path="C:/Users/patati/Documents/GitHub/new/"; setwd(path)
jpeg(paste("Heatmap of high",date, mn,neg,".jpg"), width = width, height = height, quality = 100,pointsize = 14, res=300);
order="original"; range='orig'; type='full'; method='color'; cl.offset=20;
cl.length=7;cl.cex = 1.25;pch.cex=1.25;pch=2;cl.pos = 'r'; corr=FALSE

corrplot(as.matrix(resulta1), type = type, order = order,method=method, p.mat=as.matrix(p.mat.a1), tl.col = "black",
cl.cex = cl.cex, pch.cex=pch.cex, pch.col='black',pch=pch,
sig.level = c(0.05),cl.pos = cl.pos, insig = "label_sig", cl.offset=cl.offset,cl.length=cl.length, #.001, .05, .2
tl.srt = 90, diag = TRUE,col=col,is.corr = corr,col.lim=c(-heps,heps))

dev.off()

I hope this helped.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests