2
votes

I am trying to create a heatmap using ggplot and geom_tile. The fill colour is based on my x values and alpha based on values. Based on small example (left), I would like my Plot to look similar to this example (right). Two problems:

  1. I get errors for the character elements on my alpha scale - is it possible to treat them like NA/ ignore them?
  2. Actual NA values are coloured in the same colour as the group they belong to, rather than all getting a grey fill.

enter image description here

The real Data is much larger and contains facets.. hope this doesn't mess up any possible solution. Here is my example Dataset and my (semi-working) code:


X <- rep(st, each=3)
Y <- rep(st, times=3)

Values<- c('Apple', 2,3,NA, "Banana", 3,1,2,"Pear")

Data <- data.frame(X,Y,Values)

ggplot(Data, mapping = aes(x=X, y=Y, fill=X, 
                           alpha=Values # excluding this part I get a result, just not as I want it
       )) + 
  geom_tile(colour="white") +
  ylab("Y") + 
  xlab("X")+
  scale_fill_manual("Assay", 
                    values = c( 'red', 'yellow', 'green'),
                    na.value = 'grey')+
  scale_alpha("Value", na.value = 0.02)+
  ggtitle("Results Summary")+       
  theme( strip.text.y.left = element_text(angle = 0))+
  geom_text(label=Data$Values)

Thanks in advance for any help :)

1

1 Answers

3
votes

Your first issue can be solved by converting Values to a numeric, i.e. mapping as.numeric(Values) on alpha.

Concerning the second issue. As you map X on fill the tiles are colored according to X. If you want to fill NAs differently as well as tiles where X==Y then you have to define your fill colors accordingly. To this end my approach adds a column fill to the df and makes use of scale_fill_identity.

Note that I moved the alpha and fill into geom_tile so that these are not passed on to geom_text...

... and following the suggestion by @AllanCameron I reversed the order of `Y' so that the plot is in line with your desired output.

library(ggplot2)
library(dplyr)

X <- rep(c('Apple', "Banana", "Pear"), each=3)
Y <- rep(c('Apple', "Banana", "Pear"), times=3)
Y <- factor(Y, levels = c("Pear", "Banana", "Apple"))

Values<- c('Apple', 2,3,NA, "Banana", 3,1,2,"Pear")

Data <- data.frame(X,Y,Values)
Data <- Data %>% 
  mutate(fill = case_when(
    is.na(Values) ~ "grey",
    X == Y ~ "white",
    X == "Apple" ~ "red",
    X == "Banana" ~ "yellow",
    X == "Pear" ~ "green"
  ))

ggplot(Data, mapping = aes(x=X, y=Y)) + 
  geom_tile(aes(fill=fill, alpha=as.numeric(Values)), colour="white") +
  ylab("Y") + 
  xlab("X")+
  scale_fill_identity("Assay") +
  scale_alpha("Value")+
  ggtitle("Results Summary")+       
  theme(strip.text.y.left = element_text(angle = 0))+
  geom_text(aes(label=if_else(!is.na(Values), Values, "NA")))
#> Warning in FUN(X[[i]], ...): NAs introduced by coercion