rheatmapgplots

How to set axis label size in gplots heatmap.2?


I could not find a way to set axis label size for the heatmap itself. The cex.lab argument passed to heatmap.2 has no effect. Calling par(cex.lab = 2.5) has an effect on the legend axis labels and title (these all together, I can`t imagine what if one would like to change only the title...). Anyways, my question is about the heatmap axis label sizes. Example code:

require(gplots)

data(mtcars)
x <- as.matrix(mtcars)
heatmap.2(x, ylab = 'foo bar', xlab = 'bar foo')
par(cex.lab = 5.0)
heatmap.2(x, ylab = 'foo bar', xlab = 'bar foo')

Solution

  • Inspecting heatmap.2 code it is not possible by design. heatmap.2 calls image to draw the heatmap, and extra keyword args (...) passed to it, hence calling heatmap.2(..., cex.lab = n, ...) would make it, and image considers par, so also that way it could be possible. But here xlab and ylab are replaced with empty strings, and both the ticklabels and the axis labels are plotted later:

    # from gplots heatmap.2 source:
    image(1:nc, 1:nr, x, xlim = 0.5+ c(0, nc), ylim = 0.5+ c(0, nr),
        axes = FALSE, xlab = '', ylab = '', col=col, breaks=breaks,
        ...)
    

    Then to draw the axis labels it uses mtext, which is not sensitive to par parameters, but accepts cex argument, which is not provided here:

    # from gplots heatmap.2 source:
    if(!is.null(xlab)) mtext(xlab, side = 1, line = margins[1] - 1.25)
    if(!is.null(ylab)) mtext(ylab, side = 4, line = margins[2] - 1.25)
    

    It means these labels are always the same size, while heatmaps are huge sometimes, so this might be a problem. Also one could maybe shrink the graphic device, and all the other text elements which have the options for customization, and then the relative size of the axis labels would be larger. But how we could sort this out a more flexible way? I modified the code like this:

    # gplots heatmap.2 code modified:
    ## add row and column headings (xlab, ylab)
    cex.lab <- ifelse(invalid(match.call()$cex.lab), 1.0, match.call()$cex.lab)
    if(!is.null(xlab)) mtext(xlab, side = 1,
                             line = margins[1] - 1.25 + cex.lab / 5,
                             cex = cex.lab)
    if(!is.null(ylab)) mtext(ylab, side = 4,
                             line = margins[2] - 1.25 + cex.lab / 5,
                             cex = cex.lab)
    

    The only problem is the positioning parameter which is now cex.lab / 5, this avoids overlap with ticklabels in reasonable ranges, but maye another parameter should be added to the function, so users can modify if it does not fit.

    You can copy heatmap.2.R from gplots source into your working dir, modify it and source it:

    source('heatmap.2.R')
    

    However you need to add also these lines to the beginning:

    require(gtools)
    plot.dendrogram = stats:::plot.dendrogram