Browse code

Commit made by the Bioconductor Git-SVN bridge.

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

z.gu authored on 18/08/2015 13:35:51
Showing 9 changed files

... ...
@@ -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