15 Other Tricks
15.1 Set the same cell size for different heatmaps with different dimensions
Assume you have a list of heatmaps/oncoPrints that you want to save as different e.g. png or pdf files, one
thing you might want to do is to make the size of each grid/cell in the heatmap identical across
heatmaps, thus, you need to calculate the size of png/pdf file according to the number of rows or
columns in the heatmap. In the heatmap generated by ComplexHeatmap, all the heatmap components
have absolute size and only the size of the heatmap body (or the size of the cells) is changable (or
in other words, if you change the size of the final graphic device, e.g. by draging the graphics
window if you plot in, only the size of the heatmap body is adjusted), which means, the size of the
whole plot is linearly related to the number of rows or columns in the heatmap. This implies we can
actually fit a linear model y = a*x + b
where e.g. y
is the height of the whole plot and x
is
the number of rows.
In following example, we simply demonstrate how to establish the relation between the plot height and the number of rows in the heatmap. We first define a function which generates a 10-column matrix with specific number of rows. Note the values in the matrix is of no importance in this demonstration.
random_mat = function(nr) {
m = matrix(rnorm(10*nr), nc = 10)
colnames(m) = letters[1:10]
return(m)
}
Since the relation is absolutely linear, we only need to test two heatmaps with different number of
rows where the height of a single row is unit(5, "mm")
. In the heatmap, there are also column title,
column dendrogram, column annotation and the column names.
There are several things that needs to be noted in following code:
- The heatmap object should be returned by
draw()
because the layout of the heatmap is calculated only after the execution ofdraw()
. -
component_height()
returns a vector of units which correspond to the height of all heatmap components from top to bottom in the heatmap. (component_width()
returns the width of heatmap components). - When calculating
ht_height
, we addunit(4, "mm")
because on top and bottom of the final plot, there are2mm
white borders. -
ht_height
needs to be converted to a simple unit incm
orinch
.
In following, y
contains values which are measured in inch
unit.
y = NULL
for(nr in c(10, 20)) {
ht = draw(Heatmap(random_mat(nr), height = unit(5, "mm")*nr,
column_title = "foo", # one line text
top_annotation = HeatmapAnnotation(bar = 1:10)))
ht_height = sum(component_height(ht)) + unit(4, "mm")
ht_height = convertHeight(ht_height, "inch", valueOnly = TRUE)
y = c(y, ht_height)
}
Then we can fit a linear relation between y
and the number of rows:
##
## Call:
## lm(formula = y ~ x)
##
## Coefficients:
## (Intercept) x
## 1.2222 0.1969
This means the relation between the number of rows x
and the height of the plot y
is: y = 0.1969*x + 1.3150
.
You can test whether the height of single rows are the same for heatmaps with different rows by following code.
Note all the heatmap configuations should be the same as the ones you prepare y
.
for(nr in c(10, 20)) {
png(paste0("test_heatmap_nr_", nr, ".png"), width = 5, height = 0.1969*nr + 1.3150,
units = "in", res = 100)
draw(Heatmap(random_mat(nr), height = unit(5, "mm")*nr,
column_title = "foo", # column title can be any one-line string
top_annotation = HeatmapAnnotation(bar = 1:10)))
dev.off()
}