How to change fill colour of empty cells in ggplot heatmap

Viewed 4799

I have a data set that has some missing values for the x variable. For example, the dataframe below shows 181930 and 610 has a full set of x variables, 1-7, while 1044,1114, etc only have one.

label   xvar value
181930  1    0
181930  2    0
181930  3    1
181930  4    0
181930  5    0
181930  6    0
181930  7    1
610  1    0
610  2    0
610  3    0
610  4    0
610  5    1
610  6    1
610  7    0
1044  1    0
1114  1    0
1156  1    1
1378  1    0
1834  1    1

I would like to produce a heatmap using ggplot showing cells that have values of 1. This is my code so far, however for the labels with only one xvar shows a blank cell and rather I would like for it to have a colour (white) to match the 0 values.

ggplot(activeDF,aes(xvar,factor(label)))+
  geom_tile(aes(fill=value),colour='white')+ 
  scale_x_continuous(breaks=round(seq(0,7)))+
  scale_fill_gradient(high=brewer.pal(10,'PiYG')[8],low='white',na.value = 'white')

Unfortunately, the na.value didn't work for me. Here is a photo: plot

2 Answers

Sometimes the straightforward approach to doing something in ggplot2 is to manipulate your dataset prior to plotting. In this case, expanding your dataset so it contains all combinations you want to plot is an option.

I use tidyr::complete for this along with grouping from package dplyr. This adds a row for xvar of 1 through 7 for every label. If the row doesn't currently exist, it fills in missing values with NA. NA seems sufficient for your use case, but you could also use the fill argument to set the missing values to 0 or something.

library(dplyr)
library(tidyr)

longdf = activeDF %>%
     group_by(label) %>%
     complete(xvar = 1:7)

longdf

# A tibble: 49 x 3
# Groups:   label [7]
   label  xvar value
   <int> <int> <int>
 1   610     1     0
 2   610     2     0
 3   610     3     0
 4   610     4     0
 5   610     5     1
 6   610     6     1
 7   610     7     0
 8  1044     1     0
 9  1044     2    NA
10  1044     3    NA
# ... with 39 more rows

Using the expanded dataset, your plot now expands through the entire range of the data and so the tiling is complete.

ggplot(longdf, aes(xvar, factor(label)) ) +
     geom_tile(aes(fill = value), colour = 'black') + 
     scale_x_continuous(breaks = round(seq(0, 7))) +
     scale_fill_gradient(high = brewer.pal(10, 'PiYG')[8], low='white', na.value = 'white')

enter image description here

try this + theme(panel.background = element_rect(fill = 'white'))

ggplot(activeDF,aes(xvar,factor(label)))+
geom_tile(aes(fill=value),colour='white')+ 
scale_x_continuous(breaks=round(seq(0,7)))+
scale_fill_gradient(high=brewer.pal(10,'PiYG')[8],low='white',na.value = 'white') +
theme(panel.background = element_rect(fill = 'white'))
Related