Question: pheatmap annotation - legend only for columns
3
gravatar for andrea.m.brunner
20 months ago by
andrea.m.brunner40 wrote:

I'm using the pheatmap package in R to cluster and visualize data. I have both column and row annotations. I would like to display the legend only for the row annotations and some of the column annotations. Is this possible?

annotation_legend only allows for TRUE or FALSE, however I would need something like annotation_legend_row.

Thanks!

pheatmap R • 11k views
ADD COMMENTlink modified 20 months ago by Kevin Blighe63k • written 20 months ago by andrea.m.brunner40
6
gravatar for Kevin Blighe
20 months ago by
Kevin Blighe63k
Kevin Blighe63k wrote:

This? - here I add everything but then hide the row annotation colour bar by setting it to white.

Create random data

data <- replicate(20, rnorm(50))
rownames(data) <- paste("Gene", c(1:nrow(data)))
colnames(data) <- paste("Sample", c(1:ncol(data)))

Create col and row metadata

metadata <- data.frame(
      c(rep("case", ncol(data)/2), rep("control", ncol(data)/2)),
      c(rep("cond1", ncol(data)/4), rep("cond2", ncol(data)/4), rep("cond3", ncol(data)/4), rep("cond4", ncol(data)/4)),
      row.names=colnames(data))
colnames(metadata) <- c("casecontrol","condition")

metadata_gene <- data.frame(
      c(rep("Tcell", nrow(data)/2), rep("Bcell", nrow(data)/2)),
      row.names=rownames(data))
colnames(metadata_gene) <- c("Cell")

create the heatmap

require(pheatmap)
out <- pheatmap(data, 
      show_rownames=F, cluster_cols=T, cluster_rows=T, scale="row",
      cex=1, clustering_distance_rows="euclidean", cex=1,
      clustering_distance_cols="euclidean", clustering_method="complete", border_color=FALSE,
      annotation_col=metadata,
      annotation_row=metadata_gene)

a

modify the row annotation

library(grid)
grid.ls(grid.force())
grid.gedit("row_annotation", gp = gpar(col = "white", fill = "white", text = ""))

b

ADD COMMENTlink modified 20 months ago • written 20 months ago by Kevin Blighe63k

Thanks, Kevin, but this is not what I was looking for. The annotation works just fine. I want the legend (on the right of the heatmap) to only be displayed for certain column annotations , in your case for instance only for condition but not for case control - or no legend for column annotations, just for row annotations would be OK too. Any ideas?

ADD REPLYlink modified 20 months ago • written 20 months ago by andrea.m.brunner40

I see! - we can still use the same idea, though.

When you run the grid.ls(grid.force()) command, you'll see a list appear:

layout
  col_tree.2-3-2-3
  row_tree.4-1-4-1
  matrix.4-3-4-3
    GRID.rect.36
  col_names.5-3-5-3
  col_annotation.3-3-3-3
  col_annotation_names.3-4-3-4
  row_annotation.4-2-4-2
  row_annotation_names.5-2-5-2
  annotation_legend.4-6-5-6
    GRID.text.44
    GRID.rect.45
    GRID.text.46
    GRID.text.47
    GRID.rect.48
    GRID.text.49
    GRID.text.50
    GRID.rect.51
    GRID.text.52
  legend.4-5-5-5
    GRID.rect.54
    GRID.text.55

These are objects / components in the plot. We can edit these in the same way that I mentioned previously. The row colour bar is stored as row_annotation.4-2-4-2; our annotation legends are listed under annotation_legend.4-6-5-6; the vertical colour key components are listed under legend.4-5-5-5.

Here is a reproducible answer to get rid of all components of the condition legend, and just the title of the cell legend:

Create random data

data <- replicate(20, rnorm(50))
rownames(data) <- paste("Gene", c(1:nrow(data)))
colnames(data) <- paste("Sample", c(1:ncol(data)))

Create col and row metadata

metadata <- data.frame(
      c(rep("case", ncol(data)/2), rep("control", ncol(data)/2)),
      c(rep("cond1", ncol(data)/4), rep("cond2", ncol(data)/4), rep("cond3", ncol(data)/4), rep("cond4", ncol(data)/4)),
      row.names=colnames(data))
colnames(metadata) <- c("casecontrol","condition")

metadata_gene <- data.frame(
      c(rep("Tcell", nrow(data)/2), rep("Bcell", nrow(data)/2)),
      row.names=rownames(data))
colnames(metadata_gene) <- c("Cell")

create the heatmap

require(pheatmap)
out <- pheatmap(data, 
      show_rownames=F, cluster_cols=T, cluster_rows=T, scale="row",
      cex=1, clustering_distance_rows="euclidean", cex=1,
      clustering_distance_cols="euclidean", clustering_method="complete", border_color=FALSE,
      annotation_col=metadata,
      annotation_row=metadata_gene)

a

identify the objects in the plot

library(grid)
grid.ls(grid.force())

edit the objects

# `condition`
grid.gedit("GRID.text.44", gp = gpar(col="white"))
grid.gedit("GRID.rect.45", gp = gpar(fill="white"))
grid.gedit("GRID.text.46", gp = gpar(col="white"))

# `cell`
grid.gedit("GRID.text.50", gp = gpar(col="white"))

b

ADD REPLYlink written 20 months ago by Kevin Blighe63k

Thank you very much for the thorough explanation! Unfortunately this still doesn't quite solve my issue. As I have a multitude of annotations, pheatmap cuts any legend that exceeds the height of the image. I don't want to make the image height big enough to display all legend entries. As some of my legend entries share the same color code it would be better to not show them. I was hoping that I could delete some legend entries and then the later entries would move into their space. Your solution introduces white space instead and the later legend entries are still not visible. Do you know how I can manually reorder the legend entries? So that in your example case control would be plotted before condition? That would be great! Thanks a lot!

ADD REPLYlink written 20 months ago by andrea.m.brunner40

Yes, you can just flip them by manually ordering like this:

require(pheatmap)
out <- pheatmap(data, 
      show_rownames=F, cluster_cols=T, cluster_rows=T, scale="row",
      cex=1, clustering_distance_rows="euclidean", cex=1,
      clustering_distance_cols="euclidean", clustering_method="complete", border_color=FALSE,
      annotation_col=metadata[,c("condition","casecontrol")],
      annotation_row=metadata_gene)

That should flip condition with casecontrol.

If you have issues fitting the legends on the plot, then also consider modifying the width and height via the width and height parameters, passed to either or both of pheatmap() when you generate the plot and to pdf() when you save it.

ADD REPLYlink modified 20 months ago • written 20 months ago by Kevin Blighe63k

if I understand it well that flips the annotation both in the annotation and the legend? I would like to only flip it in the legend - is that possible?

ADD REPLYlink written 20 months ago by andrea.m.brunner40
1

Although I am sure that there are ways to do that via coding, the quickest way is likely in a graphics editor, i.e., after you have generated and saved the figure to disk. Also, ComplexHeatmap provides much more flexibility than pheatmap for these things. I always use ComplexHeatmap. Working with the gplots and pheatmap heatmaps can be frustrating due to this lack of flexibility.

ADD REPLYlink written 20 months ago by Kevin Blighe63k
1

ah that's too bad, but thank you very much for your help! especially the grid package made me understand the heatmap better. thanks!

ADD REPLYlink written 20 months ago by andrea.m.brunner40
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: 1067 users visited in the last hour