jinworks / CellChat

R toolkit for inference, visualization and analysis of cell-cell communication from single-cell and spatially resolved transcriptomics
GNU General Public License v3.0
277 stars 45 forks source link

Discrete heatmap colour mapping for continuous values #196

Open at-robins opened 3 months ago

at-robins commented 3 months ago

Hi, and thanks for providing the CellChat package. We are using it at a large scale as part of an automated pipeline. However, from time to time a very specific error pops up, that has been described previously in issue 36 and issue 124 of the original CellChat repo, yet this bug has never been fixed.

Error

Error: Relative strength: cannot map colors to some of the levels: 0

The error is originating in our case from analysis.R/netAnalysis_signalingRole_heatmap (but can potentially occur in other functions too; see below). The following warning precedes the error:

There are 100 unique colors in the vector col and 100 unique values in
matrix. Heatmap() will treat it as an exact discrete one-to-one mapping.
If this is not what you want, slightly change the number of colors, e.g. by
adding one more color or removing a color.

Reason

This error happens as a concrete range of colours (in this case 100) are passed to ComplexHeatmap, while in fact the underlying values are continuous. The only reason this actually works most of the time is the fact that if the number of unique heatmap values is not exactly equal to the number of colours supplied, ComplexHeatmap interpolates a continuous colour scale from the supplied colours. However, in the rare case that the number of unique values is exactly equal to the specified number of colours (in this function again 100), the described error is triggered.

Potential fix

The colour mapping passed to ComplexHeatmap should be changed to a colour mapping function as described in the documentation and the according examples. This should be done for every function that calls ComplexHeatmap, not only analysis.R/netAnalysis_signalingRole_heatmap. You can check out my fork, where I fixed the bug specifically for the aforementioned function.

koelschnj commented 2 months ago

I experienced the same issue, and this worked perfectly for me! Thank you for detailing this so well.

All I performed was passing the same source code for netAnalysis_signalingRole_heatmap() to make a new function after changing 100 colors to 102 in the line you mentioned within your fork to increase the number of generated colors:

"color.heatmap.use = (grDevices::colorRampPalette((RColorBrewer::brewer.pal(n = 9, name = color.heatmap))))(102)"