Browse code

anno_block(): allows to set width and height

Zuguang Gu authored on 29/06/2020 15:54:31
Showing19 changed files

... ...
@@ -3,6 +3,7 @@ CHANGES in VERSION 2.5.4
3 3
 * fixed a bug where slice clusters were wrongly reordered.
4 4
 * `Heatmap()`: add `border_gp` argument.
5 5
 * Legends are nicely placed.
6
+* `anno_block()`: allows to set height and width.
6 7
 
7 8
 ========================
8 9
 
... ...
@@ -1,31 +1,31 @@
1
-setGeneric('get_legend_param_list', function(object, ...) standardGeneric('get_legend_param_list'))
1
+setGeneric('color_mapping_legend', function(object, ...) standardGeneric('color_mapping_legend'))
2 2
 setGeneric('re_size', function(object, ...) standardGeneric('re_size'))
3
-setGeneric('draw_annotation_legend', function(object, ...) standardGeneric('draw_annotation_legend'))
4
-setGeneric('draw_heatmap_body', function(object, ...) standardGeneric('draw_heatmap_body'))
5
-setGeneric('make_layout', function(object, ...) standardGeneric('make_layout'))
6
-setGeneric('component_height', function(object, ...) standardGeneric('component_height'))
7
-setGeneric('draw_dimnames', function(object, ...) standardGeneric('draw_dimnames'))
3
+setGeneric('draw_heatmap_legend', function(object, ...) standardGeneric('draw_heatmap_legend'))
4
+setGeneric('draw_dend', function(object, ...) standardGeneric('draw_dend'))
5
+setGeneric('prepare', function(object, ...) standardGeneric('prepare'))
6
+setGeneric('draw_annotation', function(object, ...) standardGeneric('draw_annotation'))
7
+setGeneric('draw_heatmap_list', function(object, ...) standardGeneric('draw_heatmap_list'))
8 8
 setGeneric('adjust_heatmap_list', function(object, ...) standardGeneric('adjust_heatmap_list'))
9
-setGeneric('map_to_colors', function(object, ...) standardGeneric('map_to_colors'))
10
-setGeneric('make_row_cluster', function(object, ...) standardGeneric('make_row_cluster'))
9
+setGeneric('draw_title', function(object, ...) standardGeneric('draw_title'))
10
+setGeneric('heatmap_legend_size', function(object, ...) standardGeneric('heatmap_legend_size'))
11 11
 setGeneric('draw', function(object, ...) standardGeneric('draw'))
12
-setGeneric('row_order', function(object, ...) standardGeneric('row_order'))
12
+setGeneric('make_layout', function(object, ...) standardGeneric('make_layout'))
13 13
 setGeneric('annotation_legend_size', function(object, ...) standardGeneric('annotation_legend_size'))
14
-setGeneric('column_dend', function(object, ...) standardGeneric('column_dend'))
14
+setGeneric('draw_heatmap_body', function(object, ...) standardGeneric('draw_heatmap_body'))
15
+setGeneric('draw_annotation_legend', function(object, ...) standardGeneric('draw_annotation_legend'))
16
+setGeneric('get_color_mapping_list', function(object, ...) standardGeneric('get_color_mapping_list'))
17
+setGeneric('get_legend_param_list', function(object, ...) standardGeneric('get_legend_param_list'))
18
+setGeneric('set_component_height', function(object, ...) standardGeneric('set_component_height'))
19
+setGeneric('component_height', function(object, ...) standardGeneric('component_height'))
15 20
 setGeneric('make_column_cluster', function(object, ...) standardGeneric('make_column_cluster'))
16
-setGeneric('draw_title', function(object, ...) standardGeneric('draw_title'))
17 21
 setGeneric('column_order', function(object, ...) standardGeneric('column_order'))
18
-setGeneric('set_component_height', function(object, ...) standardGeneric('set_component_height'))
19
-setGeneric('draw_dend', function(object, ...) standardGeneric('draw_dend'))
20
-setGeneric('component_width', function(object, ...) standardGeneric('component_width'))
21
-setGeneric('row_dend', function(object, ...) standardGeneric('row_dend'))
22
-setGeneric('color_mapping_legend', function(object, ...) standardGeneric('color_mapping_legend'))
23
-setGeneric('prepare', function(object, ...) standardGeneric('prepare'))
24
-setGeneric('get_color_mapping_list', function(object, ...) standardGeneric('get_color_mapping_list'))
25
-setGeneric('draw_heatmap_list', function(object, ...) standardGeneric('draw_heatmap_list'))
26
-setGeneric('add_heatmap', function(object, ...) standardGeneric('add_heatmap'))
27
-setGeneric('draw_heatmap_legend', function(object, ...) standardGeneric('draw_heatmap_legend'))
28
-setGeneric('draw_annotation', function(object, ...) standardGeneric('draw_annotation'))
29
-setGeneric('heatmap_legend_size', function(object, ...) standardGeneric('heatmap_legend_size'))
22
+setGeneric('column_dend', function(object, ...) standardGeneric('column_dend'))
30 23
 setGeneric('copy_all', function(object, ...) standardGeneric('copy_all'))
24
+setGeneric('draw_dimnames', function(object, ...) standardGeneric('draw_dimnames'))
25
+setGeneric('map_to_colors', function(object, ...) standardGeneric('map_to_colors'))
26
+setGeneric('make_row_cluster', function(object, ...) standardGeneric('make_row_cluster'))
27
+setGeneric('add_heatmap', function(object, ...) standardGeneric('add_heatmap'))
28
+setGeneric('row_order', function(object, ...) standardGeneric('row_order'))
31 29
 setGeneric('set_component_width', function(object, ...) standardGeneric('set_component_width'))
30
+setGeneric('row_dend', function(object, ...) standardGeneric('row_dend'))
31
+setGeneric('component_width', function(object, ...) standardGeneric('component_width'))
... ...
@@ -3247,11 +3247,22 @@ anno_block = function(gp = gpar(), labels = NULL, labels_gp = gpar(), labels_rot
3247 3247
 	}
3248 3248
 	if(length(labels)) {
3249 3249
 		if(which == "column") {
3250
-			height = grobHeight(textGrob(labels, rot = labels_rot, gp = labels_gp))
3251
-			height = height + unit(5, "mm")
3250
+			if(missing(height)) {
3251
+				height = grobHeight(textGrob(labels, rot = labels_rot, gp = labels_gp))
3252
+				height = height + unit(5, "mm")
3253
+			} else {
3254
+				if(!inherits(height, "unit")) {
3255
+					stop_wrap("Since you specified `height`, the value should be `unit` object.")
3256
+				}
3257
+			}
3252 3258
 		} else {
3253
-			width = grobWidth(textGrob(labels, rot = labels_rot, gp = labels_gp))
3254
-			width = width + unit(5, "mm")
3259
+			if(missing(width)) {
3260
+				width = grobWidth(textGrob(labels, rot = labels_rot, gp = labels_gp))
3261
+				width = width + unit(5, "mm")
3262
+			} else {
3263
+				if(!inherits(width, "unit")) {
3264
+				stop_wrap("Since you specified `width`, the value should be `unit` object.")
3265
+			}
3255 3266
 		}
3256 3267
 	}
3257 3268
 
... ...
@@ -184,6 +184,9 @@ setMethod(f = "add_heatmap",
184 184
 # -annotation_legend_side side of the annotation legends
185 185
 # -show_annotation_legend whether show annotation legends
186 186
 # -annotation_legend_list user-defined legends which are put after the annotation legends
187
+# -align_heatmap_legend How to align the legends to heatmap. Possible values are "heatmap_center", "heatmap_top" and "global_center". If the value is ``NULL``,
188
+#           it automatically picks the proper value from the three options.
189
+# -align_annotation_legend  How to align the legends to heatmap. Possible values are "heatmap_center", "heatmap_top" and "global_center".
187 190
 # -gap gap between heatmaps/annotations
188 191
 # -ht_gap same as ``gap``.
189 192
 # -main_heatmap index of main heatmap. The value can be a numeric index or the heatmap name
... ...
@@ -27,6 +27,10 @@ setMethod(f = "row_order",
27 27
 	signature = "HeatmapList",
28 28
 	definition = function(object, name = NULL) {
29 29
 
30
+	if(!object@layout$initialized) {
31
+		warning_wrap("The heatmap list has not been initialized. You might have different results if you repeatedly execute this function. It is more suggested to do as `ht_list = draw(ht_list); row_order(ht_list)`.")
32
+	}
33
+
30 34
 	object = make_layout(object)
31 35
 
32 36
 	if(!is.null(name)) {
... ...
@@ -82,6 +86,11 @@ setMethod(f = "row_order",
82 86
 	signature = "Heatmap",
83 87
 	definition = function(object) {
84 88
 
89
+	if(!object@layout$initialized) {
90
+		warning_wrap("The heatmap has not been initialized. You might have different results if you repeatedly execute this function. It is more suggested to do as `ht = draw(ht); row_order(ht)`.")
91
+	}
92
+
93
+
85 94
 	object = prepare(object)
86 95
 
87 96
 	lt = object@row_order_list
... ...
@@ -123,6 +132,10 @@ setMethod(f = "column_order",
123 132
 	signature = "HeatmapList",
124 133
 	definition = function(object, name = NULL) {
125 134
 
135
+	if(!object@layout$initialized) {
136
+		warning_wrap("The heatmap list has not been initialized. You might have different results if you repeatedly execute this function. It is more suggested to do as `ht_list = draw(ht_list); column_order(ht_list)`.")
137
+	}
138
+
126 139
 	object = make_layout(object)
127 140
 
128 141
 	if(!is.null(name)) {
... ...
@@ -177,6 +190,10 @@ setMethod(f = "column_order",
177 190
 	signature = "Heatmap",
178 191
 	definition = function(object) {
179 192
 
193
+	if(!object@layout$initialized) {
194
+		warning_wrap("The heatmap has not been initialized. You might have different results if you repeatedly execute this function. It is more suggested to do as `ht = draw(ht); column_order(ht)`.")
195
+	}
196
+
180 197
 	object = prepare(object)
181 198
 
182 199
 	lt = object@column_order_list
... ...
@@ -216,6 +233,10 @@ setMethod(f = "row_dend",
216 233
 	signature = "HeatmapList",
217 234
 	definition = function(object, name = NULL) {
218 235
 
236
+	if(!object@layout$initialized) {
237
+		warning_wrap("The heatmap list has not been initialized. You might have different results if you repeatedly execute this function. It is more suggested to do as `ht_list = draw(ht_list); row_dend(ht_list)`.")
238
+	}
239
+
219 240
 	object = make_layout(object)
220 241
 
221 242
 	if(!is.null(name)) {
... ...
@@ -272,6 +293,10 @@ setMethod(f = "row_dend",
272 293
 	signature = "Heatmap",
273 294
 	definition = function(object) {
274 295
 
296
+	if(!object@layout$initialized) {
297
+		warning_wrap("The heatmap has not been initialized. You might have different results if you repeatedly execute this function. It is more suggested to do as `ht = draw(ht); row_dend(ht)`.")
298
+	}
299
+
275 300
 	object = prepare(object)
276 301
 
277 302
 	lt = object@row_dend_list
... ...
@@ -313,6 +338,10 @@ setMethod(f = "column_dend",
313 338
 	signature = "HeatmapList",
314 339
 	definition = function(object, name = NULL) {
315 340
 
341
+	if(!object@layout$initialized) {
342
+		warning_wrap("The heatmap list has not been initialized. You might have different results if you repeatedly execute this function. It is more suggested to do as `ht_list = draw(ht_list); column_dend(ht_list)`.")
343
+	}
344
+
316 345
 	object = make_layout(object)
317 346
 
318 347
 	if(!is.null(name)) {
... ...
@@ -369,6 +398,10 @@ setMethod(f = "column_dend",
369 398
 	signature = "Heatmap",
370 399
 	definition = function(object) {
371 400
 
401
+	if(!object@layout$initialized) {
402
+		warning_wrap("The heatmap has not been initialized. You might have different results if you repeatedly execute this function. It is more suggested to do as `ht = draw(ht); column_dend(ht)`.")
403
+	}
404
+
372 405
 	object = prepare(object)
373 406
 	
374 407
 	lt = object@column_dend_list
... ...
@@ -17,6 +17,9 @@
17 17
 # -annotation_legend_side Side of annotation legends.
18 18
 # -show_annotation_legend Whether show annotation legends.
19 19
 # -annotation_legend_list A list of self-defined legends, should be wrapped into a list of `grid::grob` objects. Normally they are constructed by `Legend`.
20
+# -align_heatmap_legend How to align the legends to heatmap. Possible values are "heatmap_center", "heatmap_top" and "global_center". If the value is ``NULL``,
21
+#           it automatically picks the proper value from the three options.
22
+# -align_annotation_legend  How to align the legends to heatmap. Possible values are "heatmap_center", "heatmap_top" and "global_center".
20 23
 # -ht_gap Gap between heatmaps, should be a `grid::unit` object. It can be a vector of length 1 or the number of heamtaps/annotations.
21 24
 # -main_heatmap Name or index for the main heatmap.
22 25
 # -padding Padding of the whole plot. The four values correspond to the bottom, left, top and right paddings.
... ...
@@ -133,7 +133,7 @@ setMethod(f = "draw_heatmap_legend",
133 133
             if(object@direction == "horizontal") {
134 134
                 top_h = sum(component_height(object@ht_list[[ which_main_ht(object) ]], 1:4))
135 135
             } else {
136
-                top_h = sum(component_height(object@ht_list[[ which_first_ht(object) ]], 1:4))
136
+                top_h = calc_before_h(object)
137 137
             }
138 138
             y = unit(1, "npc") - top_h
139 139
             legend_just = "top"
... ...
@@ -145,7 +145,7 @@ setMethod(f = "draw_heatmap_legend",
145 145
             if(object@direction == "vertical") {
146 146
                 left_w = sum(component_width(object@ht_list[[ which_main_ht(object) ]], 1:4))
147 147
             } else {
148
-                left_w = sum(component_width(object@ht_list[[ which_first_ht(object) ]], 1:4))
148
+                left_w = calc_before_w(object)
149 149
             }
150 150
             x = left_w
151 151
             legend_just = "left"
... ...
@@ -156,8 +156,8 @@ setMethod(f = "draw_heatmap_legend",
156 156
                     bottom_h = sum(component_height(object@ht_list[[ which_main_ht(object) ]], 6:9))
157 157
                     top_h = sum(component_height(object@ht_list[[ which_main_ht(object) ]], 1:4))
158 158
                 } else {
159
-                    bottom_h = sum(component_height(object@ht_list[[ which_last_ht(object) ]], 6:9))
160
-                    top_h = sum(component_height(object@ht_list[[ which_first_ht(object) ]], 1:4))
159
+                    bottom_h = calc_after_h(object)
160
+                    top_h = calc_before_h(object)
161 161
                 }
162 162
                 ht_h = unit(1, "npc") - top_h - bottom_h
163 163
                 y = bottom_h + ht_h*0.5
... ...
@@ -166,8 +166,8 @@ setMethod(f = "draw_heatmap_legend",
166 166
                 # grid.rect(y = y, height = ht_h)
167 167
             } else {
168 168
                 if(object@direction == "horizontal") {
169
-                    left_w = sum(component_width(object@ht_list[[ which_first_ht(object) ]], 1:4))
170
-                    right_w = sum(component_width(object@ht_list[[ which_last_ht(object) ]], 6:9))
169
+                    left_w = calc_before_w(object)
170
+                    right_w = calc_after_w(object)
171 171
                 } else {
172 172
                     left_w = sum(component_width(object@ht_list[[ which_main_ht(object) ]], 1:4))
173 173
                     right_w = sum(component_width(object@ht_list[[ which_main_ht(object) ]], 6:9))
... ...
@@ -304,7 +304,7 @@ setMethod(f = "draw_annotation_legend",
304 304
             if(object@direction == "horizontal") {
305 305
                 top_h = sum(component_height(object@ht_list[[ which_main_ht(object) ]], 1:4))
306 306
             } else {
307
-                top_h = sum(component_height(object@ht_list[[ which_first_ht(object) ]], 1:4))
307
+                top_h = calc_before_h(object)
308 308
             }
309 309
             y = unit(1, "npc") - top_h
310 310
             legend_just = "top"
... ...
@@ -316,7 +316,7 @@ setMethod(f = "draw_annotation_legend",
316 316
             if(object@direction == "vertical") {
317 317
                 left_w = sum(component_width(object@ht_list[[ which_main_ht(object) ]], 1:4))
318 318
             } else {
319
-                left_w = sum(component_width(object@ht_list[[ which_first_ht(object) ]], 1:4))
319
+                left_w = calc_before_w(object)
320 320
             }
321 321
             x = left_w
322 322
             legend_just = "left"
... ...
@@ -327,8 +327,8 @@ setMethod(f = "draw_annotation_legend",
327 327
                     bottom_h = sum(component_height(object@ht_list[[ which_main_ht(object) ]], 6:9))
328 328
                     top_h = sum(component_height(object@ht_list[[ which_main_ht(object) ]], 1:4))
329 329
                 } else {
330
-                    bottom_h = sum(component_height(object@ht_list[[ which_last_ht(object) ]], 6:9))
331
-                    top_h = sum(component_height(object@ht_list[[ which_first_ht(object) ]], 1:4))
330
+                    bottom_h = calc_after_h(object)
331
+                    top_h = calc_before_h(object)
332 332
                 }
333 333
                 ht_h = unit(1, "npc") - top_h - bottom_h
334 334
                 y = bottom_h + ht_h*0.5
... ...
@@ -337,8 +337,8 @@ setMethod(f = "draw_annotation_legend",
337 337
                 # grid.rect(y = y, height = ht_h)
338 338
             } else {
339 339
                 if(object@direction == "horizontal") {
340
-                    left_w = sum(component_width(object@ht_list[[ which_first_ht(object) ]], 1:4))
341
-                    right_w = sum(component_width(object@ht_list[[ which_last_ht(object) ]], 6:9))
340
+                    left_w = calc_before_w(object)
341
+                    right_w = calc_after_w(object)
342 342
                 } else {
343 343
                     left_w = sum(component_width(object@ht_list[[ which_main_ht(object) ]], 1:4))
344 344
                     right_w = sum(component_width(object@ht_list[[ which_main_ht(object) ]], 6:9))
... ...
@@ -374,6 +374,72 @@ setMethod(f = "draw_annotation_legend",
374 374
     upViewport()
375 375
 })
376 376
 
377
+calc_ht_h = function(ht_list, inlcude_bottom = FALSE) {
378
+    if(ht_list@direction == "horizontal") {
379
+        bottom_h = sum(component_height(ht_list@ht_list[[ which_main_ht(ht_list) ]], 6:9))
380
+        top_h = sum(component_height(ht_list@ht_list[[ which_main_ht(ht_list) ]], 1:4))
381
+    } else {
382
+        bottom_h = calc_after_h(ht_list)
383
+        top_h = calc_before_h(ht_list)
384
+    }
385
+    ht_h = unit(1, "npc") - top_h - bottom_h
386
+    if(inlcude_bottom) {
387
+        ht_h = unit(1, "npc") - top_h
388
+    }
389
+    ht_h
390
+}
391
+
392
+calc_ht_w = function(ht_list, include_right = FALSE) {
393
+    if(ht_list@direction == "horizontal") {
394
+        left_w = calc_before_w(ht_list)
395
+        right_w = calc_after_w(ht_list)
396
+    } else {
397
+        left_w = sum(component_width(ht_list@ht_list[[ which_main_ht(ht_list) ]], 1:4))
398
+        right_w = sum(component_width(ht_list@ht_list[[ which_main_ht(ht_list) ]], 6:9))
399
+    }
400
+    ht_w = unit(1, "npc") - left_w - right_w
401
+    if(include_right) {
402
+        ht_w = unit(1, "npc") - left_w
403
+    }
404
+    ht_w
405
+}
406
+
407
+calc_before_h = function(ht_list) {
408
+    i = which_last_ht(ht_list)
409
+    if(i == 1) {
410
+        unit(0, "mm")
411
+    } else {
412
+        sum(component_height(ht_list@ht_list[[ which_last_ht(ht_list) ]], 6:9))
413
+    }
414
+}
415
+
416
+calc_after_h = function(ht_list) {
417
+    i = which_last_ht(ht_list)
418
+    if(i == length(ht_list@ht_list)) {
419
+        unit(0, "mm")
420
+    } else {
421
+        sum(component_height(ht_list@ht_list[[ which_last_ht(ht_list) ]], 6:9))
422
+    }
423
+}
424
+
425
+calc_before_w = function(ht_list) {
426
+    i = which_last_ht(ht_list)
427
+    if(i == 1) {
428
+        unit(0, "mm")
429
+    } else {
430
+        sum(component_width(ht_list@ht_list[[ which_first_ht(ht_list) ]], 1:4))
431
+    }
432
+}
433
+
434
+calc_after_w = function(ht_list) {
435
+    i = which_last_ht(ht_list)
436
+    if(i == length(ht_list@ht_list)) {
437
+        unit(0, "mm")
438
+    } else {
439
+        sum(component_width(ht_list@ht_list[[ which_last_ht(ht_list) ]], 6:9))
440
+    }
441
+}
442
+
377 443
 guess_align_legend = function(ht_list, 
378 444
     heatmap_legend_size, annotation_legend_size,
379 445
     heatmap_legend_side, annotation_legend_side,
... ...
@@ -390,46 +456,16 @@ guess_align_legend = function(ht_list,
390 456
         }
391 457
     }
392 458
 
393
-    calc_ht_h = function(inlcude_bottom = FALSE) {
394
-        if(ht_list@direction == "horizontal") {
395
-            bottom_h = sum(component_height(ht_list@ht_list[[ which_main_ht(ht_list) ]], 6:9))
396
-            top_h = sum(component_height(ht_list@ht_list[[ which_main_ht(ht_list) ]], 1:4))
397
-        } else {
398
-            bottom_h = sum(component_height(ht_list@ht_list[[ which_last_ht(ht_list) ]], 6:9))
399
-            top_h = sum(component_height(ht_list@ht_list[[ which_first_ht(ht_list) ]], 1:4))
400
-        }
401
-        ht_h = unit(1, "npc") - top_h - bottom_h
402
-        if(inlcude_bottom) {
403
-            ht_h = unit(1, "npc") - top_h
404
-        }
405
-        ht_h
406
-    }
407
-
408
-    calc_ht_w = function(include_right = FALSE) {
409
-        if(ht_list@direction == "horizontal") {
410
-            left_w = sum(component_width(ht_list@ht_list[[ which_first_ht(ht_list) ]], 1:4))
411
-            right_w = sum(component_width(ht_list@ht_list[[ which_last_ht(ht_list) ]], 6:9))
412
-        } else {
413
-            left_w = sum(component_width(ht_list@ht_list[[ which_main_ht(ht_list) ]], 1:4))
414
-            right_w = sum(component_width(ht_list@ht_list[[ which_main_ht(ht_list) ]], 6:9))
415
-        }
416
-        ht_w = unit(1, "npc") - left_w - right_w
417
-        if(include_right) {
418
-            ht_w = unit(1, "npc") - left_w
419
-        }
420
-        ht_w
421
-    }
422
-
423 459
     align_legend = NULL
424 460
     if(heatmap_legend_side == annotation_legend_side) {
425 461
         # if the size is less than the heatmap body
426 462
         if(ifelse(test_on == "heatmap_legend", heatmap_legend_side, annotation_legend_side) %in% c("left", "right")) {
427
-            ht_h = calc_ht_h()
463
+            ht_h = calc_ht_h(ht_list)
428 464
             if(convertHeight(ht_h, "mm", valueOnly = TRUE) >= max(as.numeric(heatmap_legend_size[2]), as.numeric(annotation_legend_size[2]))) {
429 465
                 align_legend = "heatmap_center"
430 466
             }
431 467
         } else {
432
-            ht_w = calc_ht_w()
468
+            ht_w = calc_ht_w(ht_list)
433 469
             if(convertWidth(ht_w, "mm", valueOnly = TRUE) >= max(as.numeric(heatmap_legend_size[1]), as.numeric(annotation_legend_size[1]))) {
434 470
                 align_legend = "heatmap_center"
435 471
             }
... ...
@@ -437,12 +473,12 @@ guess_align_legend = function(ht_list,
437 473
         # if the size if less than excluding top of first heatmap
438 474
         if(is.null(align_legend)) {
439 475
             if(ifelse(test_on == "heatmap_legend", heatmap_legend_side, annotation_legend_side) %in% c("left", "right")) {
440
-                ht_h = calc_ht_h(TRUE)
476
+                ht_h = calc_ht_h(ht_list, TRUE)
441 477
                 if(convertHeight(ht_h, "mm", valueOnly = TRUE) >= max(as.numeric(heatmap_legend_size[2]), as.numeric(annotation_legend_size[2]))) {
442 478
                     align_legend = "heatmap_top"
443 479
                 }
444 480
             } else {
445
-                ht_w = calc_ht_w(TRUE)
481
+                ht_w = calc_ht_w(ht_list, TRUE)
446 482
                 if(convertWidth(ht_w, "mm", valueOnly = TRUE) >= max(as.numeric(heatmap_legend_size[1]), as.numeric(annotation_legend_size[1]))) {
447 483
                     align_legend = "heatmap_left"
448 484
                 }
... ...
@@ -455,14 +491,14 @@ guess_align_legend = function(ht_list,
455 491
     } else {
456 492
         # if the size is less than the heatmap body
457 493
         if(ifelse(test_on == "heatmap_legend", heatmap_legend_side, annotation_legend_side) %in% c("left", "right")) {
458
-            ht_h = ht_h()
494
+            ht_h = calc_ht_h(ht_list)
459 495
             if(convertHeight(ht_h, "mm", valueOnly = TRUE) >= 
460 496
                 ifelse(test_on == "heatmap_legend", 
461 497
                     as.numeric(heatmap_legend_size[2]), as.numeric(annotation_legend_size[2]))) {
462 498
                 align_legend = "heatmap_center"
463 499
             }
464 500
         } else {
465
-            ht_w = ht_w()
501
+            ht_w = calc_ht_w(ht_list)
466 502
             if(convertWidth(ht_w, "mm", valueOnly = TRUE) >= 
467 503
                 ifelse(test_on == "heatmap_legend", 
468 504
                     as.numeric(heatmap_legend_size[1]), as.numeric(annotation_legend_size[1]))) {
... ...
@@ -472,14 +508,14 @@ guess_align_legend = function(ht_list,
472 508
         # if the size if less than excluding top of first heatmap
473 509
         if(is.null(align_legend)) {
474 510
             if(ifelse(test_on == "heatmap_legend", heatmap_legend_side, annotation_legend_side) %in% c("left", "right")) {
475
-                ht_h = ht_h(TRUE)
511
+                ht_h = calc_ht_h(ht_list, TRUE)
476 512
                 if(convertHeight(ht_h, "mm", valueOnly = TRUE) >= 
477 513
                     ifelse(test_on == "heatmap_legend", 
478 514
                         as.numeric(heatmap_legend_size[2]), as.numeric(annotation_legend_size[2]))) {
479 515
                     align_legend = "heatmap_top"
480 516
                 }
481 517
             } else {
482
-                ht_w = ht_w(TRUE)
518
+                ht_w = calc_ht_w(ht_list, TRUE)
483 519
                 if(convertWidth(ht_w, "mm", valueOnly = TRUE) >= 
484 520
                     ifelse(test_on == "heatmap_legend", 
485 521
                         as.numeric(heatmap_legend_size[1]), as.numeric(annotation_legend_size[1]))) {
... ...
@@ -804,7 +804,7 @@ horizontal_continuous_legend_body = function(at, labels = at, col_fun,
804 804
 # draw(pd, test = "two legends")
805 805
 # pd = packLegend(lgd1, lgd2, direction = "horizontal")
806 806
 # draw(pd, test = "two legends packed horizontally")
807
-packLegend = function(..., gap = unit(2, "mm"), row_gap = unit(2, "mm"), column_gap = unit(2, "mm"),
807
+packLegend = function(..., gap = unit(4, "mm"), row_gap = unit(4, "mm"), column_gap = unit(4, "mm"),
808 808
 	direction = c("vertical", "horizontal"),
809 809
 	max_width = NULL, max_height = NULL, list = NULL) {
810 810
 
... ...
@@ -12,6 +12,7 @@ Heatmap(matrix, col, name,
12 12
     color_space = "LAB",
13 13
     rect_gp = gpar(col = NA),
14 14
     border = NA,
15
+    border_gp = gpar(fill = NA, col = "black"),
15 16
     cell_fun = NULL,
16 17
     layer_fun = NULL,
17 18
     jitter = FALSE,
... ...
@@ -105,6 +106,7 @@ Heatmap(matrix, col, name,
105 106
   \item{rect_gp}{Graphic parameters for drawing rectangles (for heatmap body). The value should be specified by \code{\link[grid]{gpar}} and \code{fill} parameter is ignored.}
106 107
   \item{color_space}{The color space in which colors are interpolated. Only used if \code{matrix} is numeric and  \code{col} is a vector of colors. Pass to \code{\link[circlize]{colorRamp2}}.}
107 108
   \item{border}{Whether draw border. The value can be logical or a string of color.}
109
+  \item{border_gp}{Graphic parameters for the borders. If you want to set different parameters for different heatmap slices, please consider to use \code{\link{decorate_heatmap_body}}.}
108 110
   \item{cell_fun}{Self-defined function to add graphics on each cell. Seven parameters will be passed into  this function: \code{j}, \code{i}, \code{x}, \code{y}, \code{width}, \code{height}, \code{fill} which are column index, row index in \code{matrix}, coordinate of the cell, the width and height of the cell and the filled color. \code{x}, \code{y}, \code{width} and \code{height} are all \code{\link[grid]{unit}} objects.}
109 111
   \item{layer_fun}{Similar as \code{cell_fun}, but is vectorized. Check \url{https://jokergoo.github.io/ComplexHeatmap-reference/book/a-single-heatmap.html#customize-the-heatmap-body} .}
110 112
   \item{jitter}{Random shifts added to the matrix. The value can be logical or a single numeric value. It it is \code{TRUE}, random  values from uniform distribution between 0 and 1e-10 are generated. If it is a numeric value, the range for the uniform distribution is (0, \code{jitter}). It is mainly to solve the problem of "Error: node stack overflow" when there are too many identical rows/columns for plotting the dendrograms.}
... ...
@@ -172,7 +174,7 @@ Heatmap(matrix, col, name,
172 174
   \item{heatmap_height}{Height of the whole heatmap (including heatmap components). Check \url{https://jokergoo.github.io/ComplexHeatmap-reference/book/a-single-heatmap.html#size-of-the-heatmap} .}
173 175
   \item{show_heatmap_legend}{Whether show heatmap legend?}
174 176
   \item{heatmap_legend_param}{A list contains parameters for the heatmap legends. See \code{\link{color_mapping_legend,ColorMapping-method}} for all available parameters.}
175
-  \item{use_raster}{Whether render the heatmap body as a raster image. It helps to reduce file size when the matrix is huge. Note if \code{cell_fun} is set, \code{use_raster} is enforced to be \code{FALSE}.}
177
+  \item{use_raster}{Whether render the heatmap body as a raster image. It helps to reduce file size when the matrix is huge. If number of rows or columns is more than 2000, it is by default turned on. Note if \code{cell_fun} is set, \code{use_raster} is enforced to be \code{FALSE}.}
176 178
   \item{raster_device}{Graphic device which is used to generate the raster image.}
177 179
   \item{raster_quality}{A value set to larger than 1 will improve the quality of the raster image.}
178 180
   \item{raster_device_param}{A list of further parameters for the selected graphic device. For raster image support, please check \url{https://jokergoo.github.io/ComplexHeatmap-reference/book/a-single-heatmap.html#heatmap-as-raster-image} .}
... ...
@@ -17,7 +17,7 @@ Legend(at, labels = at, col_fun, nrow = NULL, ncol = 1, by_row = FALSE,
17 17
     direction = c("vertical", "horizontal"),
18 18
     title = "", title_gp = gpar(fontsize = 10, fontface = "bold"),
19 19
     title_position = c("topleft", "topcenter", "leftcenter", "lefttop", "leftcenter-rot", "lefttop-rot"),
20
-    title_gap = unit(1.5, "mm"))
20
+    title_gap = unit(2, "mm"))
21 21
 }
22 22
 \arguments{
23 23
 
... ...
@@ -11,8 +11,8 @@ Method dispatch page for \code{add_heatmap}.
11 11
 
12 12
 \itemize{
13 13
 \item \code{\link{add_heatmap,HeatmapList-method}}, \code{\link{HeatmapList-class}} class method
14
-\item \code{\link{add_heatmap,Heatmap-method}}, \code{\link{Heatmap-class}} class method
15 14
 \item \code{\link{add_heatmap,HeatmapAnnotation-method}}, \code{\link{HeatmapAnnotation-class}} class method
15
+\item \code{\link{add_heatmap,Heatmap-method}}, \code{\link{Heatmap-class}} class method
16 16
 }
17 17
 }
18 18
 \examples{
... ...
@@ -10,8 +10,8 @@ Method dispatch page for \code{copy_all}.
10 10
 \code{copy_all} can be dispatched on following classes:
11 11
 
12 12
 \itemize{
13
-\item \code{\link{copy_all,SingleAnnotation-method}}, \code{\link{SingleAnnotation-class}} class method
14 13
 \item \code{\link{copy_all,AnnotationFunction-method}}, \code{\link{AnnotationFunction-class}} class method
14
+\item \code{\link{copy_all,SingleAnnotation-method}}, \code{\link{SingleAnnotation-class}} class method
15 15
 }
16 16
 }
17 17
 \examples{
... ...
@@ -24,6 +24,8 @@ Draw a list of heatmaps
24 24
     annotation_legend_side = c("right", "left", "bottom", "top"),
25 25
     show_annotation_legend = TRUE,
26 26
     annotation_legend_list = list(),
27
+    align_heatmap_legend = NULL,
28
+    align_annotation_legend = NULL,
27 29
     
28 30
     gap = unit(2, "mm"),
29 31
     ht_gap = gap,
... ...
@@ -113,6 +115,8 @@ Draw a list of heatmaps
113 115
   \item{annotation_legend_side}{side of the annotation legends}
114 116
   \item{show_annotation_legend}{whether show annotation legends}
115 117
   \item{annotation_legend_list}{user-defined legends which are put after the annotation legends}
118
+  \item{align_heatmap_legend}{How to align the legends to heatmap. Possible values are "heatmap_center", "heatmap_top" and "global_center". If the value is \code{NULL}, it automatically picks the proper value from the three options.}
119
+  \item{align_annotation_legend}{How to align the legends to heatmap. Possible values are "heatmap_center", "heatmap_top" and "global_center".}
116 120
   \item{gap}{gap between heatmaps/annotations}
117 121
   \item{ht_gap}{same as \code{gap}.}
118 122
   \item{main_heatmap}{index of main heatmap. The value can be a numeric index or the heatmap name}
... ...
@@ -10,9 +10,9 @@ Method dispatch page for \code{draw}.
10 10
 \code{draw} can be dispatched on following classes:
11 11
 
12 12
 \itemize{
13
-\item \code{\link{draw,HeatmapAnnotation-method}}, \code{\link{HeatmapAnnotation-class}} class method
14 13
 \item \code{\link{draw,Heatmap-method}}, \code{\link{Heatmap-class}} class method
15 14
 \item \code{\link{draw,Legends-method}}, \code{\link{Legends-class}} class method
15
+\item \code{\link{draw,HeatmapAnnotation-method}}, \code{\link{HeatmapAnnotation-class}} class method
16 16
 \item \code{\link{draw,SingleAnnotation-method}}, \code{\link{SingleAnnotation-class}} class method
17 17
 \item \code{\link{draw,AnnotationFunction-method}}, \code{\link{AnnotationFunction-class}} class method
18 18
 \item \code{\link{draw,HeatmapList-method}}, \code{\link{HeatmapList-class}} class method
... ...
@@ -10,8 +10,8 @@ Method dispatch page for \code{draw_title}.
10 10
 \code{draw_title} can be dispatched on following classes:
11 11
 
12 12
 \itemize{
13
-\item \code{\link{draw_title,HeatmapList-method}}, \code{\link{HeatmapList-class}} class method
14 13
 \item \code{\link{draw_title,Heatmap-method}}, \code{\link{Heatmap-class}} class method
14
+\item \code{\link{draw_title,HeatmapList-method}}, \code{\link{HeatmapList-class}} class method
15 15
 }
16 16
 }
17 17
 \examples{
... ...
@@ -23,6 +23,8 @@ Make Layout for the Heatmap List
23 23
     annotation_legend_side = c("right", "left", "bottom", "top"),
24 24
     show_annotation_legend = TRUE,
25 25
     annotation_legend_list = list(),
26
+    align_heatmap_legend = NULL,
27
+    align_annotation_legend = NULL,
26 28
     
27 29
     ht_gap = unit(2, "mm"),
28 30
     
... ...
@@ -89,6 +91,8 @@ Make Layout for the Heatmap List
89 91
   \item{annotation_legend_side}{Side of annotation legends.}
90 92
   \item{show_annotation_legend}{Whether show annotation legends.}
91 93
   \item{annotation_legend_list}{A list of self-defined legends, should be wrapped into a list of \code{\link[grid:grid.grob]{grob}} objects. Normally they are constructed by \code{\link{Legend}}.}
94
+  \item{align_heatmap_legend}{How to align the legends to heatmap. Possible values are "heatmap_center", "heatmap_top" and "global_center". If the value is \code{NULL}, it automatically picks the proper value from the three options.}
95
+  \item{align_annotation_legend}{How to align the legends to heatmap. Possible values are "heatmap_center", "heatmap_top" and "global_center".}
92 96
   \item{ht_gap}{Gap between heatmaps, should be a \code{\link[grid]{unit}} object. It can be a vector of length 1 or the number of heamtaps/annotations.}
93 97
   \item{main_heatmap}{Name or index for the main heatmap.}
94 98
   \item{padding}{Padding of the whole plot. The four values correspond to the bottom, left, top and right paddings.}
... ...
@@ -7,7 +7,7 @@ Pack Legends
7 7
 Pack Legends
8 8
 }
9 9
 \usage{
10
-packLegend(..., gap = unit(2, "mm"), row_gap = unit(2, "mm"), column_gap = unit(2, "mm"),
10
+packLegend(..., gap = unit(4, "mm"), row_gap = unit(4, "mm"), column_gap = unit(4, "mm"),
11 11
     direction = c("vertical", "horizontal"),
12 12
     max_width = NULL, max_height = NULL, list = NULL)
13 13
 }
... ...
@@ -10,8 +10,8 @@ Method dispatch page for \code{row_dend}.
10 10
 \code{row_dend} can be dispatched on following classes:
11 11
 
12 12
 \itemize{
13
-\item \code{\link{row_dend,HeatmapList-method}}, \code{\link{HeatmapList-class}} class method
14 13
 \item \code{\link{row_dend,Heatmap-method}}, \code{\link{Heatmap-class}} class method
14
+\item \code{\link{row_dend,HeatmapList-method}}, \code{\link{HeatmapList-class}} class method
15 15
 }
16 16
 }
17 17
 \examples{
... ...
@@ -10,12 +10,12 @@ Method dispatch page for \code{show}.
10 10
 \code{show} can be dispatched on following classes:
11 11
 
12 12
 \itemize{
13
-\item \code{\link{show,ColorMapping-method}}, \code{\link{ColorMapping-class}} class method
14 13
 \item \code{\link{show,Heatmap-method}}, \code{\link{Heatmap-class}} class method
14
+\item \code{\link{show,AnnotationFunction-method}}, \code{\link{AnnotationFunction-class}} class method
15 15
 \item \code{\link{show,HeatmapAnnotation-method}}, \code{\link{HeatmapAnnotation-class}} class method
16
-\item \code{\link{show,HeatmapList-method}}, \code{\link{HeatmapList-class}} class method
17 16
 \item \code{\link{show,SingleAnnotation-method}}, \code{\link{SingleAnnotation-class}} class method
18
-\item \code{\link{show,AnnotationFunction-method}}, \code{\link{AnnotationFunction-class}} class method
17
+\item \code{\link{show,HeatmapList-method}}, \code{\link{HeatmapList-class}} class method
18
+\item \code{\link{show,ColorMapping-method}}, \code{\link{ColorMapping-class}} class method
19 19
 }
20 20
 }
21 21
 \examples{