Browse code

decorate_*() functions returns to the viewport where they are called

Zuguang Gu authored on 19/07/2017 14:06:45
Showing 15 changed files

... ...
@@ -2,14 +2,15 @@ Package: ComplexHeatmap
2 2
 Type: Package
3 3
 Title: Making Complex Heatmaps
4 4
 Version: 1.15.1
5
-Date: 2017-2-15
5
+Date: 2017-7-19
6 6
 Author: Zuguang Gu
7 7
 Maintainer: Zuguang Gu <z.gu@dkfz.de>
8 8
 Depends: R (>= 3.1.2), methods, grid, graphics, stats, grDevices
9 9
 Imports: circlize (>= 0.4.1), GetoptLong, colorspace,
10
-    RColorBrewer, dendextend (>= 1.0.1), GlobalOptions (>= 0.0.10)
10
+    RColorBrewer, GlobalOptions (>= 0.0.10)
11 11
 Suggests: testthat (>= 0.3), knitr, markdown, cluster, MASS, pvclust, 
12
-    dendsort, HilbertCurve, Cairo, png, jpeg, tiff, fastcluster
12
+    dendsort, HilbertCurve, Cairo, png, jpeg, tiff, fastcluster,
13
+    dendextend (>= 1.0.1)
13 14
 VignetteBuilder: knitr
14 15
 Description: Complex heatmaps are efficient to visualize associations 
15 16
     between different sources of data sets and reveal potential structures. 
... ...
@@ -18,6 +19,6 @@ Description: Complex heatmaps are efficient to visualize associations
18 19
 biocViews: Software, Visualization, Sequencing
19 20
 URL: https://github.com/jokergoo/ComplexHeatmap
20 21
 License: GPL (>= 2)
21
-Packaged: 2017-2-15 00:00:00 UTC; Administrator
22
+Packaged: 2017-7-19 00:00:00 UTC; Administrator
22 23
 Repository: Bioconductor
23
-Date/Publication: 2017-2-15 00:00:00
24
+Date/Publication: 2017-7-19 00:00:00
... ...
@@ -1,5 +1,6 @@
1 1
 export('+.AdditiveUnit')
2 2
 export('grid.dendrogram')
3
+export('grid.dendrogram2')
3 4
 export(AdditiveUnit)
4 5
 export(ColorMapping)
5 6
 export(Heatmap)
... ...
@@ -7,6 +8,7 @@ export(HeatmapAnnotation)
7 8
 export(HeatmapList)
8 9
 export(Legend)
9 10
 export(SingleAnnotation)
11
+export(adjust_dend_by_leaf_width)
10 12
 export(anno_barplot)
11 13
 export(anno_boxplot)
12 14
 export(anno_density)
... ...
@@ -109,8 +111,5 @@ importFrom("circlize", rand_color)
109 111
 importFrom("circlize", smartAlign)
110 112
 importFrom("colorspace", diverge_hcl)
111 113
 importFrom("colorspace", rainbow_hcl)
112
-importFrom("dendextend", "labels<-")
113
-importFrom("dendextend", get_branches_heights)
114
-importFrom("dendextend", nnodes)
115 114
 importFrom("utils", "getFromNamespace")
116 115
 
... ...
@@ -5,10 +5,16 @@ CHANGES in VERSION 1.15.1
5 5
 * annotations with duplicated names have no legends any more
6 6
 * re-implement `grid.xaxis()` to draw axis labels rotated 90 degrees
7 7
 * grids in discrete legend are arranged by rows if ncol > 1
8
-* raster image is generated in a independent R session
8
+* raster image is generated in an independent R session
9 9
 * empty string in annotation or heatmap is mapped to NA
10 10
 * annotation and heatmap legends can be merged into one column. 
11 11
 * change the default value of `row_names_max_width` and `column_names_max_height`
12
+* default legend style for continuous values is changed to "continuous"
13
+* add `grid.dendrogram2()` which draws dendrograms with uneven position for leaves
14
+* move **dendextend** to Suggests field because it depends/imports rlang indirectly
15
+  which has a `print.frame()` function and it will affect to print a `frame` object
16
+  returned by `frameGrob()`.
17
+* `decorate_*()` functions return to the viewport where they are called.
12 18
 
13 19
 =======================
14 20
 
... ...
@@ -212,7 +212,7 @@ setMethod(f = "map_to_colors",
212 212
 # -title title of the legend, by default it is the name of the legend
213 213
 # -title_gp graphical parameters for legend title
214 214
 # -title_position position of the title
215
-# -color_bar if the mapping is continuous, whether show the legend as discrete color bar or continuous color bar
215
+# -color_bar a string of "continous" or "discrete". If the mapping is continuous, whether show the legend as discrete color bar or continuous color bar
216 216
 # -grid_height height of each legend grid.
217 217
 # -grid_width width of each legend grid.
218 218
 # -border color for legend grid borders.
... ...
@@ -245,7 +245,7 @@ setMethod(f = "color_mapping_legend",
245 245
 	title = object@name,
246 246
 	title_gp = gpar(fontsize = 10, fontface = "bold"),
247 247
 	title_position = c("topleft", "topcenter", "leftcenter", "lefttop"),
248
-	color_bar = c("discrete", "continuous"),
248
+	color_bar = object@type,
249 249
 	grid_height = unit(4, "mm"),
250 250
 	grid_width = unit(4, "mm"),
251 251
 	border = NULL,
... ...
@@ -268,10 +268,10 @@ setMethod(f = "color_mapping_legend",
268 268
 	title_gp = check_gp(title_gp)
269 269
 	labels_gp = check_gp(labels_gp)
270 270
 
271
-	color_bar = match.arg(color_bar)
271
+	# color_bar = match.arg(color_bar)
272 272
 
273 273
 	if(object@type == "discrete" && color_bar == "continuous") {
274
-		stop("'color_bar' can only be set to 'continuous' only if the color mapping is continuous")
274
+		stop("'color_bar' can only be set to 'discrete' only if the color mapping is discrete")
275 275
 	}
276 276
 
277 277
 	# get labels
... ...
@@ -191,7 +191,7 @@ Heatmap = setClass("Heatmap",
191 191
 # -bottom_annotation_height total height of the column annotations on the bottom.
192 192
 # -km do k-means clustering on rows. If the value is larger than 1, the heatmap will be split by rows according to the k-means clustering.
193 193
 #     For each row-clusters, hierarchical clustering is still applied with parameters above.
194
-# -km_title row title for each cluster when ``km`` is set. It must a text with format of "*\%i*" where "\%i" is replaced by the index of the cluster.
194
+# -km_title row title for each cluster when ``km`` is set. It must a text with format of ".*\%i.*" where "\%i" is replaced by the index of the cluster.
195 195
 # -split a vector or a data frame by which the rows are split. But if ``cluster_rows`` is a clustering object, ``split`` can be a single number
196 196
 #        indicating rows are to be split according to the split on the tree.
197 197
 # -gap gap between row-slices if the heatmap is split by rows, should be `grid::unit` object. If it is a vector, the order corresponds
... ...
@@ -287,7 +287,7 @@ Heatmap = function(matrix, col, name,
287 287
     combined_name_fun = function(x) paste(x, collapse = "/"),
288 288
     width = NULL, 
289 289
     show_heatmap_legend = TRUE,
290
-    heatmap_legend_param = list(title = name, color_bar = "discrete"),
290
+    heatmap_legend_param = list(title = name),
291 291
     use_raster = FALSE, 
292 292
     raster_device = c("png", "jpeg", "tiff", "CairoPNG", "CairoJPEG", "CairoTIFF"),
293 293
     raster_quality = 1,
... ...
@@ -1445,7 +1445,7 @@ setMethod(f = "draw_dend",
1445 1445
 
1446 1446
     dend = as.dendrogram(hc)
1447 1447
     n = length(labels(dend))
1448
-    if(nnodes(dend) <= 1) {
1448
+    if(nobs(dend) <= 1) {
1449 1449
         return(invisible(NULL))
1450 1450
     }
1451 1451
 
... ...
@@ -135,7 +135,6 @@ Legend = function(at, labels = at, nrow = NULL, ncol = 1, col_fun,
135 135
 	# for(i in seq_len(length(odevlist) - length(dev.list()))) {
136 136
 	# 	dev.off()
137 137
 	# }
138
-
139 138
 	return(gf)
140 139
 }
141 140
 
... ...
@@ -44,6 +44,8 @@
44 44
 #
45 45
 decorate_heatmap_body = function(heatmap, code, slice = 1, envir = new.env(parent = parent.frame())) {
46 46
 
47
+	current_vp = current.viewport()$name
48
+	
47 49
 	if(is.null(slice)) {
48 50
 		vp_name = paste0(heatmap, "_heatmap_body_", 1)
49 51
 		seekViewport(vp_name)
... ...
@@ -55,7 +57,7 @@ decorate_heatmap_body = function(heatmap, code, slice = 1, envir = new.env(paren
55 57
 
56 58
 	eval(substitute(code), envir = envir)
57 59
 
58
-	seekViewport("global")
60
+	seekViewport(current_vp)
59 61
 }
60 62
 
61 63
 # == title
... ...
@@ -98,6 +100,8 @@ decorate_heatmap_body = function(heatmap, code, slice = 1, envir = new.env(paren
98 100
 decorate_dend = function(heatmap, code, slice = 1, which = c("column", "row"), 
99 101
 	envir = new.env(parent = parent.frame())) {
100 102
 	
103
+	current_vp = current.viewport()$name
104
+	
101 105
 	which = match.arg(which)[1]
102 106
 	if(which == "column") {
103 107
 		vp_name = paste0(heatmap, "_dend_", which)
... ...
@@ -116,7 +120,7 @@ decorate_dend = function(heatmap, code, slice = 1, which = c("column", "row"),
116 120
 	e = new.env(parent = parent.frame())
117 121
 	eval(substitute(code), envir = e)
118 122
 
119
-	seekViewport("global")
123
+	seekViewport(current_vp)
120 124
 }
121 125
 
122 126
 # == title
... ...
@@ -212,6 +216,8 @@ decorate_row_dend = function(..., envir = new.env(parent = parent.frame())) {
212 216
 decorate_dimnames = function(heatmap, code, slice = 1, which = c("column", "row"), 
213 217
 	envir = new.env(parent = parent.frame())) {
214 218
 	
219
+	current_vp = current.viewport()$name
220
+	
215 221
 	which = match.arg(which)[1]
216 222
 	if(which == "column") {
217 223
 		vp_name = paste0(heatmap, "_", which, "_names")
... ...
@@ -228,7 +234,7 @@ decorate_dimnames = function(heatmap, code, slice = 1, which = c("column", "row"
228 234
 
229 235
 	seekViewport(vp_name)
230 236
 	eval(substitute(code), envir = envir)
231
-	seekViewport("global")
237
+	seekViewport(current_vp)
232 238
 }
233 239
 
234 240
 # == title
... ...
@@ -312,6 +318,8 @@ decorate_column_names = function(..., envir = new.env(parent = parent.frame()))
312 318
 decorate_title = function(heatmap, code, slice = 1, which = c("column", "row"), 
313 319
 	envir = new.env(parent = parent.frame())) {
314 320
 	
321
+	current_vp = current.viewport()$name
322
+	
315 323
 	which = match.arg(which)[1]
316 324
 	if(which == "column") {
317 325
 		vp_name = paste0(heatmap, "_", which, "_title")
... ...
@@ -328,7 +336,7 @@ decorate_title = function(heatmap, code, slice = 1, which = c("column", "row"),
328 336
 
329 337
 	seekViewport(vp_name)
330 338
 	eval(substitute(code), envir = envir)
331
-	seekViewport("global")
339
+	seekViewport(current_vp)
332 340
 }
333 341
 
334 342
 # == title
... ...
@@ -416,6 +424,8 @@ decorate_column_title = function(..., envir = new.env(parent = parent.frame()))
416 424
 #
417 425
 decorate_annotation = function(annotation, code, slice, envir = new.env(parent = parent.frame())) {
418 426
 
427
+	current_vp = current.viewport()$name
428
+	
419 429
 	if(missing(slice)) {
420 430
 		vp_name = paste0("annotation_", annotation)
421 431
 		o = try(seekViewport(vp_name), silent = TRUE)
... ...
@@ -440,6 +450,6 @@ decorate_annotation = function(annotation, code, slice, envir = new.env(parent =
440 450
 	}
441 451
 
442 452
 	eval(substitute(code), envir = envir)
443
-	seekViewport("global")
453
+	seekViewport(current_vp)
444 454
 }
445 455
 
... ...
@@ -16,7 +16,6 @@
16 16
 #                            Set it to ``NULL`` if you don't want to set the order
17 17
 # -column_order order of samples. By default the order is calculated by the 'memo sort' method which can visualize
18 18
 #                                 the mutual exclusivity across genes. Set it to ``NULL`` if you don't want to set the order
19
-# -show_column_names whether show column names
20 19
 # -show_pct whether show percent values on the left of the oncoprint
21 20
 # -pct_gp graphic paramters for percent row annotation
22 21
 # -pct_digits digits for percent values
... ...
@@ -26,8 +25,31 @@
26 25
 # -remove_empty_columns if there is no alteration in that sample, whether remove it on the heatmap
27 26
 # -heatmap_legend_param pass to `Heatmap`
28 27
 # -top_annotation by default the top annotation contains barplots representing frequency of mutations in every sample.
28
+# -top_annotation_height total height of the column annotations on the top.
29
+# -bottom_annotation a `HeatmapAnnotation` object.
30
+# -bottom_annotation_height total height of the column annotations on the bottom.
29 31
 # -barplot_ignore specific alterations that you don't want to put on the barplots. If you want to really suppress the top barplot
30 32
 #        set ``top_annotation`` to ``NULL``.
33
+# -row_title title on row.
34
+# -row_title_side will the title be put on the left or right of the heatmap?
35
+# -row_title_gp graphic parameters for drawing text.
36
+# -row_title_rot rotation of row titles. Only 0, 90, 270 are allowed to set.
37
+# -column_title title on column.
38
+# -column_title_side will the title be put on the top or bottom of the heatmap?
39
+# -column_title_gp graphic parameters for drawing text.
40
+# -column_title_rot rotation of column titles. Only 0, 90, 270 are allowed to set.
41
+# -show_row_names whether show row names.
42
+# -row_names_gp graphic parameters for drawing text.
43
+# -show_column_names whether show column names.
44
+# -column_names_gp graphic parameters for drawing text.
45
+# -split a vector or a data frame by which the rows are split. But if ``cluster_rows`` is a clustering object, ``split`` can be a single number
46
+#        indicating rows are to be split according to the split on the tree.
47
+# -gap gap between row-slices if the heatmap is split by rows, should be `grid::unit` object. If it is a vector, the order corresponds
48
+#   to top to bottom in the heatmap
49
+# -combined_name_fun if the heatmap is split by rows, how to make a combined row title for each slice?
50
+#                 The input parameter for this function is a vector which contains level names under each column in ``split``.
51
+# -width the width of the single heatmap, should be a fixed `grid::unit` object. It is used for the layout when the heatmap
52
+#        is appended to a list of heatmaps.
31 53
 # -... pass to `Heatmap`, so can set ``bottom_annotation`` here.
32 54
 #
33 55
 # == details
... ...
@@ -51,8 +73,7 @@ oncoPrint = function(mat, get_type = function(x) x,
51 73
 	alter_fun = alter_fun_list, alter_fun_list = NULL, col, 
52 74
 	row_order = oncoprint_row_order(),
53 75
 	column_order = oncoprint_column_order(),
54
-	show_column_names = FALSE,
55
-	show_pct = TRUE, pct_gp = gpar(), pct_digits = 0,
76
+	show_pct = TRUE, pct_gp = row_names_gp, pct_digits = 0,
56 77
 	axis_gp = gpar(fontsize = 8), 
57 78
 	show_row_barplot = TRUE, 
58 79
 	row_barplot_width = unit(2, "cm"),
... ...
@@ -60,7 +81,26 @@ oncoPrint = function(mat, get_type = function(x) x,
60 81
 	heatmap_legend_param = list(title = "Alterations"),
61 82
 	top_annotation = HeatmapAnnotation(column_bar = anno_oncoprint_barplot(), 
62 83
 		annotation_height = unit(2, "cm")),
63
-	barplot_ignore = NULL,
84
+	top_annotation_height = top_annotation@size,
85
+	bottom_annotation = new("HeatmapAnnotation"),
86
+    bottom_annotation_height = bottom_annotation@size,
87
+    barplot_ignore = NULL,
88
+	row_title = character(0),
89
+    row_title_side = c("left", "right"),
90
+    row_title_gp = gpar(fontsize = 14),
91
+    row_title_rot = switch(row_title_side[1], "left" = 90, "right" = 270),
92
+    column_title = character(0),
93
+    column_title_side = c("top", "bottom"),
94
+    column_title_gp = gpar(fontsize = 14),
95
+    column_title_rot = 0,
96
+    show_row_names = TRUE,
97
+    row_names_gp = gpar(fontsize = 12),
98
+    show_column_names = FALSE,
99
+    column_names_gp = gpar(fontsize = 12),
100
+    split = NULL,
101
+    gap = unit(1, "mm"),
102
+    combined_name_fun = function(x) paste(x, collapse = "/"),
103
+    width = NULL,
64 104
 	...) {
65 105
 
66 106
 	if(length(names(list(...))) > 0) {
... ...
@@ -282,9 +322,29 @@ oncoPrint = function(mat, get_type = function(x) x,
282 322
 			z = arr[i, j, ]
283 323
 			names(z) = dimnames(arr)[[3]]
284 324
 			af(x, y, width, height, z)
285
-		}, show_column_names = show_column_names,
325
+		},
286 326
 		top_annotation = top_annotation,
287
-		heatmap_legend_param = heatmap_legend_param, ...)
327
+		top_annotation_height = top_annotation_height,
328
+		bottom_annotation = bottom_annotation,
329
+		bottom_annotation_height = bottom_annotation_height,
330
+		row_title = row_title,
331
+		row_title_side = row_title_side,
332
+		row_title_gp = row_names_gp,
333
+		row_title_rot = row_title_rot,
334
+		column_title = column_title,
335
+		column_title_side = column_title_side,
336
+		column_title_gp = column_title_gp,
337
+		column_title_rot = column_title_rot,
338
+		show_row_names = show_row_names,
339
+		row_names_gp = row_names_gp,
340
+		show_column_names = show_column_names,
341
+		column_names_gp = column_names_gp,
342
+		heatmap_legend_param = heatmap_legend_param, 
343
+		split = split,
344
+		gap = gap,
345
+		combined_name_fun = combined_name_fun,
346
+		width = width,
347
+		...)
288 348
 
289 349
 	ht@matrix_param$oncoprint = list()
290 350
 	ht@matrix_param$oncoprint$arr = arr
... ...
@@ -2,11 +2,20 @@
2 2
 # environment that contains global variables
3 3
 INDEX_ENV = new.env()
4 4
 
5
+INDEX_ENV$I_FIGURE = 0
5 6
 INDEX_ENV$I_HEATMAP = 0
6 7
 INDEX_ENV$I_ANNOTATION = 0
7 8
 INDEX_ENV$I_ROW_ANNOTATION = 0
8 9
 INDEX_ENV$I_COLOR_MAPPING = 0
9 10
 
11
+get_figure_index = function() {
12
+    INDEX_ENV$I_FIGURE
13
+}
14
+
15
+increase_figure_index = function() {
16
+    INDEX_ENV$I_FIGURE = INDEX_ENV$I_FIGURE + 1
17
+}
18
+
10 19
 get_heatmap_index = function() {
11 20
 	INDEX_ENV$I_HEATMAP
12 21
 }
... ...
@@ -124,8 +133,6 @@ grid.dendrogram = function(dend, facing = c("bottom", "top", "left", "right"),
124 133
             leaf
125 134
         }
126 135
     }
127
-
128
-    labels(dend) = paste0("leaf_", seq_len(nnodes(dend)))
129 136
     
130 137
     draw.d = function(dend, max_height, facing = "bottom", order = "normal", max_width = 0, env = NULL) {
131 138
         leaf = attr(dend, "leaf")
... ...
@@ -275,6 +282,287 @@ grid.dendrogram = function(dend, facing = c("bottom", "top", "left", "right"),
275 282
     }
276 283
 }
277 284
 
285
+# == title
286
+# Adjust dendrogram based on width of leaves
287
+#
288
+# == param
289
+# -dend a `stats::dendrogram` object.
290
+# -width a vector of width. The order of width SHOULD be same as the order of original elements before clustering.
291
+# -offset offset to x = 0
292
+#
293
+# == details
294
+# In the standard `stats::dendrogram` object, leaves locate at x = 0.5, 1.5, ..., n - 0.5,
295
+# which means, the width of leaves are always 1 and the distance to neighbouring leaves is always 1 as well.
296
+# Here `adjust_dend_by_leaf_width` adjusts the dendrogram by setting different width for leaves so that leaves
297
+# have unequal distance to other leaves.
298
+#
299
+# The adjusted dendrogram can be sent to `grid.dendrogram2` to make the dendrogram.
300
+#
301
+# For each branch as well each leaf, a new attribute of ``x`` is added which is the position of the middle point or the leaf.
302
+# For each leaf, a new attribute of ``width`` is added which is the width of current leaf.
303
+#
304
+# == value
305
+# A `stats::dendrogram` object. The adjustment will not affect other standard dendrogram functions.
306
+#
307
+# == author
308
+# Zuguang Gu <z.gu@dkfz.de>
309
+#
310
+# == example
311
+# m = matrix(rnorm(100), 10)
312
+# dend = as.dendrogram(hclust(dist(m)))
313
+# dend = adjust_dend_by_leaf_width(dend, width = 1:10)
314
+# require(dendextend)
315
+# get_leaves_attr(dend, "label")
316
+# get_leaves_attr(dend, "width")
317
+# get_leaves_attr(dend, "x")
318
+adjust_dend_by_leaf_width = function(dend, width = 1, offset = 0) {
319
+    n = nobs(dend)
320
+
321
+    if(length(width) == 1) {
322
+        width = rep(width, n)
323
+    }
324
+
325
+    if(identical(width, rep(1, n))) {
326
+        return(dend)
327
+    }
328
+
329
+    if(length(width) != n) {
330
+        stop("length of `width` should be same as `dend`.")
331
+    }
332
+
333
+    dend_order = order.dendrogram(dend)
334
+    leaves_pos = cumsum(width[dend_order]) - width[dend_order]/2 + offset
335
+    label2index = structure(dend_order, names = labels(dend))
336
+
337
+    env = new.env()
338
+    env$dend = dend
339
+
340
+    adj_dend = function(ind = NULL) {
341
+        if(is.null(ind)) {
342
+            d = env$dend
343
+        } else {
344
+            d = env$dend[[ind]]
345
+        }
346
+        
347
+        if(is.leaf(d)) {
348
+            i = which(labels(dend) == attr(d, "label"))
349
+            x = leaves_pos[i]
350
+            attr(env$dend[[ind]], "width") = width[dend_order[i]]
351
+        } else {
352
+            x = ( adj_dend(c(ind, 1)) + adj_dend(c(ind, 2)) )/2
353
+        }
354
+
355
+        if(is.null(ind)) {
356
+            attr(env$dend, "x") = x
357
+        } else {
358
+            attr(env$dend[[ind]], "x") = x
359
+        }
360
+        return(x)
361
+    }
362
+
363
+    adj_dend()
364
+    attr(env$dend, "width_adjusted") = TRUE
365
+    attr(env$dend, "offset") = offset
366
+
367
+    return(env$dend)
368
+}
369
+
370
+
371
+# == title
372
+# Draw dendrogram under grid system
373
+#
374
+# == param
375
+# -dend a `stats::dendrogram` object which has been adjusted by `adjust_dend_by_leaf_width`, or else
376
+#      it will be sent back to `grid.dendrogram`.
377
+# -facing same as in `grid.dendrogram`.
378
+# -max_height same as in `grid.dendrogram`.
379
+# -order same as in `grid.dendrogram`.
380
+# -... same as in `grid.dendrogram`.
381
+#
382
+# == author
383
+# Zuguang gu <z.gu@dkfz.de>
384
+#
385
+# == example
386
+# m = matrix(rnorm(100), 10)
387
+# dend = as.dendrogram(hclust(dist(m)))
388
+# dend = adjust_dend_by_leaf_width(dend, width = 1:10)
389
+# grid.dendrogram2(dend)
390
+grid.dendrogram2 = function(dend, facing = c("bottom", "top", "left", "right"), 
391
+    max_height = NULL, order = c("normal", "reverse"), ...) {
392
+
393
+    if(is.null(attr(dend, "width_adjusted"))) {
394
+        grid.dendrogram(dend, facing = facing, max_height = max_height, order = order, ...)
395
+        return(invisible(NULL))
396
+    }
397
+    
398
+    facing = match.arg(facing)[1]
399
+
400
+    if(is.null(max_height)) {
401
+        max_height = attr(dend, "height")
402
+    }
403
+    
404
+    if(max_height == 0) {
405
+        return(invisible(NULL))
406
+    }
407
+
408
+    is.leaf = function(object) {
409
+        leaf = attr(object, "leaf")
410
+        if(is.null(leaf)) {
411
+            FALSE
412
+        } else {
413
+            leaf
414
+        }
415
+    }
416
+    
417
+    draw.d = function(dend, max_height, facing = "bottom", order = "normal", max_width = 0, env = NULL) {
418
+
419
+        d1 = dend[[1]]  # child tree 1
420
+        d2 = dend[[2]]  # child tree 2
421
+        height = attr(dend, "height")
422
+        
423
+        x1 = attr(d1, "x")
424
+        y1 = attr(d1, "height")
425
+        
426
+        x2 = attr(d2, "x")
427
+        y2 = attr(d2, "height")
428
+        midpoint = (x1 + x2)/2
429
+
430
+        # graphic parameters for current branch
431
+        edge_gp1 = as.list(attr(d1, "edgePar"))
432
+        edge_gp2 = as.list(attr(d2, "edgePar"))
433
+
434
+        if(is.null(env)) {
435
+            begin = TRUE
436
+            env = new.env()
437
+            n = nobs(dend)
438
+            env$x0 = NULL
439
+            env$y0 = NULL
440
+            env$x1 = NULL
441
+            env$y1 = NULL
442
+            env$col = NULL
443
+            env$lty = NULL
444
+            env$lwd = NULL
445
+        } else {
446
+            begin = FALSE
447
+        }
448
+
449
+        for(gp_name in c("col", "lwd", "lty")) {
450
+            if(is.null(edge_gp1[[gp_name]])) {
451
+                env[[gp_name]] = c(env[[gp_name]], rep(get.gpar(gp_name)[[gp_name]], 2))
452
+            } else {
453
+                env[[gp_name]] = c(env[[gp_name]], rep(edge_gp1[[gp_name]], 2))
454
+            }
455
+            if(is.null(edge_gp2[[gp_name]])) {
456
+                env[[gp_name]] = c(env[[gp_name]], rep(get.gpar(gp_name)[[gp_name]], 2))
457
+            } else {
458
+                env[[gp_name]] = c(env[[gp_name]], rep(edge_gp2[[gp_name]], 2))
459
+            }
460
+        }
461
+
462
+        # plot the connection line
463
+        if(order == "normal") {
464
+            if(facing == "bottom") {
465
+                # grid.lines(c(x1, x1, (x1+x2)/2), c(y1, height, height), default.units = "native", gp = edge_gp1)
466
+                # grid.lines(c(x2, x2, (x1+x2)/2), c(y2, height, height), default.units = "native", gp = edge_gp2)
467
+                env$x0 = c(env$x0, c(x1, x1, x2, x2))
468
+                env$y0 = c(env$y0, c(y1, height, y2, height))
469
+                env$x1 = c(env$x1, c(x1, (x1+x2)/2, x2, (x1+x2)/2))
470
+                env$y1 = c(env$y1, c(height, height, height, height))
471
+            } else if(facing == "top") {
472
+                # grid.lines(c(x1, x1, (x1+x2)/2), max_height - c(y1, height, height), default.units = "native", gp = edge_gp1)
473
+                # grid.lines(c(x2, x2, (x1+x2)/2), max_height - c(y2, height, height), default.units = "native", gp = edge_gp2)
474
+                env$x0 = c(env$x0, c(x1, x1, x2, x2))
475
+                env$y0 = c(env$y0, max_height - c(y1, height, y2, height))
476
+                env$x1 = c(env$x1, c(x1, (x1+x2)/2, x2, (x1+x2)/2))
477
+                env$y1 = c(env$y1, max_height - c(height, height, height, height))
478
+            } else if(facing == "right") {
479
+                # grid.lines(max_height - c(y1, height, height), c(x1, x1, (x1+x2)/2), default.units = "native", gp = edge_gp1)
480
+                # grid.lines(max_height - c(y2, height, height), c(x2, x2, (x1+x2)/2), default.units = "native", gp = edge_gp2)
481
+                env$x0 = c(env$x0, max_height - c(y1, height, y2, height))
482
+                env$y0 = c(env$y0, c(x1, x1, x2, x2))
483
+                env$x1 = c(env$x1, max_height - c(height, height, height, height))
484
+                env$y1 = c(env$y1, c(x1, (x1+x2)/2, x2, (x1+x2)/2))
485
+            } else if(facing == "left") {
486
+                # grid.lines(c(y1, height, height), c(x1, x1, (x1+x2)/2), default.units = "native", gp = edge_gp1)
487
+                # grid.lines(c(y2, height, height), c(x2, x2, (x1+x2)/2), default.units = "native", gp = edge_gp2)
488
+                env$x0 = c(env$x0, c(y1, height, y2, height))
489
+                env$y0 = c(env$y0, c(x1, x1, x2, x2))
490
+                env$x1 = c(env$x1, c(height, height, height, height))
491
+                env$y1 = c(env$y1, c(x1, (x1+x2)/2, x2, (x1+x2)/2))
492
+            }
493
+        } else {
494
+            if(facing == "bottom") {
495
+                # grid.lines(max_width - c(x1, x1, (x1+x2)/2), c(y1, height, height), default.units = "native", gp = edge_gp1)
496
+                # grid.lines(max_width - c(x2, x2, (x1+x2)/2), c(y2, height, height), default.units = "native", gp = edge_gp2)
497
+                env$x0 = c(env$x0, max_width - c(x1, x1, x2, x2))
498
+                env$y0 = c(env$y0, c(y1, height, y2, height))
499
+                env$x1 = c(env$x1, max_width - c(x1, (x1+x2)/2, x2, (x1+x2)/2))
500
+                env$y1 = c(env$y1, c(height, height, height, height))
501
+            } else if(facing == "top") {
502
+                # grid.lines(max_width - c(x1, x1, (x1+x2)/2), max_height - c(y1, height, height), default.units = "native", gp = edge_gp1)
503
+                # grid.lines(max_width - c(x2, x2, (x1+x2)/2), max_height - c(y2, height, height), default.units = "native", gp = edge_gp2)
504
+                env$x0 = c(env$x0, max_width - c(x1, x1, x2, x2))
505
+                env$y0 = c(env$y0, max_height - c(y1, height, y2, height))
506
+                env$x1 = c(env$x1, max_width - c(x1, (x1+x2)/2, x2, (x1+x2)/2))
507
+                env$y1 = c(env$y1, max_height - c(height, height, height, height))
508
+            } else if(facing == "right") {
509
+                # grid.lines(max_height - c(y1, height, height), max_width - c(x1, x1, (x1+x2)/2), default.units = "native", gp = edge_gp1)
510
+                # grid.lines(max_height - c(y2, height, height), max_width - c(x2, x2, (x1+x2)/2), default.units = "native", gp = edge_gp2)
511
+                env$x0 = c(env$x0, max_height - c(y1, height, y2, height))
512
+                env$y0 = c(env$y0, max_width - c(x1, x1, x2, x2))
513
+                env$x1 = c(env$x1, max_height - c(height, height, height, height))
514
+                env$y1 = c(env$y1, max_width - c(x1, (x1+x2)/2, x2, (x1+x2)/2))
515
+            } else if(facing == "left") {
516
+                # grid.lines(c(y1, height, height), max_width - c(x1, x1, (x1+x2)/2), default.units = "native", gp = edge_gp1)
517
+                # grid.lines(c(y2, height, height), max_width - c(x2, x2, (x1+x2)/2), default.units = "native", gp = edge_gp2)
518
+                env$x0 = c(env$x0, c(y1, height, y2, height))
519
+                env$y0 = c(env$y0, max_width - c(x1, x1, x2, x2))
520
+                env$x1 = c(env$x1, c(height, height, height, height))
521
+                env$y1 = c(env$y1, max_width - c(x1, (x1+x2)/2, x2, (x1+x2)/2))
522
+            }
523
+        }
524
+        # do it recursively
525
+        if(!is.leaf(d1)) {
526
+            draw.d(d1, max_height, facing, order, max_width, env = env)
527
+        } else {
528
+            grid.rect(x1, width = attr(d1, "width"), default.units = "native", gp = gpar(fill = rand_color(1, transparency = 0.5)))
529
+        }
530
+        if(!is.leaf(d2)) {
531
+            draw.d(d2, max_height, facing, order, max_width, env = env)
532
+        } else {
533
+            grid.rect(x2, width = attr(d2, "width"), default.units = "native", gp = gpar(fill = rand_color(1, transparency = 0.5)))
534
+        }
535
+
536
+        if(begin) {
537
+            grid.segments(env$x0, env$y0, env$x1, env$y1, default.units = "native", gp = gpar(col = env$col, lty = env$lty, lwd = env$lwd))
538
+        }
539
+    }
540
+
541
+    sum_width = sum(.get_leaves_width(dend))
542
+    order = match.arg(order)[1]
543
+    offset = attr(dend, "offset")
544
+    
545
+    if(facing %in% c("top", "bottom")) {
546
+        pushViewport(viewport(xscale = c(0, sum_width) + offset, yscale = c(0, max_height), ...))
547
+        draw.d(dend, max_height, facing, order, max_width = sum_width)
548
+        upViewport()
549
+    } else if(facing %in% c("right", "left")) {
550
+        pushViewport(viewport(yscale = c(0, sum_width) + offset, xscale = c(0, max_height), ...))
551
+        draw.d(dend, max_height, facing, order, max_width = sum_width)
552
+        upViewport()
553
+    }
554
+}
555
+
556
+.get_leaves_width = function(d, v = NULL) {
557
+    if(is.leaf(d)) {
558
+        v = c(v, attr(d, "width"))
559
+    } else {
560
+        v = .get_leaves_width(d[[1]], v)
561
+        v = .get_leaves_width(d[[2]], v)
562
+    }
563
+    return(v)
564
+}
565
+
278 566
 # == title
279 567
 # Calculate pairwise distance from a matrix
280 568
 #
... ...
@@ -366,12 +654,21 @@ get_dend_order = function(x) {
366 654
 
367 655
 # can only cut dendrogram for which branches at every node are two
368 656
 cut_dendrogram = function(dend, k) {
369
-    h = sort(get_branches_heights(dend), decreasing = TRUE)
657
+    h = sort(dend_branches_heights(dend), decreasing = TRUE)
370 658
     height = (h[k-1] + h[k])/2
371 659
     trees = cut(dend, h = height)
372 660
     trees$lower
373 661
 }
374 662
 
663
+dend_branches_heights = function(d, v = NULL) {
664
+    if(!is.leaf(d)) {
665
+        v = c(v, attr(d, "height"))
666
+        v = dend_branches_heights(d[[1]], v)
667
+        v = dend_branches_heights(d[[2]], v)
668
+    }
669
+    return(v)
670
+}
671
+
375 672
 recycle_gp = function(gp, n = 1) {
376 673
     for(i in seq_along(gp)) {
377 674
         x = gp[[i]]
... ...
@@ -67,7 +67,7 @@ Heatmap(matrix, col, name,
67 67
     combined_name_fun = function(x) paste(x, collapse = "/"),
68 68
     width = NULL,
69 69
     show_heatmap_legend = TRUE,
70
-    heatmap_legend_param = list(title = name, color_bar = "discrete"),
70
+    heatmap_legend_param = list(title = name),
71 71
     use_raster = FALSE,
72 72
     raster_device = c("png", "jpeg", "tiff", "CairoPNG", "CairoJPEG", "CairoTIFF"),
73 73
     raster_quality = 1,
... ...
@@ -131,7 +131,7 @@ Heatmap(matrix, col, name,
131 131
   \item{bottom_annotation}{a \code{\link{HeatmapAnnotation}} object.}
132 132
   \item{bottom_annotation_height}{total height of the column annotations on the bottom.}
133 133
   \item{km}{do k-means clustering on rows. If the value is larger than 1, the heatmap will be split by rows according to the k-means clustering. For each row-clusters, hierarchical clustering is still applied with parameters above.}
134
-  \item{km_title}{row title for each cluster when \code{km} is set. It must a text with format of "*\%i*" where "\%i" is replaced by the index of the cluster.}
134
+  \item{km_title}{row title for each cluster when \code{km} is set. It must a text with format of ".*\%i.*" where "\%i" is replaced by the index of the cluster.}
135 135
   \item{split}{a vector or a data frame by which the rows are split. But if \code{cluster_rows} is a clustering object, \code{split} can be a single number indicating rows are to be split according to the split on the tree.}
136 136
   \item{gap}{gap between row-slices if the heatmap is split by rows, should be \code{\link[grid]{unit}} object. If it is a vector, the order corresponds to top to bottom in the heatmap}
137 137
   \item{combined_name_fun}{if the heatmap is split by rows, how to make a combined row title for each slice? The input parameter for this function is a vector which contains level names under each column in \code{split}.}
138 138
new file mode 100644
... ...
@@ -0,0 +1,44 @@
1
+\name{adjust_dend_by_leaf_width}
2
+\alias{adjust_dend_by_leaf_width}
3
+\title{
4
+Adjust dendrogram based on width of leaves
5
+}
6
+\description{
7
+Adjust dendrogram based on width of leaves
8
+}
9
+\usage{
10
+adjust_dend_by_leaf_width(dend, width = 1, offset = 0)
11
+}
12
+\arguments{
13
+
14
+  \item{dend}{a \code{\link[stats]{dendrogram}} object.}
15
+  \item{width}{a vector of width. The order of width SHOULD be same as the order of original elements before clustering.}
16
+  \item{offset}{offset to x = 0}
17
+
18
+}
19
+\details{
20
+In the standard \code{\link[stats]{dendrogram}} object, leaves locate at x = 0.5, 1.5, ..., n - 0.5,
21
+which means, the width of leaves are always 1 and the distance to neighbouring leaves is always 1 as well.
22
+Here \code{\link{adjust_dend_by_leaf_width}} adjusts the dendrogram by setting different width for leaves so that leaves
23
+have unequal distance to other leaves.
24
+
25
+The adjusted dendrogram can be sent to \code{\link{grid.dendrogram2}} to make the dendrogram.
26
+
27
+For each branch as well each leaf, a new attribute of \code{x} is added which is the position of the middle point or the leaf.
28
+For each leaf, a new attribute of \code{width} is added which is the width of current leaf.
29
+}
30
+\value{
31
+A \code{\link[stats]{dendrogram}} object. The adjustment will not affect other standard dendrogram functions.
32
+}
33
+\author{
34
+Zuguang Gu <z.gu@dkfz.de>
35
+}
36
+\examples{
37
+m = matrix(rnorm(100), 10)
38
+dend = as.dendrogram(hclust(dist(m)))
39
+dend = adjust_dend_by_leaf_width(dend, width = 1:10)
40
+require(dendextend)
41
+get_leaves_attr(dend, "label")
42
+get_leaves_attr(dend, "width")
43
+get_leaves_attr(dend, "x")
44
+}
... ...
@@ -13,7 +13,7 @@ Draw legend based on color mapping
13 13
     title = object@name,
14 14
     title_gp = gpar(fontsize = 10, fontface = "bold"),
15 15
     title_position = c("topleft", "topcenter", "leftcenter", "lefttop"),
16
-    color_bar = c("discrete", "continuous"),
16
+    color_bar = object@type,
17 17
     grid_height = unit(4, "mm"),
18 18
     grid_width = unit(4, "mm"),
19 19
     border = NULL,
... ...
@@ -33,7 +33,7 @@ Draw legend based on color mapping
33 33
   \item{title}{title of the legend, by default it is the name of the legend}
34 34
   \item{title_gp}{graphical parameters for legend title}
35 35
   \item{title_position}{position of the title}
36
-  \item{color_bar}{if the mapping is continuous, whether show the legend as discrete color bar or continuous color bar}
36
+  \item{color_bar}{a string of "continous" or "discrete". If the mapping is continuous, whether show the legend as discrete color bar or continuous color bar}
37 37
   \item{grid_height}{height of each legend grid.}
38 38
   \item{grid_width}{width of each legend grid.}
39 39
   \item{border}{color for legend grid borders.}
40 40
new file mode 100644
... ...
@@ -0,0 +1,30 @@
1
+\name{grid.dendrogram2}
2
+\alias{grid.dendrogram2}
3
+\title{
4
+Draw dendrogram under grid system
5
+}
6
+\description{
7
+Draw dendrogram under grid system
8
+}
9
+\usage{
10
+grid.dendrogram2(dend, facing = c("bottom", "top", "left", "right"),
11
+    max_height = NULL, order = c("normal", "reverse"), ...)
12
+}
13
+\arguments{
14
+
15
+  \item{dend}{a \code{\link[stats]{dendrogram}} object which has been adjusted by \code{\link{adjust_dend_by_leaf_width}}, or else it will be sent back to \code{\link{grid.dendrogram}}.}
16
+  \item{facing}{same as in \code{\link{grid.dendrogram}}.}
17
+  \item{max_height}{same as in \code{\link{grid.dendrogram}}.}
18
+  \item{order}{same as in \code{\link{grid.dendrogram}}.}
19
+  \item{...}{same as in \code{\link{grid.dendrogram}}.}
20
+
21
+}
22
+\author{
23
+Zuguang gu <z.gu@dkfz.de>
24
+}
25
+\examples{
26
+m = matrix(rnorm(100), 10)
27
+dend = as.dendrogram(hclust(dist(m)))
28
+dend = adjust_dend_by_leaf_width(dend, width = 1:10)
29
+grid.dendrogram2(dend)
30
+}
... ...
@@ -11,8 +11,7 @@ oncoPrint(mat, get_type = function(x) x,
11 11
     alter_fun = alter_fun_list, alter_fun_list = NULL, col,
12 12
     row_order = oncoprint_row_order(),
13 13
     column_order = oncoprint_column_order(),
14
-    show_column_names = FALSE,
15
-    show_pct = TRUE, pct_gp = gpar(), pct_digits = 0,
14
+    show_pct = TRUE, pct_gp = row_names_gp, pct_digits = 0,
16 15
     axis_gp = gpar(fontsize = 8),
17 16
     show_row_barplot = TRUE,
18 17
     row_barplot_width = unit(2, "cm"),
... ...
@@ -20,7 +19,26 @@ oncoPrint(mat, get_type = function(x) x,
20 19
     heatmap_legend_param = list(title = "Alterations"),
21 20
     top_annotation = HeatmapAnnotation(column_bar = anno_oncoprint_barplot(),
22 21
     annotation_height = unit(2, "cm")),
22
+    top_annotation_height = top_annotation@size,
23
+    bottom_annotation = new("HeatmapAnnotation"),
24
+    bottom_annotation_height = bottom_annotation@size,
23 25
     barplot_ignore = NULL,
26
+    row_title = character(0),
27
+    row_title_side = c("left", "right"),
28
+    row_title_gp = gpar(fontsize = 14),
29
+    row_title_rot = switch(row_title_side[1], "left" = 90, "right" = 270),
30
+    column_title = character(0),
31
+    column_title_side = c("top", "bottom"),
32
+    column_title_gp = gpar(fontsize = 14),
33
+    column_title_rot = 0,
34
+    show_row_names = TRUE,
35
+    row_names_gp = gpar(fontsize = 12),
36
+    show_column_names = FALSE,
37
+    column_names_gp = gpar(fontsize = 12),
38
+    split = NULL,
39
+    gap = unit(1, "mm"),
40
+    combined_name_fun = function(x) paste(x, collapse = "/"),
41
+    width = NULL,
24 42
     ...)
25 43
 }
26 44
 \arguments{
... ...
@@ -32,7 +50,6 @@ oncoPrint(mat, get_type = function(x) x,
32 50
   \item{col}{a vector of color for which names correspond to alteration types.}
33 51
   \item{row_order}{order of genes. By default it is sorted by frequency of alterations decreasingly. Set it to \code{NULL} if you don't want to set the order}
34 52
   \item{column_order}{order of samples. By default the order is calculated by the 'memo sort' method which can visualize the mutual exclusivity across genes. Set it to \code{NULL} if you don't want to set the order}
35
-  \item{show_column_names}{whether show column names}
36 53
   \item{show_pct}{whether show percent values on the left of the oncoprint}
37 54
   \item{pct_gp}{graphic paramters for percent row annotation}
38 55
   \item{pct_digits}{digits for percent values}
... ...
@@ -42,7 +59,26 @@ oncoPrint(mat, get_type = function(x) x,
42 59
   \item{remove_empty_columns}{if there is no alteration in that sample, whether remove it on the heatmap}
43 60
   \item{heatmap_legend_param}{pass to \code{\link{Heatmap}}}
44 61
   \item{top_annotation}{by default the top annotation contains barplots representing frequency of mutations in every sample.}
62
+  \item{top_annotation_height}{total height of the column annotations on the top.}
63
+  \item{bottom_annotation}{a \code{\link{HeatmapAnnotation}} object.}
64
+  \item{bottom_annotation_height}{total height of the column annotations on the bottom.}
45 65
   \item{barplot_ignore}{specific alterations that you don't want to put on the barplots. If you want to really suppress the top barplot set \code{top_annotation} to \code{NULL}.}
66
+  \item{row_title}{title on row.}
67
+  \item{row_title_side}{will the title be put on the left or right of the heatmap?}
68
+  \item{row_title_gp}{graphic parameters for drawing text.}
69
+  \item{row_title_rot}{rotation of row titles. Only 0, 90, 270 are allowed to set.}
70
+  \item{column_title}{title on column.}
71
+  \item{column_title_side}{will the title be put on the top or bottom of the heatmap?}
72
+  \item{column_title_gp}{graphic parameters for drawing text.}
73
+  \item{column_title_rot}{rotation of column titles. Only 0, 90, 270 are allowed to set.}
74
+  \item{show_row_names}{whether show row names.}
75
+  \item{row_names_gp}{graphic parameters for drawing text.}
76
+  \item{show_column_names}{whether show column names.}
77
+  \item{column_names_gp}{graphic parameters for drawing text.}
78
+  \item{split}{a vector or a data frame by which the rows are split. But if \code{cluster_rows} is a clustering object, \code{split} can be a single number indicating rows are to be split according to the split on the tree.}
79
+  \item{gap}{gap between row-slices if the heatmap is split by rows, should be \code{\link[grid]{unit}} object. If it is a vector, the order corresponds to top to bottom in the heatmap}
80
+  \item{combined_name_fun}{if the heatmap is split by rows, how to make a combined row title for each slice? The input parameter for this function is a vector which contains level names under each column in \code{split}.}
81
+  \item{width}{the width of the single heatmap, should be a fixed \code{\link[grid]{unit}} object. It is used for the layout when the heatmap is appended to a list of heatmaps.}
46 82
   \item{...}{pass to \code{\link{Heatmap}}, so can set \code{bottom_annotation} here.}
47 83
 
48 84
 }
... ...
@@ -157,32 +157,36 @@ ht1 = Heatmap(mat, name = "ht1", show_heatmap_legend = FALSE)
157 157
 draw(ht1 + ha_chr, heatmap_legend_side = "bottom")
158 158
 ```
159 159
 
160
-If you don't like the default discrete color bar for continuous values, you can specify `color_bar` to `continuous`.
161
-For the simple annotation which contains continuous values, `color_bar` can also be set to `continuous`.
160
+Discrete color bar for can be used for continuous values, if you specify `color_bar` to `discrete`.
161
+For the simple annotation which contains continuous values, `color_bar` can also be set to `discrete`.
162 162
 
163 163
 ```{r}
164 164
 ha = HeatmapAnnotation(df = data.frame(value = runif(10)), 
165 165
     col = list(value = colorRamp2(c(0, 1), c("white", "blue"))), 
166
-    annotation_legend_param = list(color_bar = "continuous", at = c(0, 0.5, 1), 
167
-        labels = c("low", "median", "high"), legend_height = unit(4, "cm")))
168
-Heatmap(mat, name = "ht1", top_annotation = ha, heatmap_legend_param = list(color_bar = "continuous"))
166
+    annotation_legend_param = list(color_bar = "discrete", at = c(0, 0.5, 1)))
167
+Heatmap(mat, name = "ht1", top_annotation = ha, heatmap_legend_param = list(color_bar = "discrete"))
169 168
 ```
170 169
 
171 170
 Some users prefer to put the legend at the bottom of heatmaps.
172 171
 
173 172
 ```{r}
174
-ht = Heatmap(mat, name = "ht1", heatmap_legend_param = list(color_bar = "continuous", legend_direction = "horizontal",
173
+ht = Heatmap(mat, name = "ht1", heatmap_legend_param = list(legend_direction = "horizontal",
175 174
     legend_width = unit(5, "cm"), title_position = "lefttop"))
176 175
 draw(ht, heatmap_legend_side = "bottom")
177 176
 ```
178 177
 
178
+Similarly, the height of the legend can be adjusted by `legend_height` if the legend is vertical.
179
+
180
+```{r}
181
+Heatmap(mat, name = "ht1", heatmap_legend_param = list(legend_height = unit(5, "cm")))
182
+```
183
+
179 184
 If you want to change default settings for all heatmaps/annotations, you can set it globally by `ht_global_opt()`.
180 185
 
181 186
 ```{r, fig.width = 10}
182 187
 ht_global_opt(heatmap_legend_title_gp = gpar(fontsize = 16), annotation_legend_labels_gp = gpar(fontface = "italic"))
183 188
 ha = HeatmapAnnotation(df = data.frame(value = runif(10)), 
184
-    col = list(value = colorRamp2(c(0, 1), c("white", "blue"))), 
185
-    annotation_legend_param = list(color_bar = "continuous"))
189
+    col = list(value = colorRamp2(c(0, 1), c("white", "blue"))))
186 190
 ht1 = Heatmap(mat, name = "ht1", column_title = "Heatmap 1", top_annotation = ha)
187 191
 ht2 = Heatmap(mat, name = "ht2", column_title = "Heatmap 2", heatmap_legend_param = list(title_gp = gpar(fontsize = 8)))
188 192
 ht1 + ht2