njc
njc

Reputation: 21

ggplot heatmap: different hues for different categories by rows

I'm trying to create a heatmap showing monthly fruit abundance of various species at three different sites (C, G, N).

I'd like each site to be represented by a different colour (C = grey, G = yellow, N = blue) and abundance represented by the shade of that colour. I'd also like each species at each site in separate rows (e.g. some species are found at multiple sites, so those species will be in multiple rows, with each row corresponding to the site(s) it's found at).

Here is a very small subset of my data (monthly fruit abundance by species at each site):

Species                Site JAN.18 FEB.18 MAR.18 APR.18 MAY.18.
Alangium chinense        G    0    0    0    0     2537    0
Albizia gummifera        G    0    0    0   134    268     0    
Allophylus chaunostachys G    0    0    0    0      0      6258      
Allophylus chaunostachys N    0    0    0    0      0      2      
Aningeria altissima      N   13    0    0    0      0      0      
Beilschmiedia rwandensis N    0    0    0    0      0      0      

And here is a summary of the range of my values:

Value            
Min.   :    1  
1st Qu.:   35  
Median :  329  
Mean   : 2914  
3rd Qu.: 1543
Max.   :81376

This is the code I'm working with:

ggplot(fai, aes(month, Species)) + 
  geom_tile(aes(alpha = value, fill=Site),colour = "white") + 
  scale_alpha(range=c(0,1)) +
  scale_fill_manual(values = c('C' ='grey', 'G'='yellow','N'='blue',na.value = 'white')) +
  scale_x_discrete("", expand = c(0, 0)) + 
  scale_y_discrete("", expand = c(0, 0)) + 
  theme_minimal(base_size = 9) + 
  theme(legend.position = "none",
        axis.ticks = element_blank(), 
        axis.text.x = element_text(angle = 330, hjust = 0),
        panel.grid.major = element_blank(), 
        panel.grid.minor = element_blank())

It produces this plot:

enter image description here

As you can see, the different sites are condensed into the same row and the colours aren't scaled to show a different shade based on abundance value. I'm hoping someone is able to help me adapt the code to produce my desired output.

Thanks in advance :)

Upvotes: 1

Views: 80

Answers (1)

jazzurro
jazzurro

Reputation: 23574

I came up with the following idea. I modified your data a bit. You want to create a variable including species and site. You can use it for y axis. The other thing is that you use alpha with the value. When value is 0, alpha is 0; colors are transparent. So I decided to change the color of the background with theme_cowplot(). In this way, you can show that values are 0.

library(tidyverse)
library(cowplot)

pivot_longer(mydf, cols = JAN.18:JUN.18, 
             names_to = "Date") %>% 
mutate(Date = as.Date(Date, "%b.%d"),
       Species = paste(Species, Site, sep = "_"),
       Site = replace(Site, value == 0, NA)) -> mydf

ggplot(mydf) + 
geom_tile(aes(x = Date, y = Species, fill = Site, alpha = value)) +
scale_fill_manual(values = c("G" = "yellow", "N" = "blue")) +
scale_alpha_continuous(guide = "none") +
theme_cowplot() -> g

enter image description here

DATA

mydf <- structure(list(Species = c("Alangium chinense", "Albizia gummifera", 
"Allophylus chaunostachys", "Allophylus chaunostachys", "Aningeria altissima", 
"Beilschmiedia rwandensis"), Site = c("G", "G", "G", "N", "N", 
"N"), JAN.18 = c(0, 55, 0, 0, 13, 0), FEB.18 = c(0, 0, 0, 0, 
1500, 0), MAR.18 = c(0, 0, 0, 3000, 0, 0), APR.18 = c(0, 134, 
0, 0, 0, 0), MAY.18 = c(2537, 268, 0, 0, 4500, 0), JUN.18 = c(0, 
0, 6258, 2, 0, 0)), class = "data.frame", row.names = c(NA, -6L
))

Upvotes: 0

Related Questions