1

I would like to get a customized legend for the ready heat map graph, so as it ranged from 0 to 1 with gray scale, but value before 0.01 remain white without any colour gradient on it. Managed to do it for the heat map graph but can't find any close example for the legend.

Here is my code:

> ggplot(heatmap,aes(Colour, Group, fill=p.value))+
+ scale_fill_gradientn(colours= c("white","gray","black"), values=c(0,0.011,1), breaks=c(0,0.01,0.25,0.5,0.75,1), guide=guide_colorbar(frame.colour="black"))+
+ geom_tile() + theme_bw()+ theme(legend.key.height=unit(4.5,"cm"))

and a screenshot for the heat map graph:

heatmap

Any suggestion?

Update: I was substituting the second color from "gray" to "gray95" and it looked slightly better than the graph shown. Kind of delaying the start region for the gray colour to above 0.01 (compared to the legend in the shown graph, where the gray started somewhere before 0.01). Thanks both @Nate and @tjebo for the suggestion on this! However, any helpful suggestion is still welcome.

Also, just want to clarify that I was using "white" as a representation for a specific situation, where the colour "white" was not intended to be in the range for colour gradient for the legend.

web
  • 105
  • 9
  • does using `c("lightgray","gray","black")` suit your needs, maybe just pick a hex code of a gray that you like and drop it in as the first color – Nate Jan 22 '21 at 12:11
  • @Nate Not really, it somehow disturbed the colour range for the graph too. Is it actually possible to specify the colour range in legend separately? – web Jan 22 '21 at 12:26
  • Welcome to SO. It is generally helpful to have a [MCVE](https://stackoverflow.com/help/minimal-reproducible-example) - see below in my answer for one way to approach that. It is very rare that one cannot use one of the inbuilt data sets to reproduce a problem of a more general nature – tjebo Jan 22 '21 at 12:35
  • wouldn't that be visually misleading? having the plot space and the legend be out of of sync. FWIW I think the graph looks good and conveys the signal – Nate Jan 22 '21 at 13:50

1 Answers1

2

This is a minor workaround - use "white" twice, and then start the gradient from the second position. Notice that you need to rescale the values to 0:1 first, see also ?scale_color_gradientn

library(tidyverse)
vals <- c(0, 2, 4, 10)
newvals <- scales::rescale(vals, to = 0:1)
ggplot(iris, aes(Sepal.Length, Sepal.Width, color = Petal.Length)) +
  geom_point() +
  scale_color_gradientn(colours = c("white", "white", "grey", "black"),
                        values = newvals,
                        breaks = vals, 
                        limits = c(0,10))

zoom in with black ticks. You can see the grey gradient starts immediately above 2 enter image description here

tjebo
  • 21,977
  • 7
  • 58
  • 94
  • Right! But it might affect the color representation for the intended graph, as "white" is representing clear cut for something else, not included in the range. I used "close to white colour gray" for the second colour and it looked pretty good here (well, better than what I have had previously). Thanks for the help anyway! – web Jan 22 '21 at 12:50
  • @web - I am afraid I am not sure what you mean. I thought this was what you were looking for. must have misunderstood your question then. Please try to rephrase if my answer did not answer your question. – tjebo Jan 22 '21 at 12:57
  • Hmm, my graph is actually doing well in the attached pic. I have specified the gray scale to begin with value started from 0.011, and pure white (without gradient) from 0 to 0.01. But this wasn't being shown on the legend. I would like to have the legend that go with the colour gradient and value as in the graph. – web Jan 22 '21 at 15:34
  • @web still not quite sure what you mean - using the code in my answer should give exactly what you want. Look at the zoom in - the gradient starts exactly at the defined point, in my example "2", in your example it would be 0.01. Also, consider that contrast (visibility of your greys) is not only matter of the eye physiology, but also of print, and screens. – tjebo Jan 22 '21 at 16:38