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