I want to build custom heatmap with color ranges based on multiple conditions.
I found a similar post that focuses on
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")
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)
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))