Question: Adding column annotation to heatmap using Complexheatmap
0
gravatar for Vasu
11 months ago by
Vasu320
Vasu320 wrote:

I have a matrix "data" like this

            Sample1 Sample2 Sample3 Sample4 Sample5 Sample6 Sample7
AC008870.3  1.0502  1.5076  1.3916  0.3655  1.1028  0.6700  1.6719
TLX1NB      2.0357  1.6799  -0.5898 -0.2286 1.8068  2.0801  2.1399
LINC00511   1.6435  1.3586  1.5394  1.0144  0.6329  1.6717  0.9201
PRC1-AS1    1.3657  1.5695  0.7393  0.8945  1.6971  0.7516  1.8048
AL161431.1  -0.6128 -0.6128 2.5562  -0.2102 -0.1496 -0.3387 -0.2035
AC022784.1  -1.0502 -0.1724 0.4127  2.3219  -0.6579 1.4954  -0.5929
LINC00518   -0.6053 -0.4479 -0.3621 0.0543  0.9048  0.1343  0.0658
C5orf66-AS1 0.2909  0.0603  0.3172  -0.3273 0.3660  -0.0113 -0.0723
AL589182.1  0.4675  1.9790  -0.6627 1.4468  0.4681  -0.6627 1.4636
LINC01705   1.8079  -0.1598 1.0448  0.0201  -0.0780 1.8574  1.0598
AC007639.1  1.8472  1.5940  1.6298  0.7072  0.8901  1.4685  0.8939
AL139099.5  0.4277  0.2271  0.5286  1.4965  1.2302  0.9821  1.1370

And the column data is in a dataframe "df"

Samples Type Type2
Sample1 M   AT
Sample2 M   AT
Sample3 M   AT
Sample4 N   PT
Sample5 N   PT
Sample6 N   PT
Sample7 M   AT

I'm able to make a heatmap using complex heatmap package, but a bit confused in adding column annotation to the heatmap.

pdf("heatmap.pdf", width=7, height=6.5)
Heatmap(data, name = "expression",  col = greenred(75), 
                  show_row_names = FALSE, show_column_names = FALSE,cluster_rows = TRUE,
                   cluster_columns = TRUE,show_column_dend = TRUE,show_row_dend = TRUE,
  row_dend_reorder = TRUE,column_dend_reorder = TRUE,clustering_method_rows = "ward.D2",
                   clustering_method_columns = "ward.D2",width = unit(100, "mm"))
dev.off()

How to add column annotation to the heatmap? Any help is appreciated.

complexheatmap rna-seq heatmap R • 1.6k views
ADD COMMENTlink modified 11 months ago by Kevin Blighe41k • written 11 months ago by Vasu320
2
gravatar for Kevin Blighe
11 months ago by
Kevin Blighe41k
Guy's Hospital, London
Kevin Blighe41k wrote:

Here's a quick example to get you started, with top and bottom col annotations. The general function for adding annotation in ComplexHeatmap is HeatmapAnnotation(), and one distinguishes between col and row annotation via the 'which' parameter, as you'll see below. It follow, then, that both row and col annotation are added differently to the heatmap object, as I show in my example here: C: how to cluster genes in heatmap

In short, col annotations are added via the top_annotation and bottom_annotation parameters passed to the Heatmap() function, whereas row annotations are added via the draw() function (as you'll see in my other example).

data
            Sample1 Sample2 Sample3 Sample4 Sample5 Sample6 Sample7
AC008870.3   1.0502  1.5076  1.3916  0.3655  1.1028  0.6700  1.6719
TLX1NB       2.0357  1.6799 -0.5898 -0.2286  1.8068  2.0801  2.1399
LINC00511    1.6435  1.3586  1.5394  1.0144  0.6329  1.6717  0.9201
PRC1-AS1     1.3657  1.5695  0.7393  0.8945  1.6971  0.7516  1.8048
AL161431.1  -0.6128 -0.6128  2.5562 -0.2102 -0.1496 -0.3387 -0.2035
AC022784.1  -1.0502 -0.1724  0.4127  2.3219 -0.6579  1.4954 -0.5929
LINC00518   -0.6053 -0.4479 -0.3621  0.0543  0.9048  0.1343  0.0658
C5orf66-AS1  0.2909  0.0603  0.3172 -0.3273  0.3660 -0.0113 -0.0723
AL589182.1   0.4675  1.9790 -0.6627  1.4468  0.4681 -0.6627  1.4636
LINC01705    1.8079 -0.1598  1.0448  0.0201 -0.0780  1.8574  1.0598
AC007639.1   1.8472  1.5940  1.6298  0.7072  0.8901  1.4685  0.8939
AL139099.5   0.4277  0.2271  0.5286  1.4965  1.2302  0.9821  1.1370

metadata
  Samples Type Type2
1 Sample1    M    AT
2 Sample2    M    AT
3 Sample3    M    AT
4 Sample4    N    PT
5 Sample5    N    PT
6 Sample6    N    PT
7 Sample7    M    AT

.

#Set annotation
ann <- data.frame(metadata$Type, metadata$Type2)
colnames(ann) <- c("Type", "Type2")
colours <- list("Type"=c("M"="red2","N"="royalblue"), "Type2"=c("AT"="limegreen","PT"="gold"))
colAnn <- HeatmapAnnotation(df=ann, which="col", col=colours, annotation_width=unit(c(1, 4), "cm"), gap=unit(1, "mm"))

boxplotCol <- HeatmapAnnotation(boxplot=anno_boxplot(data.matrix(data), border=TRUE, gp=gpar(fill="#CCCCCC"), pch=".", size=unit(2, "mm"), axis=TRUE, axis_side="left", axis_gp=gpar(fontsize=12)), annotation_width=unit(c(1, 5.0), "cm"), which="col")


hmap <- Heatmap(data, name = "expression",  col = greenred(75), 
   show_row_names = FALSE, show_column_names = FALSE, cluster_rows = TRUE,
   cluster_columns = TRUE, show_column_dend = TRUE, show_row_dend = TRUE,
   row_dend_reorder = TRUE, column_dend_reorder = TRUE, clustering_method_rows = "ward.D2",
   clustering_method_columns = "ward.D2", width = unit(100, "mm"),

   top_annotation_height=unit(1.0,"cm"), top_annotation=colAnn,

   bottom_annotation_height=unit(3, "cm"), bottom_annotation=boxplotCol)

draw(hmap, heatmap_legend_side="left", annotation_legend_side="right")

a

ADD COMMENTlink modified 11 months ago • written 11 months ago by Kevin Blighe41k

Thank you very much Kevin.

ADD REPLYlink written 11 months ago by Vasu320
1

You are very welcome.

ADD REPLYlink written 11 months ago by Kevin Blighe41k

One question. How to adjust the expression color? On my plot 15,10 (red), 5 (black), 0,-5 (green) was displayed and the whole plot was in green color. May I know how to adjust that? Check this plot

matrix with values is logCPM. When I used heatmap.2 function it looks fine. But when I'm using complexheatmap the whole plot was in green color

ADD REPLYlink modified 11 months ago • written 11 months ago by Vasu320
2

Yes, your heatmap just looks a bit 'flat', which can frequently happen but which does not necessarily mean that your data is incorrect. In such situations, it can be a good idea to plot Z-scaled data, which means, for example, that a value of +2 represents 2 standard deviations (sdevs) above the mean, whereas, -2 represents 2 sdevs below the mean, et cetera.

You can also quite easily specify your own colour scheme via the colorRampPalette() and colorRamp2() functions (from circlize package). If you scale your own data, it's also a good idea to specify your own 'breaks', i.e., thresholds in your data that indicate where colour should change. Doing this can help to exaggerate, for example, lower values. One then supplies the colour scheme and the breaks to the col parameter of the Heatmap() function, like this: col=colorRamp2(myBreaks, myCol)

Here, I generate your same heatmap twice with a different colour scheme and breaks.

require(ComplexHeatmap)
require(circlize)

#Specify colours and breaks
myCol1 <- colorRampPalette(c("violet", "black", "springgreen"))(100)
myBreaks1 <- seq(-3, 3, length.out=100)
myCol2 <- colorRampPalette(c("white", "grey50", "black"))(100)
myBreaks2 <- seq(-1, 1, length.out=100)

#Scale data to Z-scores
heat <- t(scale(t(data)))

#Set annotation
ann <- data.frame(metadata$Type, metadata$Type2)
colnames(ann) <- c("Type", "Type2")
colours <- list("Type"=c("M"="red2","N"="royalblue"), "Type2"=c("AT"="limegreen","PT"="gold"))
colAnn <- HeatmapAnnotation(df=ann, which="col", col=colours, annotation_width=unit(c(1, 4), "cm"), gap=unit(1, "mm"))

#Add column boxplot
boxplotCol <- HeatmapAnnotation(boxplot=anno_boxplot(data.matrix(heat), border=TRUE, gp=gpar(fill="#CCCCCC"), pch=".", size=unit(2, "mm"), axis=TRUE, axis_side="left", axis_gp=gpar(fontsize=12)), annotation_width=unit(c(1, 5.0), "cm"), which="col")

hmap1 <- Heatmap(heat, name = "expression1",

   col=colorRamp2(myBreaks1, myCol1),

   show_row_names = FALSE, show_column_names = FALSE, cluster_rows = TRUE,
   cluster_columns = TRUE, show_column_dend = TRUE, show_row_dend = TRUE,
   row_dend_reorder = TRUE, column_dend_reorder = TRUE, clustering_method_rows = "ward.D2",
   clustering_method_columns = "ward.D2", width = unit(100, "mm"),

   top_annotation_height=unit(1.0,"cm"), top_annotation=colAnn,

   bottom_annotation_height=unit(3, "cm"), bottom_annotation=boxplotCol)


hmap2 <- Heatmap(heat, name = "expression2",

   col=colorRamp2(myBreaks2, myCol2),

   show_row_names = FALSE, show_column_names = FALSE, cluster_rows = TRUE,
   cluster_columns = TRUE, show_column_dend = TRUE, show_row_dend = TRUE,
   row_dend_reorder = TRUE, column_dend_reorder = TRUE, clustering_method_rows = "ward.D2",
   clustering_method_columns = "ward.D2", width = unit(100, "mm"),

   top_annotation_height=unit(1.0,"cm"), top_annotation=colAnn,

   bottom_annotation_height=unit(3, "cm"), bottom_annotation=boxplotCol)

draw(hmap1 + hmap2, heatmap_legend_side="left", annotation_legend_side="right")

s

ADD REPLYlink modified 11 months ago • written 11 months ago by Kevin Blighe41k

Actually the matrix which I posted in my question was Z-scaled data only. From the logCPM mentioned in edgeR tutorial I used logCPM <- t(scale(t(logCPM))) and then used it for heatmap. I adjusted the expression with breaks and it looks fine. Thanks a lot again.

ADD REPLYlink modified 11 months ago • written 11 months ago by Vasu320

Sorry Kevin, if I have two time points of single cell RNA-seq data, in time point 1 cells can be clustered to 2 clusters, Lets say for example in time point 1, cell1, cell9, .. (99 cells) placed in sub cluster 1, cell4, cell12,,, (34 cells) in sub cluster 2. I have also 2 sub-clusters for time point 2. I have 200 genes. I want to heat map these 200 genes so columns have annotation for example time point 1-sub-cluster1, time point1-sub-cluster2, time point2-subcluster 1 and time point2-subcluster2 something like this picture

enter image description here

That each day has sub clusters a, b, c, ..

May you please help me

ADD REPLYlink written 8 months ago by jivarajivaraj40

Hello, I would post this as a new Question. I am unavailable for a number of days.

ADD REPLYlink written 8 months ago by Kevin Blighe41k
Please log in to add an answer.

Help
Access

Use of this site constitutes acceptance of our User Agreement and Privacy Policy.
Powered by Biostar version 2.3.0
Traffic: 1775 users visited in the last hour