jokergoo / ComplexHeatmap

Make Complex Heatmaps
https://jokergoo.github.io/ComplexHeatmap-reference/book/
Other
1.31k stars 227 forks source link

Right annotation is not correct in oncoPrint #717

Closed xlucpu closed 3 years ago

xlucpu commented 3 years ago

Hi I am using ComplexHeatmap (2.5.5) to draw an OncoPrint with several annotations. It works perfectly in column and bottom annotations but I met troubles in right annotations.

I made an example to reproduce my "error" here and you could see the right anotation barplot is different from using draw() and rowAnnotation() in oncoPrint(). The right annotation here is a stacked percentage barplot and presented incorrectly within the oncoPrint.

Call for help, many thanks advanced!

# load R package
library(ComplexHeatmap)
library(ClassDiscovery)

# simulate mutational data
r <- 10
c <- 100
m0 <- matrix(0, r, c)
set.seed(1)
mut <- apply(m0, c(1,2), function(x) sample(c(0,1),1)) 
dimnames(mut) <- list(paste0("G",1:10),paste0("P",1:100))

# clustering samples
hcs <- hclust(distanceMatrix(as.matrix(mut), "euclidean"), "ward.D")
group <- cutree(hcs,4); names(group) <- colnames(mut)
group <- sort(group)

# re-organize sample and create phenotype
mut <- mut[,names(group)]
phenotype <- data.frame(Subtype = rep(c("A","B","C","D"),table(group)),
                        row.names = colnames(mut))
head(phenotype)
# Subtype
# P1        A
# P11       A
# P13       A
# P34       A
# P35       A
# P43       A

# create basic information for oncoprint
mut.order <- names(sort(rowSums(mut),decreasing = T)) # mutational order
onco.input <- mut
onco.input[onco.input == 1] <- "Mutated"
onco.input[onco.input != "Mutated"] <- ""

alter_fun = list(
  background = function(x, y, w, h) {
    grid.rect(x, y, w-unit(0.5, "mm"), h-unit(0.5, "mm"), gp = gpar(fill = "#dcddde", col = "#dcddde"))
  },
  Mutated = function(x, y, w, h) {
    grid.rect(x, y, w-unit(0.5, "mm"), h-unit(0.5, "mm"), gp = gpar(fill = "#A60000", col = "#A60000")) 
  }
)
my_ann <- phenotype
my_annotation = HeatmapAnnotation(df = my_ann, 
                                  col = list(Subtype = c("A" = "red",
                                                         "B" = "green",
                                                         "C" = "blue",
                                                         "D" = "yellow")))

# create right annotation
tmp <- as.data.frame(t(mut))
tmp$Subtype <- phenotype$Subtype
pct <- NULL
for (i in mut.order) {
  tmp1 <- tmp[,c(i,"Subtype")]
  tmp1 <- as.data.frame.array(table(tmp1[,1],tmp1$Subtype))[2,]/sum(tmp1[,1])
  pct <- rbind.data.frame(pct,tmp1)
}
rownames(pct) <- mut.order
print(pct) # check the percentage and you can see the first one G7 has a high percentage in cluster C
# A          B         C          D
# G7  0.03278689 0.21311475 0.6393443 0.11475410
# G9  0.35185185 0.29629630 0.2407407 0.11111111
# G10 0.07407407 0.12962963 0.7037037 0.09259259
# G2  0.37735849 0.01886792 0.4150943 0.18867925
# G4  0.16981132 0.13207547 0.4339623 0.26415094
# G6  0.14000000 0.16000000 0.4200000 0.28000000
# G8  0.19148936 0.34042553 0.2127660 0.25531915
# G1  0.23913043 0.04347826 0.4565217 0.26086957
# G3  0.28571429 0.19047619 0.5238095 0.00000000
# G5  0.21052632 0.07894737 0.4736842 0.23684211

right_anno <- anno_barplot(as.matrix(pct),
                           which = "row",
                           border = FALSE,
                           gp = gpar(fill = c("red","green","blue","yellow"),
                                     border =NA,lty="blank"),height = unit(3, "cm"))

# use draw to plot right annotation
draw(right_anno) # this is correct

# use oncoprint to attach right annotation (which is different from using draw)
p <- oncoPrint(onco.input[,rownames(my_ann)], 
               alter_fun = alter_fun, 
               bottom_annotation = NULL, 
               top_annotation = NULL,
               column_order = rownames(my_ann), 
               right_annotation = rowAnnotation(bar3 = right_anno), # use right annotation
               row_order = mut.order, 
               show_pct = T, 
               column_title = "", 
               show_heatmap_legend=T, 
               column_split = my_ann$Subtype,
               column_title_gp = gpar(fontsize = 8),
               row_names_gp = gpar(fontsize = 8),
               column_names_gp = gpar(fontsize = 8))
p # this is incorrect
xlucpu commented 3 years ago

I solved this by the following:

p <- oncoPrint(onco.input[mut.order,rownames(my_ann)], 
               alter_fun = alter_fun, 
               bottom_annotation = NULL, 
               top_annotation = NULL,
               column_order = rownames(my_ann), 
               right_annotation = rowAnnotation(bar3 = right_anno), # use right annotation
               #row_order = mut.order, 
               show_pct = T, 
               column_title = "", 
               show_heatmap_legend=T, 
               column_split = my_ann$Subtype,
               column_title_gp = gpar(fontsize = 8),
               row_names_gp = gpar(fontsize = 8),
               column_names_gp = gpar(fontsize = 8))