2
votes

I am currently using heatmap.plus to draw heatmaps with color side bars in each side (row, and column). An example of a code to plot a heatmap for a matrix of dim 18 by 50 bellow:

m.to.plot = matrix(rnorm(n=18*50,mean=3,sd=2), nrow=18, ncol=50)
colc = rainbow(2)[c(rep(x=2,30), rep(x=1,20))]
tmp = runif(n=18, min=0,max = 1)
rowc = rgb(tmp^1.5+(1-tmp^1.5)*0.742,tmp^1.5+(1-tmp^1.5)*0.742,(1-tmp^1.5)*0.742);
heatmap.plus(m.to.plot, 
             scale="none", 
             ColSideColors=colc,
             RowSideColors=rowc,
             Rowv=NA, Colv=NA, 
             col=c("green2","red2"))

Such code produce a figure like this: Heatmap I produce

But what I really want is a two column colored side bar, an example of the 'unfinished' code and it's 'in theory' image would look like this:

m.to.plot = matrix(rnorm(n=18*50,mean=3,sd=2), nrow=18, ncol=50)
colc = rainbow(2)[c(rep(x=2,30), rep(x=1,20))]
tmp = runif(n=18, min=0,max = 1)
rowc = rgb(tmp^1.5+(1-tmp^1.5)*0.742,tmp^1.5+(1-tmp^1.5)*0.742,(1-tmp^1.5)*0.742);
tmp2 = runif(n=50, min=0,max = 1)
extra.colc = rgb(tmp^1.5+(1-tmp^1.5)*0.742,tmp^1.5+(1-tmp^1.5)*0.742,(1-tmp^1.5)*0.742);

Then I need to call heatmap.plus (or change/use another heatmap.plus) such that I can visualize two column colored sided bars in the same plot

And it'd be...

Heatmap I'd like to produce

voila!

Any ideas on how to modify heatmap.plus and/or the way I call the function?

Note: the heatmap function I am using is heatmap.plus, taken from bioconductor. A copy of it below (in case someone is interested).

    heatmap.plus = function (x, Rowv = NULL, Colv = if (symm) "Rowv" else NULL,
   distfun = dist, hclustfun = hclust, reorderfun = function(d,w) reorder(d, w),
   add.expr, symm = FALSE, revC = identical(Colv, "Rowv"), scale = c("row", "column", "none"), na.rm = TRUE,
   margins = c(5, 5), ColSideColors, RowSideColors, cexRow = 0.2 +
   1/log10(nr), cexCol = 0.2 + 1/log10(nc), labRow = NULL,
   labCol = NULL, cRow=NULL, cCol=NULL, main = NULL, xlab = NULL, ylab = NULL, keep.dendro = FALSE,
   verbose = getOption("verbose"), ...)
{
   scale <- if (symm && missing(scale))
   "none"
   else match.arg(scale)
   if (length(di <- dim(x)) != 2 || !is.numeric(x))
   stop("'x' must be a numeric matrix")
   nr <- di[1]
   nc <- di[2]
   if (nr <= 1 || nc <= 1)
   stop("'x' must have at least 2 rows and 2 columns")
   if (!is.numeric(margins) || length(margins) != 2)
   stop("'margins' must be a numeric vector of length 2")
   doRdend <- !identical(Rowv, NA)
   doCdend <- !identical(Colv, NA)
   if (is.null(Rowv))
   Rowv <- rowMeans(x, na.rm = na.rm)
   if (is.null(Colv))
   Colv <- colMeans(x, na.rm = na.rm)
   if (doRdend) {
   if (inherits(Rowv, "dendrogram"))
   ddr <- Rowv
   else {
   hcr <- hclustfun(distfun(x))
   ddr <- as.dendrogram(hcr)
   if (!is.logical(Rowv) || Rowv)
   ddr <- reorderfun(ddr, Rowv)
   }
   if (nr != length(rowInd <- order.dendrogram(ddr)))
   stop("row dendrogram ordering gave index of wrong length")
   }
   else rowInd <- 1:nr
   if (doCdend) {
   if (inherits(Colv, "dendrogram"))
   ddc <- Colv
   else if (identical(Colv, "Rowv")) {
   if (nr != nc)
   stop("Colv = \"Rowv\" but nrow(x) != ncol(x)")
   ddc <- ddr
   }
   else {
   hcc <- hclustfun(distfun(if (symm)
   x
   else t(x)))
   ddc <- as.dendrogram(hcc)
   if (!is.logical(Colv) || Colv)
   ddc <- reorderfun(ddc, Colv)
   }
   if (nc != length(colInd <- order.dendrogram(ddc)))
   stop("column dendrogram ordering gave index of wrong length")
   }
   else colInd <- 1:nc
   x <- x[rowInd, colInd]
   labRow <- if (is.null(labRow))
   if (is.null(rownames(x)))
   (1:nr)[rowInd]
   else rownames(x)
   else labRow[rowInd]
   labCol <- if (is.null(labCol))
   if (is.null(colnames(x)))
   (1:nc)[colInd]
   else colnames(x)
   else labCol[colInd]
   if (scale == "row") {
   x <- sweep(x, 1, rowMeans(x, na.rm = na.rm))
   sx <- apply(x, 1, sd, na.rm = na.rm)
   x <- sweep(x, 1, sx, "/")
   }
   else if (scale == "column") {
   x <- sweep(x, 2, colMeans(x, na.rm = na.rm))
   sx <- apply(x, 2, sd, na.rm = na.rm)
   x <- sweep(x, 2, sx, "/")
   }
   lmat <- rbind(c(NA, 3), 2:1)
   lwid <- c(if (doRdend) 1 else 0.05, 4)
   lhei <- c((if (doCdend) 1 else 0.05) + if (!is.null(main)) 0.2 else 0,
   4)
   if (!missing(ColSideColors))
{
   lmat <- rbind(lmat[1, ] + 1, c(NA, 1), lmat[2, ] + 1)
   lhei <- c(lhei[1], 0.125/par()$fin[2]*10, lhei[2])
}
   if (!missing(RowSideColors)) {
   lmat <- cbind(lmat[, 1] + 1, c(rep(NA, nrow(lmat) - 1),
   1), lmat[, 2] + 1)
   lwid <- c(lwid[1], 0.135/par()$fin[1]*10, lwid[2])
   }
   lmat[is.na(lmat)] <- 0
   if (verbose) {
   cat("layout: widths = ", lwid, ", heights = ", lhei,
   "; lmat=\n")
   print(lmat)
   }
   op <- par(no.readonly = TRUE)
   on.exit(par(op))
   layout(lmat, widths = lwid, heights = lhei, respect = FALSE)
   if (!missing(RowSideColors)) {
   par(mar = c(margins[1L], 0, 0, 0.5))
   image(rbind(1L:nr), col = RowSideColors[rowInd], axes = FALSE)
   }
   if (!missing(ColSideColors)) {
   par(mar = c(0.5, 0, 0, margins[2L]))
   image(cbind(1L:nc), col = ColSideColors[colInd], axes = FALSE)
   }
   par(mar = c(margins[1], 0, 0, margins[2]))
   if (!symm || scale != "none") {
   x <- t(x)
   }
   if (revC) {
   iy <- nr:1
   ddr <- rev(ddr)
   x <- x[, iy]
   }
   else iy <- 1:nr
   image(1:nc, 1:nr, x, xlim = 0.5 + c(0, nc), ylim = 0.5 +
   c(0, nr), axes = FALSE, xlab = "", ylab = "", ...)
   axis(1, 1:nc, labels = labCol, las = 2, line = -0.5, tick = 0,
   cex.axis = cexCol)
   if (!is.null(xlab))
   mtext(xlab, side = 1, line = margins[1] - 1.25)
   axis(4, iy, labels = labRow, las = 2, line = -0.5, tick = 0,
   cex.axis = cexRow)
   if (!is.null(ylab))
   mtext(ylab, side = 4, line = margins[2] - 1.25)
   if (!missing(add.expr))
   eval(substitute(add.expr))
   par(mar = c(margins[1], 0, 0, 0))
   if (doRdend)
   plot(ddr, horiz = TRUE, axes = FALSE, yaxs = "i", leaflab = "none")
   else frame()
   par(mar = c(0, 0, if (!is.null(main)) 1 else 0, margins[2]))
   if (doCdend)
   plot(ddc, axes = FALSE, xaxs = "i", leaflab = "none")
   else if (!is.null(main))
   frame()
   if (!is.null(main))
   title(main, cex.main = 1.5 * op[["cex.main"]])
   invisible(list(rowInd = rowInd, colInd = colInd, Rowv = if (keep.dendro &&
   doRdend) ddr, Colv = if (keep.dendro && doCdend) ddc))
}
1

1 Answers

0
votes

You can use a matrix for ColSideColor instead of a vector. For example: you have two vectors :

A   B
Red  Blue
green  black
Red  yellow
purple  Blue

create a matrix:

 colormatrix <- cbind(A,B)

and use it as for ColSideColor then you will have two ColSideColors in your sample code: instead of colc use colormatrix.

 heatmap.plus(m.to.plot, 
         scale="none", 
         ColSideColors=colormatrix,
         RowSideColors=rowc,
         Rowv=NA, Colv=NA, 
         col=c("green2","red2"))