Reputation: 93
I'm working on a heatmap where my values range from 0-40 and I'd like to have my 0s be colored white while the other values from 1-40 are colored with a gradient. I've experimented with a few options but none seem to accomplish exactly what I'm hoping to do.
The code below is the closest I've been able to get, where I set the limits for the scale fill gradient to 1-40, but this makes 0s appear gray not white:
ggplot(dataframe, aes(x=xvar, y=yvar, fill=n)) +
geom_tile(color="white", size = 0.25) +
geom_text(aes(label = n)) +
scale_fill_gradient(low="gold", high="darkorchid", limits=c(1, 40))
Is there a way to somehow combine scale_fill_manual and scale_fill_gradient to achieve this? Or is there a completely different function I can try?
Thanks!
Upvotes: 1
Views: 2660
Reputation: 3519
If you want an answer that doesn't rely on setting 0s to NAs you can use scale_fill_gradientn
to create a colour scale with more than two colours in the gradient. Note the use of scales::rescale
to specify where the colours should change in the gradient (i.e. to squish the first white-gold to only work from 0-1 and then gold-darkorchid to work from 1-40).
Note I have created some example data. In future when asking questions it is best to supply Minimal reproducible data for examples see this question.
library(dplyr)
library(ggplot2)
library(scales)
set.seed(2)
dataframe <- expand.grid(xvar = 1:10, yvar = 1:10) %>% mutate(n = sample(0:40, 100, replace = T))
plt <- ggplot(dataframe, aes(x=xvar, y=yvar, fill=n)) +
geom_tile(color="white", size = 0.25) +
geom_text(aes(label = n)) +
scale_fill_gradientn(colours = c("white", "gold", "darkorchid"),
values = scales::rescale(c(0,1,40)),
limits=c(0, 40))
Created on 2025-02-11 with reprex v2.1.1
Upvotes: 1
Reputation: 96
I know this was a ggplot question, but for those who are making heatmaps outside of ggplot with, for example, pheatmap, the NA option may not work depending on what you're doing. The NA option works fine with no clustering but if you want to do clustering, NA is not allowed. In pheatmap you can set the color argument and concatenate the color white with the rest of whatever color ramp you want. Here's an example using the "Reds" palette from RColorBrewer.
color = colorRampPalette(c("white", brewer.pal(n = 7, name = "Reds")))(100)
Upvotes: 0
Reputation: 93
I used Gregor Thomas's suggestion and created a new variable called "n_nas" where I coded my zeros as NA. I used "n_nas" as the fill but used the original "n" variable for the labels so that they still appeared as zeros in the heatmap. Here is my final code:
dataframe$n_nas <- ifelse(dataframe$n==0,NA,dataframe$n)
ggplot(dataframe, aes(x=xvar, y=yvar, fill=n_nas)) +
geom_tile(color="white", size = 0.25) +
geom_text(aes(label = n)) +
scale_fill_gradient(low="gold", high="darkorchid", na.value="white"))
Thanks!
Upvotes: 1