4

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')
deeenes
  • 4,148
  • 5
  • 43
  • 59
  • `cexRow` and `cexCol` arguments may be helpful. have you investigated `?heatmap`? – bouncyball Feb 15 '17 at 13:50
  • 1
    thanks, `cexCol` and `cexRow` set the size of axis ticklabels, not axis labels. running the same with `heatmap` results the same: axis labels are not affected – deeenes Feb 15 '17 at 14:15

1 Answers1

4

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
deeenes
  • 4,148
  • 5
  • 43
  • 59
  • 1
    I added the parameter you described to avoid overlaps [here.][1] I actually added three parameters, mgps, which behaves like mgp in par function, and it takes by default the values you introduced (which work quite well in general). But then I needed to control for the title labels independently, so I added a xmgp and ymgp parameter, that allow to control mgps[1] independently for x and y labels. Hence, if used, overwrite this value of mgps. [1]: https://github.com/apascualgarcia/gplots/blob/master/R/heatmap.2.R – Alf Pascu Jul 24 '19 at 19:12