Home > database >  Heatmap with multiple conditions and custom ranges
Heatmap with multiple conditions and custom ranges

Time:07-01

I want to build custom heatmap with color ranges based on multiple conditions.

I found a similar post that focuses on enter image description here

However, I want the heatmap to have multiple color gradients based on the given conditions.

For ex, the conditions are below:

If the values are < 0.4 -> Green

If the values are > 0.5 -> Red

Values that lie between 0.4 and 0.5 then -> Grey

These colors would be having their own gradient scale. Higher the value in a condition darker the shade of that color.

CodePudding user response:

Maybe something like this could be an option, using a custom color palette.

pal <- c("#238b45",
         "#74c476",
         "#bae4b3",
         "#edf8e9",
         "#cccccc",
         "#fee5d9",
         "#fcae91",
         "#fb6a4a",
         "#cb181d")

ggplot(data=tt_melt, aes(x=columns, y=rows, fill=performance)) 
  geom_tile() 
  geom_text(aes(label=performance)) 
  scale_fill_gradientn(colors=pal,breaks=c(0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0)) 
  labs(title = '') 
  coord_equal() 
  theme_minimal(base_size = 12) 
  theme(legend.position="none")

enter image description here


Update: Random test data and fixed gradient scale limits. By adding limits=c(0,1) to gradient scale, the palette is fixed from 0 to 1 regardless of input data range. Makes images comparable.

library(dplyr)
library(tidyr)

pal <- c("#238b45",
         "#74c476",
         "#bae4b3",
         "#edf8e9",
         "#cccccc",
         "#fee5d9",
         "#fcae91",
         "#fb6a4a",
         "#cb181d")
breaks <- c(0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0)

# randomly generate data
m <- as.data.frame(matrix(sample(seq(0,1,0.01),36),nrow=6)) %>%
  mutate(rows=factor(row_number())) %>%
  tidyr::pivot_longer(-rows,names_to="columns",values_to="performance")

# limits used in gradient scale
ggplot(data=m, aes(x=columns, y=rows, fill=performance)) 
  geom_tile() 
  geom_text(aes(label=performance)) 
  scale_fill_gradientn(colors=pal, breaks=breaks, limits=c(0,1)) 
  labs(title = 'Range 0:1') 
  coord_equal() 
  theme_minimal(base_size = 12)

enter image description here

CodePudding user response:

If your aim is not a real color hue gradient but just to make the color "darker", you could add a layer of grey or even black tiles with changing alpha. This needs to be relative to your midpoint though. I think the approach with cuts is good, although I would suggest to make the cuts bigger.

In the end of the day, this is sort of reproducing a diverging color scale and I am not sure if user mindlessgreens solution is not much more straight forward - really depends on your use case, I guess.

## your data preparation until tt_melt

## the cut approach seems good to me, but make the cuts reasonable
tt_melt$cut <- cut(tt_melt$performance, breaks=c(-Inf, 0.4, 0.5, Inf))
## you will need to add an alpha relative to your midpoint
tt_melt$dist = abs(tt_melt$performance - .5)

ggplot(tt_melt, aes(x = columns, y = rows))  
  geom_tile(aes(fill = cut))   
  scale_fill_manual(values = c("Red", "grey", "green"))  
## now add a layer of grey values based on performance, I am using alpha in order to avoid new fill scale
## remove your neutral values
  geom_tile(data = dplyr::filter(tt_melt, cut != "(0.4,0.5]"), 
            aes(alpha = dist), fill = "black")  
  geom_text(aes(label = performance), color = "white")  
  scale_alpha(range = c(.5,.1))

enter image description here

  • Related