Search code examples
rggplot2tidyverseheatmapggtree

Circular tree with heatmap


This question is quite trivial but I cannot be handled nicely with.

I'm trying to plot a circular tree with a side heatmap.

I'm using ggtree but any approach ggplo2 based is welcome. The problems that I'm not understanding well the gheatmap function.

I want:
1- names AFTER the heatmap
2- 2 text columns after heatmap (for while may have the same value, but I need to know how to add it )
3- heatmap columns name nicely handled, should we remove the columns name and use different colors scales for each? wherever the solution falls might better than the way it is now

library(tidyverse)
library(ggtree)
library(treeio)
library(tidytree)

beast_file <- system.file("examples/MCC_FluA_H3.tree", package="ggtree")
beast_tree <- read.beast(beast_file)

genotype_file <- system.file("examples/Genotype.txt", package="ggtree")
genotype <- read.table(genotype_file, sep="\t", stringsAsFactor=F)
colnames(genotype) <- sub("\\.$", "", colnames(genotype))
p <- ggtree(beast_tree, mrsd="2013-01-01",layout = "fan", open.angle = -270) + 
  geom_treescale(x=2008, y=1, offset=2) + 
  geom_tiplab(size=2)

gheatmap(p, genotype, offset=5, width=0.5, font.size=3, 
         colnames_angle=-45, hjust=0) +
  scale_fill_manual(breaks=c("HuH3N2", "pdm", "trig"), 
                    values=c("steelblue", "firebrick", "darkgreen"), name="genotype")

This is the result I had with this code

Thanks in advance

UPDATE:

I found a better way to plot the name of heatmap columns.
Also, I found that the simplification of the data was useful to clean up a little the tip labels. Now, I just need to add two text columns after heatmap.

p <- ggtree(beast_tree)  
gheatmap(
  p, genotype, colnames=TRUE, 
  colnames_angle=90,
  colnames_offset_y = 5,
  colnames_position = "top", 
) +
  scale_fill_manual(breaks=c("HuH3N2", "pdm", "trig"), 
                    values=c("steelblue", "firebrick", "darkgreen"), name="genotype")

enter image description here

UPDATE 2:

A very bad improvement I just used ggplot to create the label and merge with patchwork

library(patchwork)

p$data %>% 
  ggplot(aes(1, y= y, label = label )) +
  geom_text(size=2) +
  xlim(NA, 1) +
  theme_classic() +
  theme(axis.title.x=element_blank(),
        axis.text.x=element_blank(),
        axis.ticks.x=element_blank(),
        axis.title.y=element_blank(),
        axis.text.y=element_blank(),
        axis.ticks.y=element_blank()) -> adText

pp + adText

enter image description here


Solution

  • The answer according @xiangpin at GitHub.

    Big offset value to geom_tiplabel:

    p <- ggtree(beast_tree)  
    p1 <- gheatmap(
             p, genotype, colnames=TRUE, 
             colnames_angle=-45,
             colnames_offset_y = 5,
             colnames_position = "bottom",
             width=0.3,
             hjust=0, font.size=2) +
             scale_fill_manual(breaks=c("HuH3N2", "pdm", "trig"), 
                        values=c("steelblue", "firebrick", "darkgreen"), name="genotype") +
             geom_tiplab(align = TRUE, linesize=0, offset = 7, size=2) +
             xlim_tree(xlim=c(0, 36)) +
             scale_y_continuous(limits = c(-1, NA))
    p1
    

    Solution 1

    Using ggtreeExtra:

    library(ggtreeExtra)
    library(ggtree)
    library(treeio)
    library(ggplot2)
    
    beast_file <- system.file("examples/MCC_FluA_H3.tree", package="ggtree")
    genotype_file <- system.file("examples/Genotype.txt", package="ggtree")
    
    tree <- read.beast(beast_file)
    genotype <- read.table(genotype_file, sep="\t")
    
    colnames(genotype) <- sub("\\.$", "", colnames(genotype))
    genotype$ID <- row.names(genotype)
    
    dat <- reshape2::melt(genotype, id.vars="ID", variable.name = "type", value.name="genotype", factorsAsStrings=FALSE)
    dat$genotype <- unlist(lapply(as.vector(dat$genotype),function(x)ifelse(nchar(x)==0,NA,x)))
    
    p <- ggtree(tree) + geom_treescale()
    
    p2 <- p + geom_fruit(data=dat,
                         geom=geom_tile,
                         mapping=aes(y=ID, x=type, fill=genotype),
                         color="white") +
              scale_fill_manual(values=c("steelblue", "firebrick", "darkgreen"),
                                na.translate=FALSE) +
              geom_axis_text(angle=-45, hjust=0, size=1.5) +
              geom_tiplab(align = TRUE, linesize=0, offset = 6, size=2) +
              xlim_tree(xlim=c(0, 36)) +
              scale_y_continuous(limits = c(-1, NA))
    p2
    

    Solution 2