Commit id: 5092f735f37e38376bf0f9e9e91ae4fd43f0b46d
refreshed docs
Commit id: 41176f68f10188ca00773a0a279dcd67ea30ffd5
heatmap component can all have absolute units
git-svn-id: https://hedgehog.fhcrc.org/bioconductor/trunk/madman/Rpacks/ComplexHeatmap@107536 bc3139a8-67e5-0310-9ffc-ced21a209358
... | ... |
@@ -24,6 +24,7 @@ exportClasses(SingleAnnotation) |
24 | 24 |
export(SingleAnnotation) |
25 | 25 |
exportClasses(AdditiveUnit) |
26 | 26 |
export(AdditiveUnit) |
27 |
+export(max_text_height) |
|
27 | 28 |
exportMethods(annotation_legend_size) |
28 | 29 |
export(AdditiveUnit) |
29 | 30 |
exportMethods(draw_heatmap_list) |
... | ... |
@@ -34,11 +35,12 @@ exportMethods(draw_heatmap_legend) |
34 | 35 |
exportMethods(add_heatmap) |
35 | 36 |
export(anno_barplot) |
36 | 37 |
export(row_anno_boxplot) |
38 |
+export(max_text_width) |
|
37 | 39 |
export(decorate_row_title) |
38 | 40 |
exportMethods(make_layout) |
39 | 41 |
export(anno_histogram) |
40 |
-exportMethods(draw_dimnames) |
|
41 | 42 |
export(plotDataFrame) |
43 |
+exportMethods(draw_dimnames) |
|
42 | 44 |
exportClasses(ColorMapping) |
43 | 45 |
export(ColorMapping) |
44 | 46 |
exportClasses(HeatmapAnnotation) |
... | ... |
@@ -6,6 +6,8 @@ CHANGES in VERSION 1.3.0 |
6 | 6 |
* add `row_anno_*` and `column_anno_*` functions |
7 | 7 |
* `anno_barplot` add `baseline` option to define the baseline of bars |
8 | 8 |
* change default colors for matrix |
9 |
+* allow heatmap with zero-row |
|
10 |
+* heatmap components can all have absolute units |
|
9 | 11 |
|
10 | 12 |
========================================= |
11 | 13 |
|
... | ... |
@@ -286,18 +286,31 @@ Heatmap = function(matrix, col, name, na_col = "grey", rect_gp = gpar(col = NA), |
286 | 286 |
|
287 | 287 |
if(ncol(matrix) == 0) { |
288 | 288 |
.Object@heatmap_param$show_heatmap_legend = FALSE |
289 |
- .Object@heatmap_param$width = unit(0, "null") |
|
289 |
+ .Object@heatmap_param$width = unit(0, "mm") |
|
290 | 290 |
} |
291 | 291 |
|
292 |
- if(ncol(matrix) <= 1) { |
|
292 |
+ if(ncol(matrix) == 0 || nrow(matrix) == 0) { |
|
293 |
+ if(!inherits(cluster_columns, c("dendrogram", "hclust"))) { |
|
294 |
+ cluster_columns = FALSE |
|
295 |
+ show_column_hclust = FALSE |
|
296 |
+ } |
|
293 | 297 |
if(!inherits(cluster_rows, c("dendrogram", "hclust"))) { |
294 | 298 |
cluster_rows = FALSE |
295 | 299 |
show_row_hclust = FALSE |
296 | 300 |
} |
301 |
+ km = 1 |
|
302 |
+ } |
|
303 |
+ if(ncol(matrix) == 1) { |
|
297 | 304 |
if(!inherits(cluster_columns, c("dendrogram", "hclust"))) { |
298 | 305 |
cluster_columns = FALSE |
299 | 306 |
show_column_hclust = FALSE |
300 | 307 |
} |
308 |
+ } |
|
309 |
+ if(nrow(matrix) == 1) { |
|
310 |
+ if(!inherits(cluster_rows, c("dendrogram", "hclust"))) { |
|
311 |
+ cluster_rows = FALSE |
|
312 |
+ show_row_hclust = FALSE |
|
313 |
+ } |
|
301 | 314 |
km = 1 |
302 | 315 |
} |
303 | 316 |
if(is.character(matrix)) { |
... | ... |
@@ -351,7 +364,7 @@ Heatmap = function(matrix, col, name, na_col = "grey", rect_gp = gpar(col = NA), |
351 | 364 |
} |
352 | 365 |
|
353 | 366 |
# color for main matrix |
354 |
- if(ncol(matrix) > 0) { |
|
367 |
+ if(ncol(matrix) > 0 && nrow(matrix) > 0) { |
|
355 | 368 |
if(missing(col)) { |
356 | 369 |
col = default_col(matrix, main_matrix = TRUE) |
357 | 370 |
} |
... | ... |
@@ -432,12 +445,12 @@ Heatmap = function(matrix, col, name, na_col = "grey", rect_gp = gpar(col = NA), |
432 | 445 |
} else { |
433 | 446 |
.Object@row_hclust_param$cluster = cluster_rows |
434 | 447 |
if(!cluster_rows) { |
435 |
- row_hclust_width = unit(0, "null") |
|
448 |
+ row_hclust_width = unit(0, "mm") |
|
436 | 449 |
show_row_hclust = FALSE |
437 | 450 |
} |
438 | 451 |
} |
439 | 452 |
if(!show_row_hclust) { |
440 |
- row_hclust_width = unit(0, "null") |
|
453 |
+ row_hclust_width = unit(0, "mm") |
|
441 | 454 |
} |
442 | 455 |
.Object@row_hclust_list = list() |
443 | 456 |
.Object@row_hclust_param$distance = clustering_distance_rows |
... | ... |
@@ -466,12 +479,12 @@ Heatmap = function(matrix, col, name, na_col = "grey", rect_gp = gpar(col = NA), |
466 | 479 |
} else { |
467 | 480 |
.Object@column_hclust_param$cluster = cluster_columns |
468 | 481 |
if(!cluster_columns) { |
469 |
- column_hclust_height = unit(0, "null") |
|
482 |
+ column_hclust_height = unit(0, "mm") |
|
470 | 483 |
show_column_hclust = FALSE |
471 | 484 |
} |
472 | 485 |
} |
473 | 486 |
if(!show_column_hclust) { |
474 |
- column_hclust_height = unit(0, "null") |
|
487 |
+ column_hclust_height = unit(0, "mm") |
|
475 | 488 |
} |
476 | 489 |
.Object@column_hclust = NULL |
477 | 490 |
.Object@column_hclust_param$distance = clustering_distance_columns |
... | ... |
@@ -492,7 +505,7 @@ Heatmap = function(matrix, col, name, na_col = "grey", rect_gp = gpar(col = NA), |
492 | 505 |
|
493 | 506 |
.Object@top_annotation = top_annotation # a `HeatmapAnnotation` object |
494 | 507 |
if(is.null(top_annotation)) { |
495 |
- .Object@top_annotation_param$height = unit(0, "null") |
|
508 |
+ .Object@top_annotation_param$height = unit(0, "mm") |
|
496 | 509 |
} else { |
497 | 510 |
.Object@top_annotation_param$height = top_annotation_height + unit(1, "mm") # append the gap |
498 | 511 |
} |
... | ... |
@@ -506,7 +519,7 @@ Heatmap = function(matrix, col, name, na_col = "grey", rect_gp = gpar(col = NA), |
506 | 519 |
|
507 | 520 |
.Object@bottom_annotation = bottom_annotation # a `HeatmapAnnotation` object |
508 | 521 |
if(is.null(bottom_annotation)) { |
509 |
- .Object@bottom_annotation_param$height = unit(0, "null") |
|
522 |
+ .Object@bottom_annotation_param$height = unit(0, "mm") |
|
510 | 523 |
} else { |
511 | 524 |
.Object@bottom_annotation_param$height = bottom_annotation_height + unit(1, "mm") # append the gap |
512 | 525 |
} |
... | ... |
@@ -519,21 +532,21 @@ Heatmap = function(matrix, col, name, na_col = "grey", rect_gp = gpar(col = NA), |
519 | 532 |
} |
520 | 533 |
|
521 | 534 |
.Object@layout = list( |
522 |
- layout_column_title_top_height = unit(0, "null"), |
|
523 |
- layout_column_hclust_top_height = unit(0, "null"), |
|
524 |
- layout_column_anno_top_height = unit(0, "null"), |
|
525 |
- layout_column_names_top_height = unit(0, "null"), |
|
526 |
- layout_column_title_bottom_height = unit(0, "null"), |
|
527 |
- layout_column_hclust_bottom_height = unit(0, "null"), |
|
528 |
- layout_column_anno_bottom_height = unit(0, "null"), |
|
529 |
- layout_column_names_bottom_height = unit(0, "null"), |
|
530 |
- |
|
531 |
- layout_row_title_left_width = unit(0, "null"), |
|
532 |
- layout_row_hclust_left_width = unit(0, "null"), |
|
533 |
- layout_row_names_left_width = unit(0, "null"), |
|
534 |
- layout_row_hclust_right_width = unit(0, "null"), |
|
535 |
- layout_row_names_right_width = unit(0, "null"), |
|
536 |
- layout_row_title_right_width = unit(0, "null"), |
|
535 |
+ layout_column_title_top_height = unit(0, "mm"), |
|
536 |
+ layout_column_hclust_top_height = unit(0, "mm"), |
|
537 |
+ layout_column_anno_top_height = unit(0, "mm"), |
|
538 |
+ layout_column_names_top_height = unit(0, "mm"), |
|
539 |
+ layout_column_title_bottom_height = unit(0, "mm"), |
|
540 |
+ layout_column_hclust_bottom_height = unit(0, "mm"), |
|
541 |
+ layout_column_anno_bottom_height = unit(0, "mm"), |
|
542 |
+ layout_column_names_bottom_height = unit(0, "mm"), |
|
543 |
+ |
|
544 |
+ layout_row_title_left_width = unit(0, "mm"), |
|
545 |
+ layout_row_hclust_left_width = unit(0, "mm"), |
|
546 |
+ layout_row_names_left_width = unit(0, "mm"), |
|
547 |
+ layout_row_hclust_right_width = unit(0, "mm"), |
|
548 |
+ layout_row_names_right_width = unit(0, "mm"), |
|
549 |
+ layout_row_title_right_width = unit(0, "mm"), |
|
537 | 550 |
|
538 | 551 |
layout_heatmap_width = width, # for the layout of heatmap list |
539 | 552 |
|
... | ... |
@@ -882,23 +895,25 @@ setMethod(f = "make_layout", |
882 | 895 |
gap = object@matrix_param$gap |
883 | 896 |
n_slice = length(object@row_order_list) |
884 | 897 |
snr = sapply(object@row_order_list, length) |
885 |
- slice_height = (unit(1, "npc") - gap*(n_slice-1))*(snr/sum(snr)) |
|
886 |
- for(i in seq_len(n_slice)) { |
|
887 |
- if(i == 1) { |
|
888 |
- slice_y = unit(1, "npc") |
|
889 |
- } else { |
|
890 |
- slice_y = unit.c(slice_y, unit(1, "npc") - sum(slice_height[seq_len(i-1)]) - gap*(i-1)) |
|
891 |
- } |
|
892 |
- } |
|
893 |
- |
|
894 |
- ########################################### |
|
895 |
- ## heatmap body |
|
896 |
- object@layout$layout_index = rbind(c(5, 4)) |
|
897 |
- object@layout$graphic_fun_list = list(function(object) { |
|
898 |
+ if(sum(snr)) { |
|
899 |
+ slice_height = (unit(1, "npc") - gap*(n_slice-1))*(snr/sum(snr)) |
|
898 | 900 |
for(i in seq_len(n_slice)) { |
899 |
- draw_heatmap_body(object, k = i, y = slice_y[i], height = slice_height[i], just = c("center", "top")) |
|
901 |
+ if(i == 1) { |
|
902 |
+ slice_y = unit(1, "npc") |
|
903 |
+ } else { |
|
904 |
+ slice_y = unit.c(slice_y, unit(1, "npc") - sum(slice_height[seq_len(i-1)]) - gap*(i-1)) |
|
905 |
+ } |
|
900 | 906 |
} |
901 |
- }) |
|
907 |
+ |
|
908 |
+ ########################################### |
|
909 |
+ ## heatmap body |
|
910 |
+ object@layout$layout_index = rbind(c(5, 4)) |
|
911 |
+ object@layout$graphic_fun_list = list(function(object) { |
|
912 |
+ for(i in seq_len(n_slice)) { |
|
913 |
+ draw_heatmap_body(object, k = i, y = slice_y[i], height = slice_height[i], just = c("center", "top")) |
|
914 |
+ } |
|
915 |
+ }) |
|
916 |
+ } |
|
902 | 917 |
|
903 | 918 |
title_padding = unit(2.5, "mm") |
904 | 919 |
############################################ |
... | ... |
@@ -933,16 +948,16 @@ setMethod(f = "make_layout", |
933 | 948 |
if(length(row_title) > 0) { |
934 | 949 |
if(row_title_side == "left") { |
935 | 950 |
if(object@row_title_rot %in% c(0, 180)) { |
936 |
- object@layout$layout_row_title_left_width = max(grobWidth(textGrob(row_title, gp = row_title_gp))) + title_padding*2 |
|
951 |
+ object@layout$layout_row_title_left_width = max_text_width(row_title, gp = row_title_gp) + title_padding*2 |
|
937 | 952 |
} else { |
938 |
- object@layout$layout_row_title_left_width = max(grobHeight(textGrob(row_title, gp = row_title_gp))) + title_padding*2 |
|
953 |
+ object@layout$layout_row_title_left_width = max_text_height(row_title, gp = row_title_gp) + title_padding*2 |
|
939 | 954 |
} |
940 | 955 |
object@layout$layout_index = rbind(object@layout$layout_index, c(5, 1)) |
941 | 956 |
} else { |
942 | 957 |
if(object@row_title_rot %in% c(0, 180)) { |
943 |
- object@layout$layout_row_title_right_width = max(grobWidth(textGrob(row_title, gp = row_title_gp))) + title_padding*2 |
|
958 |
+ object@layout$layout_row_title_right_width = max_text_width(row_title, gp = row_title_gp) + title_padding*2 |
|
944 | 959 |
} else { |
945 |
- object@layout$layout_row_title_right_width = max(grobHeight(textGrob(row_title, gp = row_title_gp))) + title_padding*2 |
|
960 |
+ object@layout$layout_row_title_right_width = max_text_height(row_title, gp = row_title_gp) + title_padding*2 |
|
946 | 961 |
} |
947 | 962 |
object@layout$layout_index = rbind(object@layout$layout_index, c(5, 7)) |
948 | 963 |
} |
... | ... |
@@ -1249,7 +1264,7 @@ setMethod(f = "draw_hclust", |
1249 | 1264 |
if(side == "left") { |
1250 | 1265 |
grid.dendrogram(dend, name = paste(object@name, "hclust_row", k, sep = "_"), max_height = max_height, facing = "right", order = "reverse", x = hclust_padding, width = unit(1, "npc") - hclust_padding*2, just = "left") |
1251 | 1266 |
} else if(side == "right") { |
1252 |
- grid.dendrogram(dend, name = paste(object@name, "hclust_row", k, sep = "_"), max_height = max_height, facing = "left", order = "reverse", x = unit(0, "null"), width = unit(1, "npc") - hclust_padding*2, just = "left") |
|
1267 |
+ grid.dendrogram(dend, name = paste(object@name, "hclust_row", k, sep = "_"), max_height = max_height, facing = "left", order = "reverse", x = unit(0, "mm"), width = unit(1, "npc") - hclust_padding*2, just = "left") |
|
1253 | 1268 |
} else if(side == "top") { |
1254 | 1269 |
grid.dendrogram(dend, name = paste(object@name, "hclust_column", sep = "_"), max_height = max_height, facing = "bottom", y = hclust_padding, height = unit(1, "npc") - hclust_padding*2, just = "bottom") |
1255 | 1270 |
} else if(side == "bottom") { |
... | ... |
@@ -1448,7 +1463,7 @@ setMethod(f = "draw_annotation", |
1448 | 1463 |
if(which == "top") { |
1449 | 1464 |
draw(annotation, index = object@column_order, y = padding, height = unit(1, "npc") - padding, just = "bottom") |
1450 | 1465 |
} else { |
1451 |
- draw(annotation, index = object@column_order, y = unit(0, "null"), height = unit(1, "npc") - padding, just = "bottom") |
|
1466 |
+ draw(annotation, index = object@column_order, y = unit(0, "mm"), height = unit(1, "npc") - padding, just = "bottom") |
|
1452 | 1467 |
} |
1453 | 1468 |
}) |
1454 | 1469 |
|
... | ... |
@@ -1482,9 +1497,13 @@ setMethod(f = "component_width", |
1482 | 1497 |
object@layout$layout_row_names_left_width |
1483 | 1498 |
} else if(k == 4) { |
1484 | 1499 |
if(ncol(object@matrix) == 0) { |
1485 |
- unit(0, "null") |
|
1500 |
+ unit(0, "mm") |
|
1486 | 1501 |
} else { |
1487 |
- unit(1, "null") |
|
1502 |
+ if(!is.unit(object@heatmap_param$width)) { |
|
1503 |
+ unit(1, "null") |
|
1504 |
+ } else { |
|
1505 |
+ object@heatmap_param$width - sum(component_width(object, c(1:3, 5:7))) |
|
1506 |
+ } |
|
1488 | 1507 |
} |
1489 | 1508 |
} else if(k == 5) { |
1490 | 1509 |
object@layout$layout_row_names_right_width |
... | ... |
@@ -27,9 +27,9 @@ HeatmapAnnotation = setClass("HeatmapAnnotation", |
27 | 27 |
), |
28 | 28 |
prototype = list( |
29 | 29 |
anno_list = list(), |
30 |
- size = unit(0, "null"), |
|
30 |
+ size = unit(0, "mm"), |
|
31 | 31 |
which = "row", |
32 |
- gap = unit(0, "null") |
|
32 |
+ gap = unit(0, "mm") |
|
33 | 33 |
), |
34 | 34 |
contains = "AdditiveUnit" |
35 | 35 |
) |
... | ... |
@@ -164,12 +164,12 @@ HeatmapAnnotation = function(df, name, col, annotation_legend_param = list(), |
164 | 164 |
|
165 | 165 |
n_anno = length(anno_list) |
166 | 166 |
|
167 |
- if(is.null(gap)) gap = unit(0, "null") |
|
167 |
+ if(is.null(gap)) gap = unit(0, "mm") |
|
168 | 168 |
|
169 | 169 |
if(length(gap) == 1) { |
170 | 170 |
.Object@gap = rep(gap, n_anno) |
171 | 171 |
} else if(length(gap) == n_anno - 1) { |
172 |
- .Object@gap = unit.c(gap, unit(0, "null")) |
|
172 |
+ .Object@gap = unit.c(gap, unit(0, "mm")) |
|
173 | 173 |
} else if(length(gap) < n_anno - 1) { |
174 | 174 |
stop("Length of `gap` is wrong.") |
175 | 175 |
} else { |
... | ... |
@@ -66,19 +66,19 @@ HeatmapList = setClass("HeatmapList", |
66 | 66 |
), |
67 | 67 |
prototype = list( |
68 | 68 |
layout = list( |
69 |
- layout_annotation_legend_left_width = unit(0, "null"), |
|
70 |
- layout_heatmap_legend_left_width = unit(0, "null"), |
|
71 |
- layout_row_title_left_width = unit(0, "null"), |
|
72 |
- layout_row_title_right_width = unit(0, "null"), |
|
73 |
- layout_heatmap_legend_right_width = unit(0, "null"), |
|
74 |
- layout_annotation_legend_right_width = unit(0, "null"), |
|
75 |
- |
|
76 |
- layout_annotation_legend_top_height = unit(0, "null"), |
|
77 |
- layout_heatmap_legend_top_height = unit(0, "null"), |
|
78 |
- layout_column_title_top_height = unit(0, "null"), |
|
79 |
- layout_column_title_bottom_height = unit(0, "null"), |
|
80 |
- layout_heatmap_legend_bottom_height = unit(0, "null"), |
|
81 |
- layout_annotation_legend_bottom_height = unit(0, "null"), |
|
69 |
+ layout_annotation_legend_left_width = unit(0, "mm"), |
|
70 |
+ layout_heatmap_legend_left_width = unit(0, "mm"), |
|
71 |
+ layout_row_title_left_width = unit(0, "mm"), |
|
72 |
+ layout_row_title_right_width = unit(0, "mm"), |
|
73 |
+ layout_heatmap_legend_right_width = unit(0, "mm"), |
|
74 |
+ layout_annotation_legend_right_width = unit(0, "mm"), |
|
75 |
+ |
|
76 |
+ layout_annotation_legend_top_height = unit(0, "mm"), |
|
77 |
+ layout_heatmap_legend_top_height = unit(0, "mm"), |
|
78 |
+ layout_column_title_top_height = unit(0, "mm"), |
|
79 |
+ layout_column_title_bottom_height = unit(0, "mm"), |
|
80 |
+ layout_heatmap_legend_bottom_height = unit(0, "mm"), |
|
81 |
+ layout_annotation_legend_bottom_height = unit(0, "mm"), |
|
82 | 82 |
|
83 | 83 |
layout_index = matrix(nrow = 0, ncol = 2), |
84 | 84 |
graphic_fun_list = list() |
... | ... |
@@ -237,7 +237,7 @@ setMethod(f = "make_layout", |
237 | 237 |
} |
238 | 238 |
} else { |
239 | 239 |
if(!is.unit(gap)) { |
240 |
- gap = unit(rep(0, n), "null") |
|
240 |
+ gap = unit(rep(0, n), "mm") |
|
241 | 241 |
} |
242 | 242 |
} |
243 | 243 |
object@ht_list_param$gap = gap |
... | ... |
@@ -246,11 +246,11 @@ setMethod(f = "make_layout", |
246 | 246 |
# if the zero-column matrix is the first one |
247 | 247 |
if(inherits(object@ht_list[[i]], "Heatmap")) { |
248 | 248 |
if(i == 1 && ncol(object@ht_list[[1]]@matrix) == 0) { |
249 |
- gap[1] = unit(0, "null") |
|
249 |
+ gap[1] = unit(0, "mm") |
|
250 | 250 |
} else if(i == n && ncol(object@ht_list[[n]]@matrix) == 0) { |
251 |
- gap[n - 1] = unit(0, "null") |
|
251 |
+ gap[n - 1] = unit(0, "mm") |
|
252 | 252 |
} else if(ncol(object@ht_list[[i]]@matrix) == 0) { |
253 |
- gap[i] = unit(0, "null") |
|
253 |
+ gap[i] = unit(0, "mm") |
|
254 | 254 |
} |
255 | 255 |
} |
256 | 256 |
} |
... | ... |
@@ -268,7 +268,7 @@ setMethod(f = "make_layout", |
268 | 268 |
# add a heatmap with zero column so that we can put titles and hclust on the most left |
269 | 269 |
if(inherits(object@ht_list[[1]], "HeatmapAnnotation")) { |
270 | 270 |
object = Heatmap(matrix(nrow = nr, ncol = 0)) + object |
271 |
- gap = unit.c(unit(0, "null"), gap) |
|
271 |
+ gap = unit.c(unit(0, "mm"), gap) |
|
272 | 272 |
i_main = i_main + 1 |
273 | 273 |
} |
274 | 274 |
|
... | ... |
@@ -278,9 +278,14 @@ setMethod(f = "make_layout", |
278 | 278 |
# if the last one is a HeatmapAnnotation object |
279 | 279 |
if(inherits(object@ht_list[[ length(object@ht_list) ]], "HeatmapAnnotation")) { |
280 | 280 |
object = object + Heatmap(matrix(nrow = nr, ncol = 0)) |
281 |
- gap = unit.c(gap, unit(0, "null")) |
|
281 |
+ gap = unit.c(gap, unit(0, "mm")) |
|
282 | 282 |
} |
283 | 283 |
} |
284 |
+ if(n == 1) { |
|
285 |
+ gap = unit(0, "mm") |
|
286 |
+ } else if(length(gap) == n) { |
|
287 |
+ gap = gap[seq_len(n-1)] |
|
288 |
+ } |
|
284 | 289 |
object@ht_list_param$gap = gap |
285 | 290 |
|
286 | 291 |
n = length(object@ht_list) |
... | ... |
@@ -425,10 +430,14 @@ setMethod(f = "make_layout", |
425 | 430 |
ColorMappingList = c(ColorMappingList, ht@matrix_color_mapping) |
426 | 431 |
} |
427 | 432 |
} |
433 |
+ if(inherits(ht, "HeatmapAnnotation")) { |
|
434 |
+ ColorMappingList = c(ColorMappingList, get_color_mapping_list(ht)) |
|
435 |
+ } |
|
428 | 436 |
} |
429 | 437 |
if(length(ColorMappingList) == 0 && length(heatmap_legend_list) == 0) { |
430 | 438 |
show_heatmap_legend = FALSE |
431 | 439 |
} |
440 |
+ |
|
432 | 441 |
object@heatmap_legend_param$show = show_heatmap_legend |
433 | 442 |
heatmap_legend_side = match.arg(heatmap_legend_side)[1] |
434 | 443 |
object@heatmap_legend_param$side = heatmap_legend_side |
... | ... |
@@ -562,10 +571,14 @@ setMethod(f = "draw", |
562 | 571 |
definition = function(object, padding = unit(c(2, 2, 2, 2), "mm"), ..., |
563 | 572 |
newpage= TRUE) { |
564 | 573 |
|
565 |
- if(! any(sapply(object@ht_list, inherits, "Heatmap"))) { |
|
574 |
+ l = sapply(object@ht_list, inherits, "Heatmap") |
|
575 |
+ if(! any(l)) { |
|
566 | 576 |
stop("There should be at least one Heatmap in the heatmap list. You can add a matrix with zero column to the list.") |
567 | 577 |
} |
568 |
- |
|
578 |
+ if(nrow(object@ht_list[[ which(l)[1] ]]@matrix) == 0 && length(l) > 1) { |
|
579 |
+ stop("Since you have a zeor-row matrix, only one heatmap (no row annotation) is allowed.") |
|
580 |
+ } |
|
581 |
+ |
|
569 | 582 |
if(newpage) { |
570 | 583 |
grid.newpage() |
571 | 584 |
} |
... | ... |
@@ -639,7 +652,18 @@ setMethod(f = "component_width", |
639 | 652 |
} else if(k == 3) { |
640 | 653 |
object@layout$layout_row_title_left_width |
641 | 654 |
} else if(k == 4) { |
642 |
- unit(1, "null") |
|
655 |
+ size = sum(do.call("unit.c", lapply(object@ht_list, function(ht) { |
|
656 |
+ if(inherits(ht, "Heatmap")) { |
|
657 |
+ sum(component_width(ht, 1:7)) |
|
658 |
+ } else if(inherits(ht, "HeatmapAnnotation")) { |
|
659 |
+ ht@size |
|
660 |
+ } |
|
661 |
+ }))) |
|
662 |
+ if(is_abs_unit(size)) { # summation of all heatmap/rowannotation are fixed unit |
|
663 |
+ size + sum(object@ht_list_param$gap) |
|
664 |
+ } else { |
|
665 |
+ unit(1, "null") |
|
666 |
+ } |
|
643 | 667 |
} else if(k == 5) { |
644 | 668 |
object@layout$layout_row_title_right_width |
645 | 669 |
} else if(k == 6) { |
... | ... |
@@ -671,6 +695,9 @@ setMethod(f = "component_height", |
671 | 695 |
signature = "HeatmapList", |
672 | 696 |
definition = function(object, k = 1:7) { |
673 | 697 |
|
698 |
+ ht_index = which(sapply(object@ht_list, inherits, "Heatmap")) |
|
699 |
+ n = length(object@ht_list) |
|
700 |
+ |
|
674 | 701 |
.single_unit = function(k) { |
675 | 702 |
if(k == 1) { |
676 | 703 |
object@layout$layout_annotation_legend_top_height |
... | ... |
@@ -679,7 +706,11 @@ setMethod(f = "component_height", |
679 | 706 |
} else if(k == 3) { |
680 | 707 |
object@layout$layout_column_title_top_height |
681 | 708 |
} else if(k == 4) { |
682 |
- unit(1, "null") |
|
709 |
+ if(nrow(object@ht_list[[ht_index[1]]]@matrix) == 0) { |
|
710 |
+ unit(0, "mm") |
|
711 |
+ } else { |
|
712 |
+ unit(1, "null") |
|
713 |
+ } |
|
683 | 714 |
} else if(k == 5) { |
684 | 715 |
object@layout$layout_column_title_bottom_height |
685 | 716 |
} else if(k == 6) { |
... | ... |
@@ -736,7 +767,7 @@ setMethod(f = "draw_heatmap_list", |
736 | 767 |
if(length(i_row_anno_fix_width)) { |
737 | 768 |
row_anno_fix_width = sum(do.call("unit.c", lapply(object@ht_list[i_row_anno_fix_width], function(x) x@size))) |
738 | 769 |
} else { |
739 |
- row_anno_fix_width = unit(0, "null") |
|
770 |
+ row_anno_fix_width = unit(0, "mm") |
|
740 | 771 |
} |
741 | 772 |
object@ht_list[[i_row_anno_nofix_width]]@size = unit(1, "npc") - ht@heatmap_param$width - sum(component_width(ht, k = c(1:3, 5:7))) - |
742 | 773 |
row_anno_fix_width - sum(gap) + gap[length(gap)] |
... | ... |
@@ -772,7 +803,7 @@ setMethod(f = "draw_heatmap_list", |
772 | 803 |
if(inherits(ht, "Heatmap")) { |
773 | 804 |
component_width(ht, c(1:3, 5:7)) |
774 | 805 |
} else { |
775 |
- unit(rep(0, 6), "null") # to be consistent with heatmap non-body columns |
|
806 |
+ unit(rep(0, 6), "mm") # to be consistent with heatmap non-body columns |
|
776 | 807 |
} |
777 | 808 |
})) |
778 | 809 |
|
... | ... |
@@ -791,11 +822,11 @@ setMethod(f = "draw_heatmap_list", |
791 | 822 |
if(is.unit(ht@heatmap_param$width)) { |
792 | 823 |
return(ht@heatmap_param$width) |
793 | 824 |
} else { |
794 |
- return(unit(0, "null")) |
|
825 |
+ return(unit(0, "mm")) |
|
795 | 826 |
} |
796 | 827 |
} else if(inherits(ht, "HeatmapAnnotation")) { |
797 | 828 |
if(is.null(ht@size)) { |
798 |
- return(unit(0, "null")) |
|
829 |
+ return(unit(0, "mm")) |
|
799 | 830 |
} else { |
800 | 831 |
return(ht@size) |
801 | 832 |
} |
... | ... |
@@ -804,9 +835,9 @@ setMethod(f = "draw_heatmap_list", |
804 | 835 |
heatmap_fixed_width = do.call("unit.c", heatmap_fixed_width) |
805 | 836 |
# width for body for each heatmap |
806 | 837 |
if(sum(heatmap_ncol) == 0) { |
807 |
- heatmap_nofixed_width = unit(rep(0, n), "null") |
|
838 |
+ heatmap_nofixed_width = unit(rep(0, n), "mm") |
|
808 | 839 |
} else { |
809 |
- heatmap_nofixed_width = (unit(1, "npc") - sum(width_without_heatmap_body) - sum(heatmap_fixed_width) - sum(gap) + gap[length(gap)]) * (1/sum(heatmap_ncol)) * heatmap_ncol |
|
840 |
+ heatmap_nofixed_width = (unit(1, "npc") - sum(width_without_heatmap_body) - sum(heatmap_fixed_width) - sum(gap)) * (1/sum(heatmap_ncol)) * heatmap_ncol |
|
810 | 841 |
} |
811 | 842 |
|
812 | 843 |
# width of heatmap including body, and other components |
... | ... |
@@ -1150,7 +1181,7 @@ draw_legend = function(ColorMappingList, ColorMappingParamList, side = c("right" |
1150 | 1181 |
height = sum(cm_height) + gap*(n + length(legend_list) -1) |
1151 | 1182 |
|
1152 | 1183 |
if(plot) { |
1153 |
- cm_height = unit.c(unit(0, "null"), cm_height) |
|
1184 |
+ cm_height = unit.c(unit(0, "mm"), cm_height) |
|
1154 | 1185 |
|
1155 | 1186 |
for(i in seq_len(n)) { |
1156 | 1187 |
cm = ColorMappingList[[i]] |
... | ... |
@@ -1185,7 +1216,7 @@ draw_legend = function(ColorMappingList, ColorMappingParamList, side = c("right" |
1185 | 1216 |
height = max(cm_height) |
1186 | 1217 |
|
1187 | 1218 |
if(plot) { |
1188 |
- cm_width = unit.c(unit(0, "null"), cm_width) |
|
1219 |
+ cm_width = unit.c(unit(0, "mm"), cm_width) |
|
1189 | 1220 |
for(i in seq_len(n)) { |
1190 | 1221 |
cm = ColorMappingList[[i]] |
1191 | 1222 |
cm_param = ColorMappingParamList[[i]] |
... | ... |
@@ -490,3 +490,29 @@ rep.list = function(x, n) { |
490 | 490 |
return(lt) |
491 | 491 |
} |
492 | 492 |
|
493 |
+ |
|
494 |
+list_component = function() { |
|
495 |
+ vp_name = grid.ls(viewports = TRUE, grobs = FALSE, print = FALSE)$name |
|
496 |
+} |
|
497 |
+ |
|
498 |
+# == title |
|
499 |
+# Maximum width of text |
|
500 |
+# |
|
501 |
+# == param |
|
502 |
+# -text a vector of text |
|
503 |
+# -... pass to `grid::textGrob` |
|
504 |
+# |
|
505 |
+max_text_width = function(text, ...) { |
|
506 |
+ max(do.call("unit.c", lapply(text, function(x) grobWidth(textGrob(x, ...))))) |
|
507 |
+} |
|
508 |
+ |
|
509 |
+# == title |
|
510 |
+# Maximum height of text |
|
511 |
+# |
|
512 |
+# == param |
|
513 |
+# -text a vector of text |
|
514 |
+# -... pass to `grid::textGrob` |
|
515 |
+# |
|
516 |
+max_text_height = function(text, ...) { |
|
517 |
+ max(do.call("unit.c", lapply(text, function(x) grobHeight(textGrob(x, ...))))) |
|
518 |
+} |
493 | 519 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,17 @@ |
1 |
+\name{max_text_height} |
|
2 |
+\alias{max_text_height} |
|
3 |
+\title{ |
|
4 |
+Maximum height of text |
|
5 |
+} |
|
6 |
+\description{ |
|
7 |
+Maximum height of text |
|
8 |
+} |
|
9 |
+\usage{ |
|
10 |
+max_text_height(text, ...) |
|
11 |
+} |
|
12 |
+\arguments{ |
|
13 |
+ |
|
14 |
+ \item{text}{a vector of text} |
|
15 |
+ \item{...}{pass to \code{\link[grid]{textGrob}}} |
|
16 |
+ |
|
17 |
+} |
0 | 18 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,17 @@ |
1 |
+\name{max_text_width} |
|
2 |
+\alias{max_text_width} |
|
3 |
+\title{ |
|
4 |
+Maximum width of text |
|
5 |
+} |
|
6 |
+\description{ |
|
7 |
+Maximum width of text |
|
8 |
+} |
|
9 |
+\usage{ |
|
10 |
+max_text_width(text, ...) |
|
11 |
+} |
|
12 |
+\arguments{ |
|
13 |
+ |
|
14 |
+ \item{text}{a vector of text} |
|
15 |
+ \item{...}{pass to \code{\link[grid]{textGrob}}} |
|
16 |
+ |
|
17 |
+} |
... | ... |
@@ -381,6 +381,21 @@ ha = rowAnnotation(points = row_anno, width = unit(1, "cm")) |
381 | 381 |
ht1 + ha |
382 | 382 |
``` |
383 | 383 |
|
384 |
+### Heatmap with zero row |
|
385 |
+ |
|
386 |
+If you only want to visualize meta data of your matrix, you can set the matrix with zero row. |
|
387 |
+In this case, only one heatmap is allowed. |
|
388 |
+ |
|
389 |
+```{r zero_row_heatmap, fig.height = 2} |
|
390 |
+ha = HeatmapAnnotation(df = data.frame(value = runif(10), type = rep(letters[1:2], 5)), |
|
391 |
+ barplot = anno_barplot(runif(10)), |
|
392 |
+ points = anno_points(runif(10)), |
|
393 |
+ height = unit(3, "cm")) |
|
394 |
+zero_row_mat = matrix(nrow = 0, ncol = 10) |
|
395 |
+colnames(zero_row_mat) = letters[1:10] |
|
396 |
+Heatmap(zero_row_mat, top_annotation = ha, column_title = "only annotations") |
|
397 |
+``` |
|
398 |
+ |
|
384 | 399 |
### Heatmap with zero column |
385 | 400 |
|
386 | 401 |
If no heatmap is needed to draw and users only want to arrange a list of row annotations, an empty |
... | ... |
@@ -391,7 +406,7 @@ split row annotaitons: |
391 | 406 |
ha_boxplot = rowAnnotation(boxplot = row_anno_boxplot(mat), width = unit(3, "cm")) |
392 | 407 |
ha = rowAnnotation(df = df, col = list(type = c("a" = "red", "b" = "blue")), width = unit(2, "cm")) |
393 | 408 |
text = paste0("row", seq_len(nrow(mat))) |
394 |
-ha_text = rowAnnotation(text = row_anno_text(text), width = max(grobWidth(textGrob(text)))) |
|
409 |
+ha_text = rowAnnotation(text = row_anno_text(text), width = max_text_width(text)) |
|
395 | 410 |
nr = nrow(mat) |
396 | 411 |
Heatmap(matrix(nrow = nr, ncol = 0), split = sample(c("A", "B"), nr, replace = TRUE)) + |
397 | 412 |
ha_boxplot + ha + ha_text |