ONeillMB1
ONeillMB1

Reputation: 343

Resize/manually enter breaks on colorbar guide of geom_tile AND replace y-axis labels

I am revisiting this issue I ran into approximately a year ago. I would like my 'colourbar' guide to effectively be displayed on a log scale so that the takeaway when looking at it is that increasingly darker values of blue reflect greater significance.

With the following code, I generate the below image:

pz <- ggplot(dat.m, aes(x=variable,y=Category)) +
  geom_tile(aes(fill=value)) +
  xlab(NULL) + ylab(NULL) +
  scale_fill_gradientn(colours=c("#000066","#0000FF","#DDDDDD","white"), 
                   values=c(0,0.05,0.050000000000001,1.0),
                   breaks=c(0, 0.000001, 0.01, 0.05, 1),
                   guide = "colourbar") +
  theme_bw()+
  theme(panel.background = element_blank(),
        panel.border = element_blank(),
        axis.ticks.x = element_blank(),
        axis.ticks.y = element_blank()) +
  theme(legend.position="top",
        legend.text = element_text(angle=45),
        axis.text.x = element_text(angle=45)
  )

colourbar

Or, I can display it as a "legend" as opposed to a "colourbar":

enter image description here

But what I really desire is something like this:

enter image description here

I have tried adding 'trans="log"' (scale_fill_gradientn(trans="log")), but there are lots of zeros in my data which causes a problem. If you have any ideas it would be greatly appreciated!


Previous wording:

I am trying to make a heatmap of p-values for different samples for various categorizations. There are two things I would like to modify on this plot:

  1. I would like to adjust the legend of my geom_tile plot to emphasize the lower end of the legend scale while still maintaining the full spectrum of the gradient - similar to how it would look if it were a log scale. So essentially the white to blue transition from 1.0-0.05 and the blue to darkblue transition from 0.05-0.00 will be approximately equal in size. Is there a way that I can manually adjust the colorbar guide?

  2. I would like to replace the y-axis names so that I can remove my "empty" row label. Note, the Categories are simply represented as letters here, but in my real data set they are long names. I have inserted "dummy" rows of data to split categorizations into chucks and ordered the tiles within each block to go from most significant to not significant - I am sure there is a better solution to this, but this is what I came up with after many failed attempts of other ideas I found on stack overflow! I have tried labeling them with scale_y_discrete, but this gets jumbled with the aforementioned ordering.

Help with either of these issues will be much appreciated!

sample_heatmap

Here is a sample dataset:

dput(dat.m)
structure(list(Category = structure(c(12L, 11L, 10L, 9L, 8L, 
7L, 6L, 5L, 4L, 3L, 2L, 1L, 12L, 11L, 10L, 9L, 8L, 7L, 6L, 5L, 
4L, 3L, 2L, 1L, 12L, 11L, 10L, 9L, 8L, 7L, 6L, 5L, 4L, 3L, 2L, 
1L), class = "factor", .Label = c("j", "i", "empty2", "h", "empty1", 
"g", "f", "e", "d", "c", "b", "a")), variable = structure(c(1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 
2L, 2L, 2L, 2L, 2L, 2L, 2L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 
3L, 3L, 3L), .Label = c("b2", "c1", "c2"), class = "factor"), 
    value = c(7.40214650772221e-06, 0.0075828339, 0.1825924627, 
    0.0384381317, 0.0440256659, 0.3659284985, 0.9777569144, 1, 
    0.0075828339, 1, 0.2193606406, 0.3659284985, 0.0004289756, 
    0.0011541045, 0.0004289756, 0.4400885491, 0.6121402215, 0.6724032426, 
    0.2735924085, 1, 0.018824582, 1, 0.4386503891, 0.4249526456, 
    1.05094571578633e-05, 0.0027216795, 0.715979827, 0.0050376405, 
    0.7473334763, 0.9053300832, 1, 1, 0.0015392848, 1, 0.039679469, 
    0.0950327519)), .Names = c("Category", "variable", "value"
), row.names = c(NA, -36L), class = "data.frame")

And here is my code:

col_blue <- c("#FFFFFF","#000099","#000066","#000033")
ggplot(dat.m, aes(x=variable,y=Category)) +
  geom_tile(aes(fill=value)) +
  xlab(NULL) + ylab(NULL) +
  scale_fill_gradientn(colours=col_blue, values=c(1,0.05,0.01,0),guide="colorbar") +
  theme_mary(base_size=12)

UPDATE:

So now I have modified the code as such with the following results. I am getting closer to what I hope to achieve but I would like to play with the proportions of the colourbar to show the gradient from 0.05-0.0 a bit more clearly.

col_blue <- c("#FFFFFF","#000099","#000066","#000033")
ggplot(dat.m, aes(x=variable,y=Category)) +
  geom_tile(aes(fill=value)) +
  xlab(NULL) + ylab(NULL) +
  scale_fill_gradientn(colours=col_blue, values=c(1,0.05,0.01,0), guide=FALSE) +
  scale_colour_gradientn(guide = "colourbar", limits = c(0,1),breaks=c(1,0.05,0.01,0),values=c(1,0.05,0.01,0),colours=c("#FFFFFF","#000099","#000066","#000033"))

image2

Upvotes: 6

Views: 5516

Answers (2)

qwwqwwq
qwwqwwq

Reputation: 7309

We can tell scale_fill_gradientn not to display a guide with guide=FALSE, then manually add our own with limits set to c(0,0.1) (or whatever range you want).

ggplot(dat.m, aes(x=variable,y=Category)) +
  geom_tile(aes(fill=value)) +
  xlab(NULL) + 
  ylab(NULL) + 
  scale_fill_gradientn(colours=col_blue, values=c(1,0.05,0.01,0), guide=FALSE) +
  scale_colour_gradientn(guide = "colorbar", limits = c(0,0.1), colours=col_blue) 

enter image description here

As for your second point, why not just remove the "empty" rows from the source data before plotting?

Upvotes: 2

Ricardo Saporta
Ricardo Saporta

Reputation: 55340

for (1), simply modify the data being used to drop the empty rows before (or as you are) plotting. eg: ggplot(dat.m[!grepl("^empty", dat.m$Category), ], aes(<etc>...))

for (2), you can override the aesthetics specifically just for the legend. Here is one example, adjust to your taste: + guides(fill=guide_legend(override.aes=list(alpha=1)))

enter image description here

Upvotes: 0

Related Questions