Browse code

add documentations

Zuguang Gu authored on 04/09/2018 20:01:49
Showing10 changed files

... ...
@@ -1,3 +1,11 @@
1
+
2
+# == title
3
+# AnnotationFunction class
4
+#
5
+# == details
6
+# THe AnnotationFunction class is a wrapper of user-defined annotation functions.
7
+# See `AnnotationFunction` constructor for details
8
+#
1 9
 AnnotationFunction = setClass("AnnotationFunction",
2 10
 	slots = list(
3 11
 		which = "character",
... ...
@@ -60,6 +68,27 @@ anno_width_and_height = function(which, width = NULL, height = NULL,
60 68
 }
61 69
 
62 70
 
71
+# == title
72
+# Constructor of AnnotationFunction class
73
+#
74
+# == param
75
+# -fun A function which defines how to draw annotation. See **Details** section.
76
+# -fun_name The name of the function. It is only used for `show,AnnotationFunction-method`.
77
+# -which Whether it is drawn as a column annotation or a row annotation?
78
+# -var_imported The name of the object or the objects themselves that the annotation function depends on. See **Details** section.
79
+# -n Number of observations in the annotation. It is not mandatory, but it is better to provide this information.
80
+# -data_scale The data scale on the data axis (y-axis for column annotation and x-axis for row annotation). It is only used
81
+#             when `decoration_annotation` is used with "native" unit coordinates.
82
+# -subset_rule The rule of subsetting variables in ``var_import``. It should be set when users want the final object to
83
+#              be subsetable. See **Details** section.
84
+# -subsetable Whether the object is subsetable?
85
+# -width The width of the plotting region (the viewport) that the annotation is drawn. If it is a row annotation,
86
+#        the width must be an absolute unit.
87
+# -height The height of the plotting region (the viewport) that the annotation is drawn. If it is a column annotation,
88
+#        the width must be an absolute unit.
89
+#
90
+# == details
91
+# The AnnotationFunction class is a wrapper of the function which draws heatmap annotation.
63 92
 AnnotationFunction = function(fun, fun_name = "", which = c("column", "row"), 
64 93
 	var_imported = list(), n = 0, data_scale = c(0, 1), subset_rule = list(), 
65 94
 	subsetable = FALSE, width = NULL, height = NULL) {
... ...
@@ -133,7 +162,20 @@ AnnotationFunction = function(fun, fun_name = "", which = c("column", "row"),
133 162
 	return(anno)
134 163
 }
135 164
 
136
-
165
+# == title
166
+# Subset an AnnotationFunction Object
167
+#
168
+# == param
169
+# -x An `AnnotationFunction-class` object.
170
+# -i Index
171
+#
172
+# == details
173
+# One good thing for designing the `AnnotationFunction-class` can be subsetted.
174
+#
175
+# == example
176
+# anno = anno_simple(1:10)
177
+# anno[1:5]
178
+# draw(anno[1:5], test = "subset of column annotation")
137 179
 "[.AnnotationFunction" = function(x, i) {
138 180
 	if(nargs() == 1) {
139 181
 		return(x)
... ...
@@ -158,6 +200,20 @@ AnnotationFunction = function(fun, fun_name = "", which = c("column", "row"),
158 200
 	}
159 201
 }
160 202
 
203
+# == title
204
+# Draw the AnnotationFunction object
205
+#
206
+# == param
207
+# -object The `AnnotationFunction-class` object.
208
+# -index Index of observations.
209
+# -test Is it in test mode? The value can be logical or a text which is plotted as the title of plot.
210
+#
211
+# == detail
212
+# Normally it is called internally by the `SingleAnnotation` class.
213
+#
214
+# When ``test`` is set to ``TRUE``, the annotation graphic is directly drawn,
215
+# which is generally for testing purpose.
216
+# 
161 217
 setMethod(f = "draw",
162 218
 	signature = "AnnotationFunction",
163 219
 	definition = function(object, index, test = FALSE) {
... ...
@@ -209,9 +265,19 @@ setMethod(f = "draw",
209 265
 	
210 266
 })
211 267
 
268
+# == title
269
+# Copy the AnnotationFunction object
270
+#
271
+# == param
272
+# -object The `AnnotationFunction-class` object.
273
+#
274
+# == detail
275
+# In `AnnotationFunction-class`, there is an environment which stores some external variables
276
+# for the annotation function. This `copy_all,AnnotationFunction-method` hard copy all the variables
277
+# in that environment to a new environment.
212 278
 setMethod(f = "copy_all",
213 279
 	signature = "AnnotationFunction",
214
-	definition = function(object, i) {
280
+	definition = function(object) {
215 281
 		object2 = object
216 282
 		object2@var_env = new.env()
217 283
 		for(var in names(object@var_env)) {
... ...
@@ -221,6 +287,12 @@ setMethod(f = "copy_all",
221 287
 		return(object2)
222 288
 })
223 289
 
290
+# == title
291
+# Print the AnnotationFunction object
292
+#
293
+# == param
294
+# -object The `AnnotationFunction-class` object.
295
+#
224 296
 setMethod(f = "show",
225 297
 	signature = "AnnotationFunction",
226 298
 	definition = function(object) {
... ...
@@ -253,12 +325,26 @@ setMethod(f = "show",
253 325
 	
254 326
 })
255 327
 
328
+# == title
329
+# Width of the AnnotationFunction object
330
+#
331
+# == param
332
+# -object The `AnnotationFunction-class` object.
333
+#
256 334
 setMethod(f = "width",
257 335
 	signature = "AnnotationFunction",
258 336
 	definition = function(object) {
259 337
 	object@width
260 338
 })
261 339
 
340
+# == title
341
+# Assign the Width of the AnnotationFunction object
342
+#
343
+# == param
344
+# -object The `AnnotationFunction-class` object.
345
+# -value A `grid::unit` object.
346
+# -... Other arguments
347
+#
262 348
 setReplaceMethod(f = "width",
263 349
 	signature = "AnnotationFunction",
264 350
 	definition = function(object, value, ...) {
... ...
@@ -266,12 +352,26 @@ setReplaceMethod(f = "width",
266 352
 	object
267 353
 })
268 354
 
355
+# == title
356
+# Height of the AnnotationFunction object
357
+#
358
+# == param
359
+# -object The `AnnotationFunction-class` object.
360
+#
269 361
 setMethod(f = "height",
270 362
 	signature = "AnnotationFunction",
271 363
 	definition = function(object) {
272 364
 	object@height
273 365
 })
274 366
 
367
+# == title
368
+# Assign the Height of the AnnotationFunction object
369
+#
370
+# == param
371
+# -object The `AnnotationFunction-class` object.
372
+# -value A `grid::unit` object.
373
+# -... Other arguments
374
+#
275 375
 setReplaceMethod(f = "height",
276 376
 	signature = "AnnotationFunction",
277 377
 	definition = function(object, value, ...) {
... ...
@@ -279,6 +379,15 @@ setReplaceMethod(f = "height",
279 379
 	object
280 380
 })
281 381
 
382
+# == title
383
+# Size of the AnnotationFunction object
384
+#
385
+# == param
386
+# -object The `AnnotationFunction-class` object.
387
+#
388
+# == detail
389
+# It returns the width if it is a row annotation and the height if it is a column annotation.
390
+#
282 391
 setMethod(f = "size",
283 392
 	signature = "AnnotationFunction",
284 393
 	definition = function(object) {
... ...
@@ -289,6 +398,17 @@ setMethod(f = "size",
289 398
 	}
290 399
 })
291 400
 
401
+# == title
402
+# Assign the Size of the AnnotationFunction object
403
+#
404
+# == param
405
+# -object The `AnnotationFunction-class` object.
406
+# -value A `grid::unit` object.
407
+# -... Other arguments
408
+#
409
+# == detail
410
+# It assigns the width if it is a row annotation and the height if it is a column annotation.
411
+#
292 412
 setReplaceMethod(f = "size",
293 413
 	signature = "AnnotationFunction",
294 414
 	definition = function(object, value, ...) {
... ...
@@ -300,6 +420,14 @@ setReplaceMethod(f = "size",
300 420
 	object
301 421
 })
302 422
 
423
+# == title
424
+# Number of Observations
425
+#
426
+# == param
427
+# -x The `AnnotationFunction-class` object.
428
+#
429
+# == details
430
+# It returns the ``n`` slot in the object.
303 431
 nobs.AnnotationFunction = function(x) {
304 432
 	if(x@n > 0) {
305 433
 		x@n
... ...
@@ -1,4 +1,44 @@
1 1
 
2
+# == title
3
+# Empty Annotation
4
+#
5
+# == param
6
+# -which Whether it is a column annotation or a row annotation?
7
+# -border Wether draw borders of the annotation region?
8
+# -width Width of the annotation.
9
+# -height Height of the annotation.
10
+#
11
+# == details
12
+# It creates an empty annotation and holds space, later users can add graphics
13
+# by `decorate_annotation`. This function is useful when users have difficulty to
14
+# implement `AnnotationFunction` object.
15
+#
16
+# In following example, an empty annotation is first created and later points are added:
17
+#
18
+# 	m = matrix(rnorm(100), 10)
19
+# 	ht = Heatmap(m, top_annotation = HeatmapAnnotation(pt = anno_empty()))
20
+# 	ht = draw(ht)
21
+# 	co = column_order(ht)[[1]]
22
+# 	pt_value = 1:10
23
+# 	decorate_annotation("pt", {
24
+# 		pushViewport(viewport(xscale = c(0.5, ncol(mat)+0.5), yscale = range(pt_value)))
25
+# 		grid.points(seq_len(ncol(mat)), pt_value[co], pch = 16, default.units = "native")
26
+# 		grid.yaxis()
27
+# 		popViewport()
28
+# 	})
29
+#
30
+# And it is similar as using `anno_points`:
31
+#
32
+# 	Heatmap(m, top_annotation = HeatmapAnnotation(pt = anno_points(pt_value)))
33
+#
34
+# == value
35
+# An annotation function which can be used in `HeatmapAnnotation`.
36
+#
37
+# == examples
38
+# anno = anno_empty()
39
+# draw(anno, test = "anno_empty")
40
+# anno = anno_empty(border = FALSE)
41
+# draw(anno, test = "anno_empty without border")
2 42
 anno_empty = function(which = c("column", "row"), border = TRUE, width = NULL, height = NULL) {
3 43
 	
4 44
 	if(is.null(.ENV$current_annotation_which)) {
... ...
@@ -29,6 +69,59 @@ anno_empty = function(which = c("column", "row"), border = TRUE, width = NULL, h
29 69
 subset_matrix_by_row = function(x, i) x[i, , drop = FALSE]
30 70
 subset_vector = function(x, i) x[i]
31 71
 
72
+# == title
73
+# Simple Annotation
74
+#
75
+# == param
76
+# -x The value vector. The value can be a vector or a matrix. The length of the vector
77
+#    or the number of rows of the matrix is taken as the number of the observations of the annotation.
78
+#    The value can be numeric or character and NA value is allowed.
79
+# -col Color that maps to ``x``. If ``x`` is numeric and needs a continuous mapping, ``col`` 
80
+#      should be a color mapping function which accepts a vector of values and returns a
81
+#      vector of colors. Normally it is generated by `circlize::colorRamp2`. If ``x`` is discrete
82
+#      (numeric or character) and needs a discrete color mapping, ``col`` should be a vector of 
83
+#      colors with levels in ``x`` as vector names. If ``col`` is not specified, the color mapping
84
+#      is randomly generated by `default_col`.
85
+# -na_col Color for NA value.
86
+# -which Whether it is a column annotation or a row annotation?
87
+# -border Wether draw borders of the annotation region?
88
+# -gp Graphic parameters for grid borders. The ``fill`` parameter is disabled.
89
+# -pch Points/symbols that are added on top of the annotation grids. The value can be numeric
90
+#      or single letters. It can be a vector if ``x`` is a vector and a matrix if ``x`` is a matrix.
91
+#      No points are drawn if the corresponding values are NA.
92
+# -pt_size Size of the points/symbols. It should be a `grid::unit` object. If ``x`` is a vector,
93
+#          the value of ``pt_size`` can be a vector, while if ``x`` is a matrix, ``pt_size`` can
94
+#          only be a single value.
95
+# -pt_gp Graphic parameters for points/symbols. The length setting is same as ``pt_size``.
96
+# -width Width of the annotation.
97
+# -height Height of the annotation.
98
+#
99
+# == details
100
+# The "simple annotation" is the most widely used annotation type which is heatmap-like, where
101
+# the grid colors correspond to the values. `anno_simple` also supports to add points/symbols
102
+# on top of the grids where the it can be normal point (when pch is set as numbers) or letters (when
103
+# pch is set as single letters).
104
+#
105
+# == value
106
+# An annotation function which can be used in `HeatmapAnnotation`.
107
+#
108
+# == example
109
+# anno = anno_simple(1:10)
110
+# draw(anno, test = "a numeric vector")
111
+#
112
+# anno = anno_simple(cbind(1:10, 10:1))
113
+# draw(anno, test = "a matrix")
114
+#
115
+# anno = anno_simple(1:10, pch = c(1:4, NA, 6:8, NA, 10))
116
+# draw(anno, test = "pch has NA values")
117
+#
118
+# anno = anno_simple(1:10, pch = c(rep("A", 5, rep(NA, 5))))
119
+# draw(anno, test = "pch has NA values")
120
+#
121
+# pch = matrix(1:20, nc = 2)
122
+# pch[sample(length(pch), 10)] = NA
123
+# anno = anno_simple(cbind(1:10, 10:1), pch = pch)
124
+# draw(anno, test = "matrix, pch is a matrix with NA values")
32 125
 anno_simple = function(x, col, na_col = "grey", 
33 126
 	which = c("column", "row"), border = FALSE, gp = gpar(col = NA),
34 127
 	pch = NULL, pt_size = unit(1, "snpc")*0.8, pt_gp = gpar(), 
... ...
@@ -179,14 +272,55 @@ anno_simple = function(x, col, na_col = "grey",
179 272
 	return(anno)      
180 273
 }
181 274
 
275
+# == title
276
+# Image Annotation
277
+#
278
+# == param
279
+# -image A vector of file paths of images. The format of the image is inferred from the suffix name of the image file.
280
+#       NA values or empty strings in the vector means no image to drawn.
281
+# -which Whether it is a column annotation or a row annotation?
282
+# -border Wether draw borders of the annotation region?
283
+# -gp Graphic parameters for annotation grids. If the image has transparent background, the ``fill`` parameter 
284
+#     can be used to control the background color in the annotation grids.
285
+# -space The space around the image to the annotation grid borders. The value should be a `grid::unit` object.
286
+# -width Width of the annotation.
287
+# -height Height of the annotation.
288
+#
289
+# == details
290
+# This function supports image formats in ``png``, ``svg``, ``pdf``, ``eps``, ``jpeg/jpg``, ``tiff``. 
291
+# ``png``, ``jpeg/jpg`` and ``tiff`` images are imported by `png::readPNG`, `jpeg::readJPEG` and 
292
+# `tiff::readTIFF`, and drawn by `grid.grid.raster`. ``svg`` images are firstly reformatted by `rsvg::rsvg_svg`
293
+# and then imported by `grImport2::readPicture` and drawn by `grImport2::grid.picture`. ``pdf`` and ``eps``
294
+# images are imported by `grImport::PostScriptTrace` and `grImport::readPicture`, later drawn by `grImport::grid.picture`.
295
+#
296
+# Different image formats can be mixed in the ``image`` vector.
297
+#
298
+# == value
299
+# An annotation function which can be used in `HeatmapAnnotation`.
300
+#
301
+# == example
302
+# # download the free icons from https://github.com/Keyamoon/IcoMoon-Free
303
+# \dontrun{
304
+# image = sample(dir("~/Downloads/IcoMoon-Free-master/PNG/64px", full.names = TRUE), 10)
305
+# anno = anno_image(image)
306
+# draw(anno, test = "png")
307
+# image[1:5] = ""
308
+# anno = anno_image(image)
309
+# draw(anno, test = "some of png")
310
+# }
182 311
 anno_image = function(image, which = c("column", "row"), border = TRUE, 
183
-	gp = gpar(fill = NA, col = NA), space = unit(1, "mm"), width = NULL, height = NULL) {
312
+	gp = gpar(fill = NA, col = NA), space = unit(1, "mm"), 
313
+	width = NULL, height = NULL) {
184 314
 
315
+	image[is.na(image)] = ""
316
+	l = grepl("^\\s*$", image)
317
+	image[l] = ""
318
+	
185 319
 	allowed_image_type = c("png", "svg", "pdf", "eps", "jpeg", "jpg", "tiff")
186 320
 
187 321
 	if(inherits(image, "character")) { ## they are file path
188 322
 		image_type = tolower(gsub("^.*\\.(\\w+)$", "\\1", image))
189
-		if(! all(image_type %in% allowed_image_type)) {
323
+		if(! all(image_type[image_type != ""] %in% allowed_image_type)) {
190 324
 			stop("image file should be of png/svg/pdf/eps/jpeg/jpg/tiff.")
191 325
 		}
192 326
 	} else {
... ...
@@ -197,7 +331,10 @@ anno_image = function(image, which = c("column", "row"), border = TRUE,
197 331
 	image_list = vector("list", n_image)
198 332
 	image_class = vector("character", n_image)
199 333
 	for(i in seq_along(image)) {
200
-		if(image_type[i] == "png") {
334
+		if(image[i] == "") {
335
+			image_list[[i]] = NA
336
+			image_class[i] = NA
337
+		} else if(image_type[i] == "png") {
201 338
 			if(!requireNamespace("png")) {
202 339
 				stop("Need png package to read png images.")
203 340
 			}
... ...
@@ -243,6 +380,8 @@ anno_image = function(image, which = c("column", "row"), border = TRUE,
243 380
 			nrow(x)/ncol(x)
244 381
 		} else if(inherits(x, "Picture")) {
245 382
 			max(x@summary@yscale)/max(x@summary@xscale)
383
+		} else {
384
+			1
246 385
 		}
247 386
 	})
248 387
 
... ...
@@ -265,6 +404,7 @@ anno_image = function(image, which = c("column", "row"), border = TRUE,
265 404
 		asp = convertHeight(unit(1, "npc") - space*2, "mm", valueOnly = TRUE)/convertWidth(unit(1/n, "npc") - space*2, "mm", value = TRUE)
266 405
 		grid.rect(x = (1:n - 0.5)/n, width = 1/n, gp = subset_gp(gp, index))
267 406
 		for(i in seq_len(n)) {
407
+			if(identical(image_list[[i]], NA)) next
268 408
 			if(yx_asp[ index[i] ] > asp) {
269 409
 				height = unit(1, "npc") - space*2
270 410
 				width = convertHeight(height, "mm")*yx_asp[ index[i] ]
... ...
@@ -293,6 +433,7 @@ anno_image = function(image, which = c("column", "row"), border = TRUE,
293 433
 		asp = convertHeight(unit(1/n, "npc") - space*2, "mm", valueOnly = TRUE)/convertWidth(unit(1, "npc") - space*2, "mm", value = TRUE)
294 434
 		grid.rect(y = (n - 1:n + 0.5)/n, height = 1/n, gp = subset_gp(gp, index))
295 435
 		for(i in seq_len(n)) {
436
+			if(identical(image_list[[i]], NA)) next
296 437
 			if(yx_asp[ index[i] ] > asp) {
297 438
 				height = unit(1/n, "npc") - space*2
298 439
 				width = convertHeight(height, "mm")*(1/yx_asp[ index[i] ])
... ...
@@ -340,6 +481,28 @@ anno_image = function(image, which = c("column", "row"), border = TRUE,
340 481
 	return(anno)   
341 482
 }
342 483
 
484
+# == title
485
+# The Default Parameters for Annotation Axis
486
+#
487
+# == param
488
+# -which Whether it is for column annotation or row annotation?
489
+#
490
+# == details
491
+# There are following parameters for the annotation axis:
492
+#
493
+# -at The breaks of axis. By default it is automatically inferred.
494
+# -labels The corresponding axis labels.
495
+# -labels_rot The rotation of the axis labels.
496
+# -gp Graphc parameters of axis labels. The value should be a `grid::unit` object.
497
+# -side If it is for column annotation, the value should only be one of ``left`` and ``right``. If
498
+#       it is for row annotation, the value should only be one of ``top`` and ``bottom``.
499
+# -facing Whether the axis faces to the outside of the annotation region or inside. Sometimes when
500
+#         appending more than one heatmaps, the axes of column annotations of one heatmap might
501
+#         overlap to the neighbouring heatmap, setting ``facing`` to ``inside`` may invoild it.
502
+#
503
+# == example
504
+# default_axis_param("column")
505
+# default_axis_param("row")
343 506
 default_axis_param = function(which) {
344 507
 	list(
345 508
 		at = NULL, 
... ...
@@ -380,33 +543,35 @@ construct_axis_grob = function(axis_param, which, data_scale) {
380 543
 }
381 544
 
382 545
 # == title
383
-# Using points as annotation
546
+# Points Annotation
384 547
 #
385 548
 # == param
386
-# -x a vector of numeric values.
387
-# -which is the annotation a column annotation or a row annotation?
388
-# -border whether show border of the annotation compoment
389
-# -gp graphic parameters.
390
-# -pch point type.
391
-# -size point size.
392
-# -ylim data ranges.
393
-# -axis whether add axis.
394
-# -axis_side if it is placed as column annotation, value can only be "left" or "right".
395
-#            If it is placed as row annotation, value can only be "bottom" or "top".
396
-# -axis_gp graphic parameters for axis
397
-# -axis_direction if the annotation is row annotation, should the axis be from left to right (default) or follow the reversed direction?
398
-# -... for future use.
549
+# -x The value vector. The value can be a vector or a matrix. The length of the vector
550
+#    or the number of rows of the matrix is taken as the number of the observations of the annotation.
551
+# -which Whether it is a column annotation or a row annotation?
552
+# -border Wether draw borders of the annotation region?
553
+# -gp Graphic parameters for points. The length of each graphic parameter can be 1, length of ``x`` if ``x``
554
+#     is a vector, or number of columns of ``x`` is ``x`` is a matrix.
555
+# -pch Point type. The length setting is the same as ``gp``.
556
+# -size Point size, the value should be a `grid::unit` object. The length setting is the same as ``gp``.
557
+# -ylim Data ranges. By default it is ``range(x)``.
558
+# -extend The extension to both side of ``ylim``. The value is a percent value corresponding to ``ylim[2] - ylim[1]``.
559
+# -axis Whether to add axis?
560
+# -axis_param parameters for controlling axis. See `default_axis_param` for all possible settings and default parameters.
561
+# -width Width of the annotation.
562
+# -height Height of the annotation.
399 563
 #
400 564
 # == value
401
-# A graphic function which can be set in `HeatmapAnnotation` constructor method.
402
-#
403
-# == author
404
-# Zuguang Gu <z.gu@dkfz.de>
565
+# An annotation function which can be used in `HeatmapAnnotation`.
405 566
 #
567
+# == example
568
+# anno = anno_points(runif(10))
569
+# draw(anno, test = "anno_points")
570
+# anno = anno_points(matrix(runif(20), nc = 2), pch = 1:2)
571
+# draw(anno, test = "matrix")
406 572
 anno_points = function(x, which = c("column", "row"), border = TRUE, gp = gpar(), pch = 16, 
407 573
 	size = unit(2, "mm"), ylim = NULL, extend = 0.05, axis = TRUE,
408
-	axis_param = default_axis_param(which),
409
-	width = NULL, height = NULL) {
574
+	axis_param = default_axis_param(which), width = NULL, height = NULL) {
410 575
 
411 576
 	if(is.null(.ENV$current_annotation_which)) {
412 577
 		which = match.arg(which)[1]
... ...
@@ -434,16 +599,16 @@ anno_points = function(x, which = c("column", "row"), border = TRUE, gp = gpar()
434 599
 		nc = 1
435 600
 	}
436 601
 
437
-	if(is.atomic(x)) {
438
-		gp = recycle_gp(gp, n)
439
-		if(length(pch) == 1) pch = rep(pch, n)
440
-		if(length(size) == 1) size = rep(size, n)
441
-	} else if(input_is_matrix) {
602
+	if(input_is_matrix) {
442 603
 		gp = recycle_gp(gp, nc)
443 604
 		if(length(pch) == 1) pch = rep(pch, nc)
444 605
 		if(length(size) == 1) size = rep(size, nc)
606
+	} else if(is.atomic(x)) {
607
+		gp = recycle_gp(gp, n)
608
+		if(length(pch) == 1) pch = rep(pch, n)
609
+		if(length(size) == 1) size = rep(size, n)
445 610
 	}
446
-	
611
+
447 612
 	if(is.null(ylim)) {
448 613
 		data_scale = range(x, na.rm = TRUE)
449 614
 	} else {
... ...
@@ -540,8 +705,39 @@ update_anno_extend = function(anno, axis_grob, axis_param) {
540 705
 	return(extended)
541 706
 }
542 707
 
708
+# == title
709
+# Lines Annotation
710
+#
711
+# == param
712
+# -x The value vector. The value can be a vector or a matrix. The length of the vector
713
+#    or the number of rows of the matrix is taken as the number of the observations of the annotation.
714
+# -which Whether it is a column annotation or a row annotation?
715
+# -border Wether draw borders of the annotation region?
716
+# -gp Graphic parameters for lines. The length of each graphic parameter can be 1, or number of columns of ``x`` is ``x`` is a matrix.
717
+# -add_points Whether to add points on the lines?
718
+# -pch Point type. The length setting is the same as ``gp``.
719
+# -size Point size, the value should be a `grid::unit` object. The length setting is the same as ``gp``.
720
+# -pt_size Graphic parameters for points. The length setting is the same as ``gp``.
721
+# -ylim Data ranges. By default it is ``range(x)``.
722
+# -extend The extension to both side of ``ylim``. The value is a percent value corresponding to ``ylim[2] - ylim[1]``.
723
+# -axis Whether to add axis?
724
+# -axis_param parameters for controlling axis. See `default_axis_param` for all possible settings and default parameters.
725
+# -width Width of the annotation.
726
+# -height Height of the annotation.
727
+#
728
+# == value
729
+# An annotation function which can be used in `HeatmapAnnotation`.
730
+#
731
+# == example
732
+# anno = anno_lines(runif(10))
733
+# draw(anno, test = "anno_lines")
734
+# anno = anno_lines(cbind(c(1:5, 1:5), c(5:1, 5:1)), gp = gpar(col = 2:3))
735
+# draw(anno, test = "matrix")
736
+# anno = anno_lines(cbind(c(1:5, 1:5), c(5:1, 5:1)), gp = gpar(col = 2:3),
737
+# 	add_points = TRUE, pt_gp = gpar(col = 5:6), pch = c(1, 16))
738
+# draw(anno, test = "matrix")
543 739
 anno_lines = function(x, which = c("column", "row"), border = TRUE, gp = gpar(), 
544
-	add_points = TRUE, pch = 16, size = unit(2, "mm"), pt_gp = gpar(), ylim = NULL, 
740
+	add_points = FALSE, pch = 16, size = unit(2, "mm"), pt_gp = gpar(), ylim = NULL, 
545 741
 	extend = 0.05, axis = TRUE, axis_param = default_axis_param(which),
546 742
 	width = NULL, height = NULL) {
547 743
 
... ...
@@ -571,18 +767,18 @@ anno_lines = function(x, which = c("column", "row"), border = TRUE, gp = gpar(),
571 767
 		nc = 1
572 768
 	}
573 769
 
574
-	if(is.atomic(x)) {
575
-		gp = recycle_gp(gp, 1)
576
-		pt_gp = recycle_gp(pt_gp, n)
577
-		if(length(pch) == 1) pch = rep(pch, n)
578
-		if(length(size) == 1) size = rep(size, n)
579
-	} else if(input_is_matrix) {
770
+	if(input_is_matrix) {
580 771
 		gp = recycle_gp(gp, nc)
581 772
 		pt_gp = recycle_gp(pt_gp, nc)
582 773
 		if(length(pch) == 1) pch = rep(pch, nc)
583 774
 		if(length(size) == 1) size = rep(size, nc)
775
+	} else if(is.atomic(x)) {
776
+		gp = recycle_gp(gp, 1)
777
+		pt_gp = recycle_gp(pt_gp, n)
778
+		if(length(pch) == 1) pch = rep(pch, n)
779
+		if(length(size) == 1) size = rep(size, n)
584 780
 	}
585
-	
781
+
586 782
 	if(is.null(ylim)) {
587 783
 		data_scale = range(x, na.rm = TRUE)
588 784
 	} else {
... ...
@@ -623,7 +819,7 @@ anno_lines = function(x, which = c("column", "row"), border = TRUE, gp = gpar(),
623 819
 
624 820
 	column_fun = function(index) {
625 821
 		n = length(index)
626
-		
822
+
627 823
 		pushViewport(viewport(yscale = data_scale, xscale = c(0.5, n+0.5)))
628 824
 		if(is.matrix(value)) {
629 825
 			for(i in seq_len(ncol(value))) {
... ...
@@ -682,32 +878,37 @@ anno_lines = function(x, which = c("column", "row"), border = TRUE, gp = gpar(),
682 878
 }
683 879
 
684 880
 # == title
685
-# Using barplot as annotation
881
+# Barplot Annotation
686 882
 #
687 883
 # == param
688
-# -x a vector of numeric values. If the value is a matrix, columns of the matrix will be represented as
689
-#    stacked barplots. Note for stacked barplots, each row in the matrix should only contain values with same sign (either all positive or all negative).
690
-# -baseline baseline for bars. The value should be "min" or "max", or a numeric value. It is enforced to be zero
884
+# -x The value vector. The value can be a vector or a matrix. The length of the vector
885
+#    or the number of rows of the matrix is taken as the number of the observations of the annotation.
886
+#    If ``x`` is a vector, the barplots will be represented as stacked barplots.
887
+# -baseline baseline of bars. The value should be "min" or "max", or a numeric value. It is enforced to be zero
691 888
 #       for stacked barplots.
692
-# -which is the annotation a column annotation or a row annotation?
693
-# -border whether show border of the annotation compoment
694
-# -bar_width relative width of the bars, should less than one
695
-# -gp graphic parameters. If it is the stacked barplots, the length of the graphic parameter should 
696
-#     be same as the number of stacks.
697
-# -ylim data ranges.
698
-# -axis whether add axis
699
-# -axis_side if it is placed as column annotation, value can only be "left" or "right".
700
-#            If it is placed as row annotation, value can only be "bottom" or "top".
701
-# -axis_gp graphic parameters for axis
702
-# -axis_direction if the annotation is row annotation, should the axis be from left to right (default) or follow the reversed direction?
703
-# -... for future use.
889
+# -which Whether it is a column annotation or a row annotation?
890
+# -border Wether draw borders of the annotation region?
891
+# -bar_width Relative width of the bars. The value should be smaller than one.
892
+# -gp Graphic parameters for points. The length of each graphic parameter can be 1, length of ``x`` if ``x``
893
+#     is a vector, or number of columns of ``x`` is ``x`` is a matrix.
894
+# -ylim Data ranges. By default it is ``range(x)`` if ``x`` is a vector, or ``range(rowSums(x))`` if ``x`` is a matrix.
895
+# -extend The extension to both side of ``ylim``. The value is a percent value corresponding to ``ylim[2] - ylim[1]``.
896
+# -axis Whether to add axis?
897
+# -axis_param parameters for controlling axis. See `default_axis_param` for all possible settings and default parameters.
898
+# -width Width of the annotation.
899
+# -height Height of the annotation.
704 900
 #
705 901
 # == value
706
-# A graphic function which can be set in `HeatmapAnnotation` constructor method.
902
+# An annotation function which can be used in `HeatmapAnnotation`.
707 903
 #
708
-# == author
709
-# Zuguang Gu <z.gu@dkfz.de>
904
+# == example
905
+# anno = anno_barplot(1:10)
906
+# draw(anno, test = "a vector")
710 907
 #
908
+# m = matrix(runif(4*10), nc = 4)
909
+# m = t(apply(m, 1, function(x) x/sum(x)))
910
+# anno = anno_barplot(m, gp = gpar(fill = 2:5), bar_width = 1, height = unit(6, "cm"))
911
+# draw(anno, test = "proportion matrix")
711 912
 anno_barplot = function(x, baseline = 0, which = c("column", "row"), border = TRUE, bar_width = 0.6,
712 913
 	gp = gpar(fill = "#CCCCCC"), ylim = NULL, extend = 0.05, axis = TRUE, 
713 914
 	axis_param = default_axis_param(which),
... ...
@@ -836,30 +1037,35 @@ anno_barplot = function(x, baseline = 0, which = c("column", "row"), border = TR
836 1037
 }
837 1038
 
838 1039
 # == title
839
-# Using boxplot as annotation
1040
+# Boxplot Annotation
840 1041
 #
841 1042
 # == param
842
-# -x a matrix or a list. If ``x`` is a matrix and if ``which`` is ``column``, statistics for boxplot
843
-#    is calculated by columns, if ``which`` is ``row``, the calculation is by rows.
844
-# -which is the annotation a column annotation or a row annotation?
845
-# -border whether show border of the annotation compoment
846
-# -gp graphic parameters
847
-# -ylim data ranges.
848
-# -outline whether draw outliers
849
-# -pch point type
850
-# -size point size
851
-# -axis whether add axis
852
-# -axis_side if it is placed as column annotation, value can only be "left" or "right".
853
-#            If it is placed as row annotation, value can only be "bottom" or "top".
854
-# -axis_gp graphic parameters for axis
855
-# -axis_direction if the annotation is row annotation, should the axis be from left to right (default) or follow the reversed direction?
1043
+# -x A matrix or a list. If ``x`` is a matrix and if ``which`` is ``column``, statistics for boxplots
1044
+#    are calculated by columns, if ``which`` is ``row``, the calculation is done by rows.
1045
+# -which Whether it is a column annotation or a row annotation?
1046
+# -border Wether draw borders of the annotation region?
1047
+# -gp Graphic parameters for the boxes. The length of the graphic parameters should be one or the number of observations.
1048
+# -ylim Data ranges.
1049
+# -extend The extension to both side of ``ylim``. The value is a percent value corresponding to ``ylim[2] - ylim[1]``.
1050
+# -outline Whether draw outline of boxplots?
1051
+# -box_width Relative width of boxes. The value should be smaller than one.
1052
+# -pch Point style.
1053
+# -size Point size.
1054
+# -axis Whether to add axis?
1055
+# -axis_param parameters for controlling axis. See `default_axis_param` for all possible settings and default parameters.
1056
+# -width Width of the annotation.
1057
+# -height Height of the annotation.
856 1058
 #
857 1059
 # == value
858
-# A graphic function which can be set in `HeatmapAnnotation` constructor method.
859
-#
860
-# == author
861
-# Zuguang Gu <z.gu@dkfz.de>
862
-#
1060
+# An annotation function which can be used in `HeatmapAnnotation`.
1061
+#
1062
+# == example
1063
+# set.seed(123)
1064
+# m = matrix(rnorm(100), 10)
1065
+# anno = anno_boxplot(m, height = unit(4, "cm"))
1066
+# draw(anno, test = "anno_boxplot")
1067
+# anno = anno_boxplot(m, height = unit(4, "cm"), gp = gpar(fill = 1:10))
1068
+# draw(anno, test = "anno_boxplot with gp")
863 1069
 anno_boxplot = function(x, which = c("column", "row"), border = TRUE,
864 1070
 	gp = gpar(fill = "#CCCCCC"), ylim = NULL, extend = 0.05, outline = TRUE, box_width = 0.6,
865 1071
 	pch = 1, size = unit(2, "mm"), axis = TRUE, axis_param = default_axis_param(which),
... ...
@@ -1018,21 +1224,31 @@ anno_boxplot = function(x, which = c("column", "row"), border = TRUE,
1018 1224
 }
1019 1225
 
1020 1226
 # == title
1021
-# Using histogram as annotation
1227
+# Histogram Annotation
1022 1228
 #
1023 1229
 # == param
1024
-# -x a matrix or a list. If ``x`` is a matrix and if ``which`` is ``column``, statistics for histogram
1025
-#    is calculated by columns, if ``which`` is ``row``, the calculation is by rows.
1026
-# -which is the annotation a column annotation or a row annotation?
1027
-# -gp graphic parameters
1028
-# -... pass to `graphics::hist`
1230
+# -x A matrix or a list. If ``x`` is a matrix and if ``which`` is ``column``, statistics for boxplots
1231
+#    are calculated by columns, if ``which`` is ``row``, the calculation is done by rows.
1232
+# -which Whether it is a column annotation or a row annotation?
1233
+# -n_breaks Number of breaks for calculating histogram.
1234
+# -border Wether draw borders of the annotation region?
1235
+# -gp Graphic parameters for the boxes. The length of the graphic parameters should be one or the number of observations.
1236
+# -axis Whether to add axis?
1237
+# -axis_param parameters for controlling axis. See `default_axis_param` for all possible settings and default parameters.
1238
+# -width Width of the annotation.
1239
+# -height Height of the annotation.
1029 1240
 #
1030 1241
 # == value
1031
-# A graphic function which can be set in `HeatmapAnnotation` constructor method.
1032
-#
1033
-# == author
1034
-# Zuguang Gu <z.gu@dkfz.de>
1035
-#
1242
+# An annotation function which can be used in `HeatmapAnnotation`.
1243
+#
1244
+# == example
1245
+# m = matrix(rnorm(1000), nc = 10)
1246
+# anno = anno_histogram(t(m), which = "row")
1247
+# draw(anno, test = "row histogram")
1248
+# anno = anno_histogram(t(m), which = "row", gp = gpar(fill = 1:10))
1249
+# draw(anno, test = "row histogram with color")
1250
+# anno = anno_histogram(t(m), which = "row", n_breaks = 20)
1251
+# draw(anno, test = "row histogram with color")
1036 1252
 anno_histogram = function(x, which = c("column", "row"), n_breaks = 11, 
1037 1253
 	border = FALSE, gp = gpar(fill = "#CCCCCC"), 
1038 1254
 	axis = TRUE, axis_param = default_axis_param(which), 
... ...
@@ -1152,26 +1368,41 @@ anno_histogram = function(x, which = c("column", "row"), n_breaks = 11,
1152 1368
 }
1153 1369
 
1154 1370
 # == title
1155
-# Using kernel density as annotation
1371
+# Density Annotation
1156 1372
 #
1157 1373
 # == param
1158
-# -x a matrix or a list. If ``x`` is a matrix and if ``which`` is ``column``, statistics for density
1159
-#    is calculated by columns, if ``which`` is ``row``, the calculation is by rows.
1160
-# -which is the annotation a column annotation or a row annotation?
1161
-# -gp graphic parameters. Note it is ignored if ``type`` equals to ``heatmap``.
1162
-# -type which type of graphics is used to represent density distribution.
1163
-# -... pass to `stats::density`
1374
+# -x A matrix or a list. If ``x`` is a matrix and if ``which`` is ``column``, statistics for boxplots
1375
+#    are calculated by columns, if ``which`` is ``row``, the calculation is done by rows.
1376
+# -which Whether it is a column annotation or a row annotation?
1377
+# -type Type of graphics to represent density distribution. "lines" for normal density plot; "violine" for violin plot
1378
+#       and "heatmap" for heatmap visualization of density distribution.
1379
+# -heatmap_colors A vector of colors for interpolating density values.
1380
+# -joyplot_scale Relative height of density distribution. A value higher than 1 increases the height of the density
1381
+#               distribution and the plot will represented as so-called "joyplot".
1382
+# -border Wether draw borders of the annotation region?
1383
+# -gp Graphic parameters for the boxes. The length of the graphic parameters should be one or the number of observations.
1384
+# -axis Whether to add axis?
1385
+# -axis_param parameters for controlling axis. See `default_axis_param` for all possible settings and default parameters.
1386
+# -width Width of the annotation.
1387
+# -height Height of the annotation.
1164 1388
 #
1165 1389
 # == value
1166
-# A graphic function which can be set in `HeatmapAnnotation` constructor method.
1167
-#
1168
-# == author
1169
-# Zuguang Gu <z.gu@dkfz.de>
1170
-#
1171
-anno_density = function(x, which = c("column", "row"), gp = gpar(fill = "#CCCCCC"),
1390
+# An annotation function which can be used in `HeatmapAnnotation`.
1391
+#
1392
+# == example
1393
+# anno = anno_density(t(m), which = "row")
1394
+# draw(anno, test = "normal density")
1395
+# anno = anno_density(t(m), which = "row", type = "violin")
1396
+# draw(anno, test = "violin")
1397
+# anno = anno_density(t(m), which = "row", type = "heatmap")
1398
+# draw(anno, test = "heatmap")
1399
+# anno = anno_density(t(m), which = "row", type = "heatmap", 
1400
+#     heatmap_colors = c("white", "orange"))
1401
+# draw(anno, test = "heatmap, colors")
1402
+anno_density = function(x, which = c("column", "row"),
1172 1403
 	type = c("lines", "violin", "heatmap"), 
1173 1404
 	heatmap_colors = rev(brewer.pal(name = "RdYlBu", n = 11)), 
1174
-	joyplot_scale = 1, border = TRUE,
1405
+	joyplot_scale = 1, border = TRUE, gp = gpar(fill = "#CCCCCC"),
1175 1406
 	axis = TRUE, axis_param = default_axis_param(which),
1176 1407
 	width = NULL, height = NULL) {
1177 1408
 	
... ...
@@ -1382,24 +1613,41 @@ anno_density = function(x, which = c("column", "row"), gp = gpar(fill = "#CCCCCC
1382 1613
 }
1383 1614
 
1384 1615
 # == title
1385
-# Using text as annotation
1616
+# Text Annotation
1386 1617
 #
1387 1618
 # == param
1388
-# -x a vector of text
1389
-# -which is the annotation a column annotation or a row annotation?
1390
-# -gp graphic parameters.
1391
-# -rot rotation of text
1392
-# -just justification of text, pass to `grid::grid.text`
1393
-# -offset if it is a row annotation, ``offset`` corresponds to the x-coordinates of text.
1394
-#         and if it is a column annotation, ``offset`` corresponds to the y-coordinates of text.
1395
-#         The value should be a `grid::unit` object.
1619
+# -x A vector of text.
1620
+# -which Whether it is a column annotation or a row annotation?
1621
+# -gp Graphic parameters.
1622
+# -rot Rotation of the text, pass to `grid::grid.text`.
1623
+# -just Justification of text, pass to `grid::grid.text`.
1624
+# -offset Depracated, use ``location`` instead.
1625
+# -location Position of the text. By default ``rot``, ``just`` and ``location`` are automatically
1626
+#           inferred according to whether it is a row annotation or column annotation. The value
1627
+#           of ``location`` should be a `grid::unit` object, normally in ``npc`` unit. E.g. ``unit(0, 'npc')``
1628
+#           means the most left of the annotation region and ``unit(1, 'npc')`` means the most right of
1629
+#           the annotation region. 
1630
+# -width Width of the annotation.
1631
+# -height Height of the annotation.
1396 1632
 #
1397 1633
 # == value
1398
-# A graphic function which can be set in `HeatmapAnnotation` constructor method.
1399
-#
1400
-# == author
1401
-# Zuguang Gu <z.gu@dkfz.de>
1402
-#
1634
+# An annotation function which can be used in `HeatmapAnnotation`.
1635
+#
1636
+# == example
1637
+# anno = anno_text(month.name)
1638
+# draw(anno, test = "month names")
1639
+# anno = anno_text(month.name, gp = gpar(fontsize = 16))
1640
+# draw(anno, test = "month names with fontsize")
1641
+# anno = anno_text(month.name, gp = gpar(fontsize = 1:12+4))
1642
+# draw(anno, test = "month names with changing fontsize")
1643
+# anno = anno_text(month.name, which = "row")
1644
+# draw(anno, test = "month names on rows")
1645
+# anno = anno_text(month.name, location = 0, rot = 45, 
1646
+#     just = "left", gp = gpar(col = 1:12))
1647
+# draw(anno, test = "with rotations")
1648
+# anno = anno_text(month.name, location = 1, 
1649
+#     rot = 45, just = "right", gp = gpar(fontsize = 1:12+4))
1650
+# draw(anno, test = "with rotations")
1403 1651
 anno_text = function(x, which = c("column", "row"), gp = gpar(), 
1404 1652
 	rot = guess_rot(), just = guess_just(), 
1405 1653
 	offset = guess_location(), location = guess_location(),
... ...
@@ -1511,6 +1759,37 @@ anno_text = function(x, which = c("column", "row"), gp = gpar(),
1511 1759
 	return(anno)
1512 1760
 }
1513 1761
 
1762
+# == title
1763
+# Joyplot Annotation
1764
+#
1765
+# == param
1766
+# -x A matrix or a list. If ``x`` is a matrix or a data frame, columns correspond to observations.
1767
+# -which Whether it is a column annotation or a row annotation?
1768
+# -gp Graphic parameters for the boxes. The length of the graphic parameters should be one or the number of observations.
1769
+# -scale Relative height of the curve. A value higher than 1 increases the height of the curve.
1770
+# -transparency Transparency of the filled colors. Value should be between 0 and 1.
1771
+# -axis Whether to add axis?
1772
+# -axis_param parameters for controlling axis. See `default_axis_param` for all possible settings and default parameters.
1773
+# -width Width of the annotation.
1774
+# -height Height of the annotation.
1775
+#
1776
+# == value
1777
+# An annotation function which can be used in `HeatmapAnnotation`.
1778
+#
1779
+# == example
1780
+# m = matrix(rnorm(1000), nc = 10)
1781
+# lt = apply(m, 2, function(x) data.frame(density(x)[c("x", "y")]))
1782
+# anno = anno_joyplot(lt, width = unit(4, "cm"), which = "row")
1783
+# draw(anno, test = "joyplot")
1784
+# anno = anno_joyplot(lt, width = unit(4, "cm"), which = "row", gp = gpar(fill = 1:10))
1785
+# draw(anno, test = "joyplot + col")
1786
+# anno = anno_joyplot(lt, width = unit(4, "cm"), which = "row", scale = 1)
1787
+# draw(anno, test = "joyplot + scale")
1788
+#
1789
+# m = matrix(rnorm(5000), nc = 50)
1790
+# lt = apply(m, 2, function(x) data.frame(density(x)[c("x", "y")]))
1791
+# anno = anno_joyplot(lt, width = unit(4, "cm"), which = "row", gp = gpar(fill = NA), scale = 4)
1792
+# draw(anno, test = "joyplot")
1514 1793
 anno_joyplot = function(x, which = c("column", "row"), gp = gpar(fill = "#000000"),
1515 1794
 	scale = 2, transparency = 0.6,
1516 1795
 	axis = TRUE, axis_param = default_axis_param(which),
... ...
@@ -1652,11 +1931,50 @@ anno_joyplot = function(x, which = c("column", "row"), gp = gpar(fill = "#000000
1652 1931
 	return(anno)
1653 1932
 }
1654 1933
 
1655
-
1934
+# == title
1935
+# Horizon chart Annotation
1936
+#
1937
+# == param
1938
+# -x A matrix or a list. If ``x`` is a matrix or a data frame, columns correspond to observations.
1939
+# -which Whether it is a column annotation or a row annotation?
1940
+# -gp Graphic parameters for the boxes. The length of the graphic parameters should be one or the number of observations.
1941
+#     There are two unstandard parameters specificly for horizon chart: ``pos_fill`` and ``neg_fill` controls the filled
1942
+#     color for positive values and negative values.
1943
+# -n_slice Number of slices on y-axis.
1944
+# -slice_size Height of the slice. If the value is not ``NULL``, ``n_slice`` will be recalculated. 
1945
+# -negative_from_top Whether the areas for negative values start from the top or the bottom of the plotting region?
1946
+# -normalize Whether normalize ``x`` to let data range of each observation in (0, 1)?
1947
+# -gap Gap size of neighbouring horizon chart.
1948
+# -axis Whether to add axis?
1949
+# -axis_param parameters for controlling axis. See `default_axis_param` for all possible settings and default parameters.
1950
+# -width Width of the annotation.
1951
+# -height Height of the annotation.
1952
+#
1953
+# == detail
1954
+# Horizon chart as row annotation is only supported.
1955
+#
1956
+# == value
1957
+# An annotation function which can be used in `HeatmapAnnotation`.
1958
+#
1959
+# == detail
1960
+# lt = lapply(1:20, function(x) cumprod(1 + runif(1000, -x/100, x/100)) - 1)
1961
+# anno = anno_horizon(lt, which = "row")
1962
+# draw(anno, test = "horizon chart")
1963
+# anno = anno_horizon(lt, which = "row", 
1964
+#     gp = gpar(pos_fill = "orange", neg_fill = "darkgreen"))
1965
+# draw(anno, test = "horizon chart, col")
1966
+# anno = anno_horizon(lt, which = "row", negative_from_top = TRUE)
1967
+# draw(anno, test = "horizon chart + negative_from_top")
1968
+# anno = anno_horizon(lt, which = "row", gap = unit(1, "mm"))
1969
+# draw(anno, test = "horizon chart + gap")
1970
+# anno = anno_horizon(lt, which = "row", 
1971
+#     gp = gpar(pos_fill = rep(c("orange", "red"), each = 10),
1972
+#     neg_fill = rep(c("darkgreen", "blue"), each = 10)))
1973
+# draw(anno, test = "horizon chart, col")
1656 1974
 anno_horizon = function(x, which = c("column", "row"), 
1657 1975
 	gp = gpar(pos_fill = "#D73027", neg_fill = "#313695"),
1658 1976
 	n_slice = 4, slice_size = NULL, negative_from_top = FALSE, 
1659
-	normalize = TRUE, border = FALSE, gap = unit(0, "mm"),
1977
+	normalize = TRUE, gap = unit(0, "mm"),
1660 1978
 	axis = TRUE, axis_param = default_axis_param(which),
1661 1979
 	width = NULL, height = NULL) {
1662 1980
 
... ...
@@ -1769,7 +2087,7 @@ anno_horizon = function(x, which = c("column", "row"),
1769 2087
 		height = anno_size$height,
1770 2088
 		n = n,
1771 2089
 		data_scale = xscale,
1772
-		var_import = list(value, gp, border, axis, axis_param, axis_grob, n_slice, slice_size,
2090
+		var_import = list(value, gp, axis, axis_param, axis_grob, n_slice, slice_size,
1773 2091
 			negative_from_top, xscale, yscale, gap)
1774 2092
 	)
1775 2093
 
... ...
@@ -1861,7 +2179,7 @@ split_vec_by_NA = function(x) {
1861 2179
 
1862 2180
 
1863 2181
 # == title
1864
-# Row annotation which is represented as points
2182
+# Points as Row Annotation
1865 2183
 #
1866 2184
 # == param
1867 2185
 # -... pass to `anno_points`
... ...
@@ -1869,12 +2187,11 @@ split_vec_by_NA = function(x) {
1869 2187
 # == details
1870 2188
 # A wrapper of `anno_points` with pre-defined ``which`` to ``row``.
1871 2189
 #
2190
+# You can directly use `anno_points` for row annotation if you call it in `rowAnnotation`.
2191
+#
1872 2192
 # == value
1873 2193
 # See help page of `anno_points`
1874 2194
 #
1875
-# == author
1876
-# Zuguang Gu <z.gu@dkfz.de>
1877
-#
1878 2195
 row_anno_points = function(...) {
1879 2196
 	if(exists(".__under_SingleAnnotation__", envir = parent.frame())) {
1880 2197
 		message("From this version of ComplexHeatmap, you can directly use `anno_points()` for row annotation if you call it in `rowAnnotation()`.")
... ...
@@ -1882,27 +2199,9 @@ row_anno_points = function(...) {
1882 2199
 	anno_points(..., which = "row")
1883 2200
 }
1884 2201
 
1885
-# == title
1886
-# Column annotation which is represented as points
1887
-#
1888
-# == param
1889
-# -... pass to `anno_points`
1890
-#
1891
-# == details
1892
-# A wrapper of `anno_points` with pre-defined ``which`` to ``column``.
1893
-#
1894
-# == value
1895
-# See help page of `anno_points`
1896
-#
1897
-# == author
1898
-# Zuguang Gu <z.gu@dkfz.de>
1899
-#
1900
-column_anno_points = function(...) {
1901
-	anno_points(..., which = "column")
1902
-}
1903 2202
 
1904 2203
 # == title
1905
-# Row annotation which is represented as barplots
2204
+# Barplots as Row Annotation
1906 2205
 #
1907 2206
 # == param
1908 2207
 # -... pass to `anno_barplot`
... ...
@@ -1910,37 +2209,18 @@ column_anno_points = function(...) {
1910 2209
 # == details
1911 2210
 # A wrapper of `anno_barplot` with pre-defined ``which`` to ``row``.
1912 2211
 #
2212
+# You can directly use `anno_barplot` for row annotation if you call it in `rowAnnotation`.
2213
+#
1913 2214
 # == value
1914 2215
 # See help page of `anno_barplot`
1915 2216
 #
1916
-# == author
1917
-# Zuguang Gu <z.gu@dkfz.de>
1918
-#
1919 2217
 row_anno_barplot = function(...) {
1920 2218
 	anno_barplot(..., which = "row")
1921 2219
 }
1922 2220
 
1923
-# == title
1924
-# Column annotation which is represented as barplots
1925
-#
1926
-# == param
1927
-# -... pass to `anno_barplot`
1928
-#
1929
-# == details
1930
-# A wrapper of `anno_barplot` with pre-defined ``which`` to ``column``.
1931
-#
1932
-# == value
1933
-# See help page of `anno_barplot`
1934
-#
1935
-# == author
1936
-# Zuguang Gu <z.gu@dkfz.de>
1937
-#
1938
-column_anno_barplot = function(...) {
1939
-	anno_barplot(..., which = "column")
1940
-}
1941 2221
 
1942 2222
 # == title
1943
-# Row annotation which is represented as boxplots
2223
+# Boxplots as Row Annotation
1944 2224
 #
1945 2225
 # == param
1946 2226
 # -... pass to `anno_boxplot`
... ...
@@ -1948,37 +2228,17 @@ column_anno_barplot = function(...) {
1948 2228
 # == details
1949 2229
 # A wrapper of `anno_boxplot` with pre-defined ``which`` to ``row``.
1950 2230
 #
2231
+# You can directly use `anno_boxplot` for row annotation if you call it in `rowAnnotation`.
2232
+#
1951 2233
 # == value
1952 2234
 # See help page of `anno_boxplot`
1953 2235
 #
1954
-# == author
1955
-# Zuguang Gu <z.gu@dkfz.de>
1956
-#
1957 2236
 row_anno_boxplot = function(...) {
1958 2237
 	anno_boxplot(..., which = "row")
1959 2238
 }
1960 2239
 
1961 2240
 # == title
1962
-# Column annotation which is represented as boxplots
1963
-#
1964
-# == param
1965
-# -... pass to `anno_boxplot`
1966
-#
1967
-# == details
1968
-# A wrapper of `anno_boxplot` with pre-defined ``which`` to ``column``.
1969
-#
1970
-# == value
1971
-# See help page of `anno_boxplot`
1972
-#
1973
-# == author
1974
-# Zuguang Gu <z.gu@dkfz.de>
1975
-#
1976
-column_anno_boxplot = function(...) {
1977
-	anno_boxplot(..., which = "column")
1978
-}
1979
-
1980
-# == title
1981
-# Row annotation which is represented as histogram
2241
+# Histograms as Row Annotation
1982 2242
 #
1983 2243
 # == param
1984 2244
 # -... pass to `anno_histogram`
... ...
@@ -1986,37 +2246,17 @@ column_anno_boxplot = function(...) {
1986 2246
 # == details
1987 2247
 # A wrapper of `anno_histogram` with pre-defined ``which`` to ``row``.
1988 2248
 #
2249
+# You can directly use `anno_histogram` for row annotation if you call it in `rowAnnotation`.
2250
+#
1989 2251
 # == value
1990 2252
 # See help page of `anno_histogram`
1991 2253
 #
1992
-# == author
1993
-# Zuguang Gu <z.gu@dkfz.de>
1994
-#
1995 2254
 row_anno_histogram = function(...) {
1996 2255
 	anno_histogram(..., which = "row")
1997 2256
 }
1998 2257
 
1999 2258
 # == title
2000
-# Column annotation which is represented as histogram
2001
-#
2002
-# == param
2003
-# -... pass to `anno_histogram`
2004
-#
2005
-# == details
2006
-# A wrapper of `anno_histogram` with pre-defined ``which`` to ``column``.
2007
-#
2008
-# == value
2009
-# See help page of `anno_histogram`
2010
-#
2011
-# == author
2012
-# Zuguang Gu <z.gu@dkfz.de>
2013
-#
2014
-column_anno_histogram = function(...) {
2015
-	anno_histogram(..., which = "column")
2016
-}
2017
-
2018
-# == title
2019
-# Row annotation which is represented as density plot
2259
+# Density as Row Annotation
2020 2260
 #
2021 2261
 # == param
2022 2262
 # -... pass to `anno_density`
... ...
@@ -2024,37 +2264,17 @@ column_anno_histogram = function(...) {
2024 2264
 # == details
2025 2265
 # A wrapper of `anno_density` with pre-defined ``which`` to ``row``.
2026 2266
 #
2267
+# You can directly use `anno_density` for row annotation if you call it in `rowAnnotation`.
2268
+#
2027 2269
 # == value
2028 2270
 # See help page of `anno_density`
2029 2271
 #
2030
-# == author
2031
-# Zuguang Gu <z.gu@dkfz.de>
2032
-#
2033 2272
 row_anno_density = function(...) {
2034 2273
 	anno_density(..., which = "row")
2035 2274
 }
2036 2275
 
2037 2276
 # == title
2038
-# Column annotation which is represented as density plot
2039
-#
2040
-# == param
2041
-# -... pass to `anno_density`
2042
-#
2043
-# == details
2044
-# A wrapper of `anno_density` with pre-defined ``which`` to ``column``.
2045
-#
2046
-# == value
2047
-# See help page of `anno_density`
2048
-#
2049
-# == author
2050
-# Zuguang Gu <z.gu@dkfz.de>
2051
-#
2052
-column_anno_density = function(...) {
2053
-	anno_density(..., which = "column")
2054
-}
2055
-
2056
-# == title
2057
-# Row annotation which is represented as text
2277
+# Text as Row Annotation
2058 2278
 #
2059 2279
 # == param
2060 2280
 # -... pass to `anno_text`
... ...
@@ -2062,49 +2282,30 @@ column_anno_density = function(...) {
2062 2282
 # == details
2063 2283
 # A wrapper of `anno_text` with pre-defined ``which`` to ``row``.
2064 2284
 #
2285
+# You can directly use `anno_text` for row annotation if you call it in `rowAnnotation`.
2286
+#
2065 2287
 # == value
2066 2288
 # See help page of `anno_text`
2067 2289
 #
2068
-# == author
2069
-# Zuguang Gu <z.gu@dkfz.de>
2070
-#
2071 2290
 row_anno_text = function(...) {
2072 2291
 	anno_text(..., which = "row")
2073 2292
 }
2074 2293
 
2075
-# == title
2076
-# Column annotation which is represented as text
2077
-#
2078
-# == param
2079
-# -... pass to `anno_text`
2080
-#
2081
-# == details
2082
-# A wrapper of `anno_text` with pre-defined ``which`` to ``column``.
2083
-#
2084
-# == value
2085
-# See help page of `anno_text`
2086
-#
2087
-# == author
2088
-# Zuguang Gu <z.gu@dkfz.de>
2089
-#
2090
-column_anno_text = function(...) {
2091
-	anno_text(..., which = "column")
2092
-}
2093
-
2094 2294
 # == title
2095 2295
 # Link annotation with labels
2096 2296
 #
2097 2297
 # == param
2098
-# -at numeric index in the original matrix
2099
-# -labels corresponding labels
2100
-# -which column annotation or row annotation
2101
-# -side side of the labels. If it is a column annotation, permitted values are "top" and "bottom";
2102
-#       If it is a row annotation, permitted values are "left" and "right".
2103
-# -lines_gp graphic settings for the segments
2104
-# -labels_gp graphic settings for the labels
2105
-# -padding padding between labels if they are attached to each other
2106
-# -link_width, width of the segments.
2107
-# -extend by default, the region for the labels has the same width (if it is a column annotation) or
2298
+# -at Numeric index from the original matrix.
2299
+# -labels Corresponding labels.
2300
+# -which Whether it is a column annotation or a row annotation?
2301
+# -side Side of the labels. If it is a column annotation, valid values are "top" and "bottom";
2302
+#       If it is a row annotation, valid values are "left" and "right".
2303
+# -lines_gp Please use ``link_gp`` instead.
2304
+# -link_gp Graphic settings for the segments.
2305
+# -labels_gp Graphic settings for the labels.
2306
+# -padding Padding between neighbouring labels in the plot.
2307
+# -link_width Width of the segments.
2308
+# -extend By default, the region for the labels has the same width (if it is a column annotation) or
2108 2309
 #         same height (if it is a row annotation) as the heatmap. The size can be extended by this options.
2109 2310
 #         The value can be a proportion number or  a `grid::unit` object. The length can be either one or two.
2110 2311
 #
... ...
@@ -2114,13 +2315,21 @@ column_anno_text = function(...) {
2114 2315
 # with links.
2115 2316
 #
2116 2317
 # == value
2117
-# A graphic function which can be set in `HeatmapAnnotation` constructor method.
2118
-#
2119
-# == author
2120
-# Zuguang Gu <z.gu@dkfz.de>
2121
-anno_mark = function(at, labels, which = c("column", "row"), side = ifelse(which == "column", "top", "right"),
2122
-	lines_gp = gpar(), labels_gp = gpar(), padding = 0.5, link_width = unit(5, "mm"), 
2123
-	link_gp = lines_gp, extend = unit(0, "mm")) {
2318
+# An annotation function which can be used in `HeatmapAnnotation`.
2319
+#
2320
+# == example
2321
+# anno = anno_mark(at = c(1:4, 20, 60, 97:100), labels = month.name[1:10], which = "row")
2322
+# draw(anno, index = 1:100, test = "anno_mark")
2323
+#
2324
+# m = matrix(1:1000, byrow = TRUE, nr = 100)
2325
+# anno = anno_mark(at = c(1:4, 20, 60, 97:100), labels = month.name[1:10], which = "row")
2326
+# Heatmap(m, cluster_rows = F, cluster_columns = F) + rowAnnotation(mark = anno)
2327
+# Heatmap(m) + rowAnnotation(mark = anno)
2328
+anno_mark = function(at, labels, which = c("column", "row"), 
2329
+	side = ifelse(which == "column", "top", "right"),
2330
+	lines_gp = gpar(), labels_gp = gpar(), padding = 0.5, 
2331
+	link_width = unit(5, "mm"), link_gp = lines_gp, 
2332
+	extend = unit(0, "mm")) {
2124 2333
 
2125 2334
 	if(is.null(.ENV$current_annotation_which)) {
2126 2335
 		which = match.arg(which)[1]
... ...
@@ -2256,46 +2465,36 @@ subset_by_intersect = function(x, i) {
2256 2465
 	intersect(x, i)
2257 2466
 }
2258 2467
 
2259
-anno_link = function(...) {
2260
-	warning("anno_link() is deprecated, please use anno_mark() instead.")
2261
-	anno_mark(...)
2262
-}
2263
-
2264 2468
 # == title
2265
-# Column annotation which is represented as links
2469
+# Label Markers Annotation
2266 2470
 #
2267 2471
 # == param
2268
-# -... pass to `anno_link`
2472
+# -... Pass to `anno_mark`.
2269 2473
 #
2270 2474
 # == details
2271
-# A wrapper of `anno_link` with pre-defined ``which`` to ``row``.
2272
-#
2273
-# == value
2274
-# See help page of `anno_link`
2475
+# `anno_link` is deprecated, please use `anno_mark` instead.
2275 2476
 #
2276
-# == author
2277
-# Zuguang Gu <z.gu@dkfz.de>
2278
-#
2279
-row_anno_link = function(...) {
2280
-	anno_link(..., which = "row")
2477
+anno_link = function(...) {
2478
+	warning("anno_link() is deprecated, please use anno_mark() instead.")
2479
+	anno_mark(...)
2281 2480
 }
2282 2481
 
2482
+
2283 2483
 # == title
2284
-# Column annotation which is represented as links
2484
+# Label Markers as Row Annotation
2285 2485
 #
2286 2486
 # == param
2287 2487
 # -... pass to `anno_link`
2288 2488
 #
2289 2489
 # == details
2290
-# A wrapper of `anno_link` with pre-defined ``which`` to ``column``.
2490
+# A wrapper of `anno_link` with pre-defined ``which`` to ``row``.
2491
+#
2492
+# You can directly use `anno_link` for row annotation if you call it in `rowAnnotation`.
2291 2493
 #
2292 2494
 # == value
2293 2495
 # See help page of `anno_link`
2294 2496
 #
2295
-# == author
2296
-# Zuguang Gu <z.gu@dkfz.de>
2297
-#
2298
-column_anno_link = function(...) {
2299
-	anno_link(..., which = "column")
2497
+row_anno_link = function(...) {
2498
+	anno_link(..., which = "row")
2300 2499
 }
2301 2500
 
... ...
@@ -663,7 +663,7 @@ Heatmap = function(matrix, col, name,
663 663
     if(is.null(top_annotation)) {
664 664
         .Object@top_annotation_param$height = unit(0, "mm")    
665 665
     } else {
666
-        .Object@top_annotation_param$height = height(bottom_annotation) + COLUMN_ANNO_PADDING*2  # append the gap
666
+        .Object@top_annotation_param$height = height(top_annotation) + COLUMN_ANNO_PADDING*2  # append the gap
667 667
     }
668 668
     if(!is.null(top_annotation)) {
669 669
         if(length(top_annotation) > 0) {
... ...
@@ -711,7 +711,7 @@ nobs.HeatmapAnnotation = function(object, ...) {
711 711
 	n_anno = length(object@anno_list)
712 712
 	len = sapply(seq_len(n_anno), function(i) {
713 713
 		if(inherits(object@anno_list[[i]]@fun, "AnnotationFunction")) {
714
-			object@anno_list[[i]]@fun@n
714
+			nobs(object@anno_list[[i]]@fun)
715 715
 		} else {
716 716
 			NA
717 717
 		}
... ...
@@ -999,12 +999,12 @@ setMethod(f = "adjust_heatmap_list",
999 999
         if(has_component(object@ht_list[[i]], "top_annotation")) {
1000 1000
             if(verbose) qqcat("adjust height of top annotation of heamtap @{object@ht_list[[i]]@name}\n")
1001 1001
             object@ht_list[[i]]@top_annotation = resize(object@ht_list[[i]]@top_annotation, height = max_top_anno_height)
1002
-            object@ht_list[[i]] = set_component_height(object@ht_list[[i]], k = 4, object@ht_list[[i]]@top_annotation@size)
1002
+            object@ht_list[[i]] = set_component_height(object@ht_list[[i]], k = 4, object@ht_list[[i]]@top_annotation@height)
1003 1003
         }
1004 1004
         if(has_component(object@ht_list[[i]], "bottom_annotation")) {   
1005 1005
             if(verbose) qqcat("adjust height of bottom annotation of heamtap @{object@ht_list[[i]]@name}\n")
1006 1006
             object@ht_list[[i]]@bottom_annotation = resize(object@ht_list[[i]]@bottom_annotation, height = max_bottom_anno_height)
1007
-            object@ht_list[[i]] = set_component_height(object@ht_list[[i]], k = 6, object@ht_list[[i]]@bottom_annotation@size)
1007
+            object@ht_list[[i]] = set_component_height(object@ht_list[[i]], k = 6, object@ht_list[[i]]@bottom_annotation@height)
1008 1008
         }
1009 1009
     }
1010 1010
 
... ...
@@ -1,7 +1,7 @@
1 1
 
2 2
 
3 3
 # == title 
4
-# Class for a single annotation
4
+# Class for a Single Annotation
5 5
 #
6 6
 # == details
7 7
 # A complex heatmap always has more than one annotations on rows and columns. Here
... ...
@@ -1,32 +1,4 @@
1 1
 
2
-# == title
3
-# Draw dendrogram under grid system
4
-#
5
-# == param
6
-# -dend a `stats::dendrogram` object.
7
-# -facing facing of the dendrogram.
8
-# -max_height maximum height of the dendrogram. It is useful to make dendrograms comparable
9
-#             if you want to plot more than one dendrograms. Height for each dendrogram can be obtained by
10
-#             ``attr(dend, "height")``.
11
-# -order should leaves of dendrogram be put in the normal order (1, ..., n) or reverse order (n, ..., 1)?
12
-#        It may matters for the dendrograms putting on left and right.
13
-# -... pass to `grid::viewport` which contains the dendrogram.
14
-#
15
-# == details
16
-# The dendrogram can be renderred (e.g. by ``dendextend`` package).
17
-#
18
-# A viewport is created which contains the dendrogram.
19
-#
20
-# This function only plots the dendrogram without adding labels. The leaves of the dendrogram
21
-# locates at ``unit(c(0.5, 1.5, ...(n-0.5))/n, "npc")``.
22
-#
23
-# == value
24
-# No value is returned.
25
-#
26
-# == author
27
-# Zuguang Gu <z.gu@dkfz.de>
28
-#
29
-
30 2
 ############
31 3
 ## for these functions, plotting dendrogram does not reply on the midpoint attribute in the
32 4
 ## dendrogram object, the positions of all nodes are calculated and stored as x attribute
... ...
@@ -40,15 +12,34 @@ subset_dendrogram = function(x, ind) {
40 12
     }
41 13
 }
42 14
 
43
-adjust_dend_by_x = function(dend, x = 1:nobs(dend)-0.5) {
15
+# == title
16
+# Adjust the Positions of nodes/leaves in the Dendrogram
17
+#
18
+# == param
19
+# -dend A `dendrogram` object
20
+# -leaf_pos A vector of positions of leaves. The value can also be a `grid.unit` object.
21
+#
22
+# == detail
23
+# The positions of nodes stored as ``x`` attribute are recalculated based on the new positions of leaves.
24
+# 
25
+# By default, the position of leaves are at 0.5, 1.5, ..., n-0.5.
26
+#
27
+# == example
28
+# m = matrix(rnorm(100), 10)
29
+# dend = as.dendrogram(hclust(dist(m)))
30
+# dend = adjust_dend_by_x(dend, sort(runif(10)))
31
+# str(dend)
32
+# dend = adjust_dend_by_x(dend, unit(1:10, "cm"))
33
+# str(dend)
34
+adjust_dend_by_x = function(dend, leaf_pos = 1:nobs(dend)-0.5) {
44 35
     n = nobs(dend)
45 36
 
46
-    if(length(x) != n) {
47
-        stop("`x` should be a vector with same length as `dend`.")
37
+    if(length(leaf_pos) != n) {
38
+        stop("`leaf_pos` should be a vector with same length as `dend`.")
48 39
     }
49 40
 
50 41
     dend_order = order.dendrogram(dend)
51
-    leaves_pos = x
42
+    leaves_pos = leaf_pos
52 43
     od2index = NULL
53 44
     od2index[dend_order] = 1:n
54 45
 
... ...
@@ -190,6 +181,25 @@ construct_dend_segments = function(dend, gp) {
190 181
 
191 182
 }
192 183
 
184
+
185
+# == title
186
+# Grob for Dendrogram
187
+#
188
+# == param
189
+# -dend A `dendrogram` object.
190
+# -facing Facing of the dendrogram.
191
+# -order If it is set to ``reverse``, the first element is put on the right if the dendrogram
192
+#        is horizontal and it is put on the top if the dendrogram is vertical.
193
+# -gp Graphic parameters for the dendrogram segments. If any of ``col``, ``lwd`` or ``lty`` is set
194
+#     in the ``edgePar`` attribute of a node, the corresponding value defined in ``gp`` will be
195
+#     overwritten for this node, so ``gp`` is like a global graphic parameters for dendrogram segments.
196
+#
197
+# == details
198
+# If ``dend`` has not been processed by `adjust_dend_by_x`, internally `adjust_dend_by_x` is called
199
+# to add ``x`` attributes of each node/leaf.
200
+#
201
+# == value
202
+# A `grob` object which is generally contructed by `grid::segmentsGrob`.
193 203
 dendrogramGrob = function(dend, facing = c("bottom", "top", "left", "right"),
194 204
     order = c("normal", "reverse"), gp = gpar()) {
195 205
 
... ...
@@ -226,6 +236,38 @@ dendrogramGrob = function(dend, facing = c("bottom", "top", "left", "right"),
226 236
     }
227 237
 }
228 238
 
239
+# == title
240
+# Draw the Dendrogram
241
+#
242
+# == param
243
+# -dend A `dendrogram` object.
244
+# -... Pass to `dendrogramGrob`.
245
+# -test Is it in test mode? If it is in test mode, a viewport is created by calculating proper xlim and ylim.
246
+#
247
+# == detail
248
+# `grid.dendrogram` supports drawing dendrograms with self-defind leaf positions. The positions
249
+# of leaves can be defined by `adjust_dend_by_x`. Also the dendrogram can be customized by setting
250
+# the ``edgePar`` attribute for each node (basically for controlling the style of segments), e.g.
251
+# by `dendextend::color_branches`.
252
+# 
253
+# To draw the dendrogram, a viewport should be firstly created. `dend_xy` can be used to get the 
254
+# positions of leaves and height of the dendrogram.
255
+#
256
+# == example
257
+# m = matrix(rnorm(100), 10)
258
+# dend = as.dendrogram(hclust(dist(m)))
259
+# grid.newpage()
260
+# pushViewport(viewport(xscale = c(0, 10.5), yscale = c(0, dend_heights(dend)), 
261
+#     width = 0.9, height = 0.9))
262
+# grid.dendrogram(dend)
263
+# popViewport()
264
+#
265
+# grid.dendrogram(dend, test = TRUE)
266
+#
267
+# require(dendextend2)
268
+# dend = color_branches(dend, k = 2)
269
+# dend = adjust_dend_by_x(dend, unit(sort(runif(10)*10), "cm"))
270
+# grid.dendrogram(dend, test = TRUE)
229 271
 grid.dendrogram = function(dend, ..., test = FALSE) {
230 272
     gb = dendrogramGrob(dend, ...)
231 273
     if(test) {
... ...
@@ -233,7 +275,7 @@ grid.dendrogram = function(dend, ..., test = FALSE) {
233 275
         ylim[1] = - 0.05*(ylim[2] - ylim[1])
234 276
         ylim[2] = ylim[2] + 0.05*ylim[2]
235 277
         grid.newpage()
236
-        if(is.unit(gb$x0[1])) {
278
+        if(is_abs_unit(gb$x0[1]) && !identical("native", attr(gb$x0[1], "unit"))) {
237 279
             width = max(unit.c(gb$x0, gb$x1))
238 280
             pushViewport(viewport(yscale = ylim, 
239 281
                 width = width*1.1, 
... ...
@@ -257,10 +299,42 @@ grid.dendrogram = function(dend, ..., test = FALSE) {
257 299
     }
258 300
 }
259 301
 
260
-merge.dendrogram = function(x, y, only_parent = FALSE, reorder = TRUE, ...) {
261
-
262
-    parent = x
263
-    children = y
302
+# == title
303
+# Merge Dendrograms
304
+# 
305
+# == param
306
+# -parent The parent dendrogram.
307
+# -children The children dendrograms. They are connected to the leaves of the parent dendrogram.
308
+#           So the length of ``children`` should be as same as the number of leaves of the parent dendrogram.
309
+# -only_parent Whether only returns the parent dendrogram where the height and node positions have
310
+#              been adjusted by children dendrograms.
311
+# -... Other arguments.
312
+#
313
+# == details
314
+# Do not retrieve the order of the merged dendrogram. It is not reliable.
315
+#
316
+# == example
317
+# m1 = matrix(rnorm(100), nr = 10)
318
+# m2 = matrix(rnorm(80), nr = 8)
319
+# m3 = matrix(rnorm(50), nr = 5)
320
+# dend1 = as.dendrogram(hclust(dist(m1)))
321
+# dend2 = as.dendrogram(hclust(dist(m2)))
322
+# dend3 = as.dendrogram(hclust(dist(m3)))
323
+# dend_p = as.dendrogram(hclust(dist(rbind(colMeans(m1), colMeans(m2), colMeans(m3)))))
324
+# dend_m = merge(dend_p, list(dend1, dend2, dend3))
325
+# grid.dendrogram(dend_m, test = TRUE)
326
+#
327
+# dend_m = merge(dend_p, list(dend1, dend2, dend3), only_parent = TRUE)
328
+# grid.dendrogram(dend_m, test = TRUE)
329
+#
330
+# require(dendextend)
331
+# dend1 = color_branches(dend1, k = 1, col = "red")
332
+# dend2 = color_branches(dend2, k = 1, col = "blue")
333
+# dend3 = color_branches(dend3, k = 1, col = "green")
334
+# dend_p = color_branches(dend_p, k = 1, col = "orange")
335
+# dend_m = merge(dend_p, list(dend1, dend2, dend3))
336
+# grid.dendrogram(dend_m, test = TRUE)
337
+merge.dendrogram = function(parent, children, only_parent = FALSE, ...) {
264 338
 
265 339
     n = nobs(parent)
266 340
     if(n != length(children)) {
... ...
@@ -343,19 +417,17 @@ merge.dendrogram = function(x, y, only_parent = FALSE, reorder = TRUE, ...) {
343 417
     attr(dend, "members") = sum(children_members)
344 418
 
345 419
     # adjust order of leaves
346
-    if(reorder) {
347
-        od_parent = order.dendrogram(parent)
348
-        od_children = lapply(children, function(x) order.dendrogram(x))
349
-
350
-        s = 0
351
-        for(i in seq_along(od_parent)) {
352
-            od_children[[ od_parent[i] ]] = od_children[[ od_parent[i] ]] + s
353
-            s = s + length(od_children[[ od_parent[i] ]])
354
-        }
420
+    od_parent = order.dendrogram(parent)
421
+    od_children = lapply(children, function(x) rank(order.dendrogram(x)))
355 422
 
356
-        order.dendrogram(dend) = unlist(od_children)
423
+    s = 0
424
+    for(i in seq_along(od_parent)) {
425
+        od_children[[ od_parent[i] ]] = od_children[[ od_parent[i] ]] + s
426
+        s = s + length(od_children[[ od_parent[i] ]])
357 427
     }
358 428
 
429
+    order.dendrogram(dend) = unlist(od_children)
430
+    
359 431
     attr(dend, "children_height") = children_height
360 432
     attr(dend, "parent_height") = parent_height
361 433
     attr(dend, "h_line") = h_line
... ...
@@ -372,12 +444,12 @@ get_branches_heights = function(dend) {
372 444
 }
373 445
 
374 446
 "order.dendrogram<-" = function(x, value) {
375
-    map = NULL
376
-    n = nobs(x)
377
-    map[ order.dendrogram(x) ] = seq_len(n)
447
+    env = new.env()
448
+    env$i = 0
378 449
     dendrapply(x, function(node) {
379 450
         if(is.leaf(node)) {
380
-            node[[1]] = value[ map[ node[[1]] ] ]
451
+            env$i = env$i + 1
452
+            node[[1]] = value[ env$i ]
381 453
         }
382 454
         return(node)
383 455
     })
... ...
@@ -415,3 +487,104 @@ dend_heights = function(x) {
415 487
         sapply(x, function(y) attr(y, "height"))
416 488
     }
417 489
 }
490
+
491
+# == title
492
+# Coordinates of the Dendrogram
493
+#
494
+# == param
495
+# -dend a `dendrogram` object.
496
+#
497
+# == detail
498
+# ``dend`` will be processed by `adjust_dend_by_x` if it is processed yet.
499
+#
500
+# == value
501
+# A list of leave positions and dendrogram height.
502
+#
503
+# == example
504
+# m = matrix(rnorm(100), 10)
505
+# dend1 = as.dendrogram(hclust(dist(m)))
506
+# dend_xy(dend1)
507
+#
508
+# dend1 = adjust_dend_by_x(dend1, sort(runif(10)))
509
+# dend_xy(dend1)
510
+#
511
+# dend1 = adjust_dend_by_x(dend1, unit(1:10, "cm"))
512
+# dend_xy(dend1)
513
+dend_xy = function(dend) {
514
+    if(is.null(attr(dend, "x"))) {
515
+        dend = adjust_dend_by_x(dend)
516
+    }
517
+    env = new.env()
518
+    env$lt = list()
519
+    dendrapply(dend, function(d) {
520
+        if(is.leaf(d))
521
+            env$lt = c(env$lt, list(attr(d, "x")))
522
+    })
523
+    x = env$lt
524
+    if(inherits(x[[1]], "unit")) {
525
+        x = do.call("unit.c", x)
526
+    } else {
527
+        x = unlist(x)
528
+    }
529
+    return(list(x = x,
530
+                y = c(0, dend_heights(dend1))))
531
+}
532
+
533
+
534
+# == title
535
+# Cluster within and between Groups
536
+#
537
+# == param
538
+# -mat A matrix where clustering is applied on columns.
539
+# -factor A categorical vector.
540
+#
541
+# == details
542
+# The clustering is firstly applied in each group, then clustering is applied
543
+# to group means. The within-group dendrograms and between-group dendrogram
544
+# are finally connected by `merge.dendrogram`.
545
+#
546
+# In the final dendrogram, the within group dendrograms are enforced to be 
547
+# flat lines to emphasize that the within group dendrograms have no sense to 
548
+# compare to between-group dendrogram.
549
+#
550
+# == value
551
+# A `dendrogram` object. The order of columns can be retrieved by `order.dendrogram`.
552
+#
553
+# == example
554
+# m = matrix(rnorm(120), nc = 12)
555
+# colnames(m) = letters[1:12]
556
+# fa = rep(c("a", "b", "c"), times = c(2, 4, 6))
557
+# dend = cluster_within_group(m, fa)
558
+# grid.dendrogram(dend, test = TRUE)
559
+cluster_within_group = function(mat, factor) {
560
+
561
+    if (!is.factor(factor)) {
562
+        factor = factor(factor, levels = unique(factor))
563
+    }
564
+
565
+    dend_list = list()
566
+    order_list = list()
567
+    for(le in unique(levels(factor))) {
568
+        m = mat[, factor == le, drop = FALSE]
569
+        if (ncol(m) == 1) {
570
+            order_list[[le]] = which(factor == le)
571
+            dend_list[[le]] = structure(which(factor == le), class = "dendrogram", leaf = TRUE,
572
+                height = 0, label = 1, members = 1)
573
+        } else {
574
+            hc1 = hclust(dist(t(m)))
575
+            dend_list[[le]] = as.dendrogram(hc1)
576
+            order_list[[le]] = which(factor == le)[order.dendrogram(dend_list[[le]])]
577
+            order.dendrogram(dend_list[[le]]) = order_list[[le]]
578
+        }
579
+    }
580
+    
581
+    parent = as.dendrogram(hclust(dist(t(sapply(order_list, function(x) rowMeans(mat[, x, drop = FALSE]))))))
582
+    dend_list = lapply(dend_list, function(dend) dendrapply(dend, function(node) {
583
+        attr(node, "height") = 0
584
+        node
585
+    }))
586
+    dend = merge(parent, dend_list)
587
+    order.dendrogram(dend) = unlist(order_list)
588
+    return(dend)
589
+   
590
+}
... ...
@@ -415,40 +415,6 @@ unit.c = function(...) {
415 415
     do.call(grid::unit.c, lt)
416 416
 }
417 417
 
418
-cluster_within_group = function(mat, factor, only_order = FALSE) {
419
-
420
-    if (!is.factor(factor)) {
421
-        factor = factor(factor, levels = unique(factor))
422
-    }
423
-
424
-    dend_list = list()
425
-    order_list = list()
426
-    for(le in unique(levels(factor))) {
427
-        m = mat[, factor == le, drop = FALSE]
428
-        if (ncol(m) == 1) {
429
-            order_list[[le]] = which(factor == le)
430
-            dend_list[[le]] = structure(which(factor == le), class = "dendrogram", leaf = TRUE,
431
-                height = 0, label = 1, members = 1)
432
-        } else {
433
-            hc1 = hclust(dist(t(m)))
434
-            dend_list[[le]] = as.dendrogram(hc1)
435
-            order_list[[le]] = which(factor == le)[order.dendrogram(dend_list[[le]])]
436
-            order.dendrogram(dend_list[[le]]) = order_list[[le]]
437
-        }
438
-    }
439
-    if(only_order) {
440
-        return(unlist(order_list))
441
-    } else {
442
-        parent = as.dendrogram(hclust(dist(t(sapply(order_list, function(x) rowMeans(mat[, x, drop = FALSE]))))))
443
-        dend_list = lapply(dend_list, function(dend) dendrapply(dend, function(node) {
444
-            attr(node, "height") = 0
445
-            node
446
-        }))
447
-        dend = merge(parent, dend_list, reorder = TRUE)
448
-        return(dend)
449
-    }
450
-}
451
-
452 418
 
453 419
 normalize_graphic_param_to_mat = function(x, nc, nr, name) {
454 420
     if(is.matrix(x)) {
... ...
@@ -101,6 +101,10 @@ draw(anno[1:5], test = "png + gp")
101 101
 anno = anno_image(image1, space = unit(3, "mm"))
102 102
 draw(anno, test = "space")
103 103
 
104
+image1[1] = ""
105
+anno = anno_image(image1)
106
+draw(anno, test = "png")
107
+
104 108
 ######## test anno_points #####
105 109
 anno = anno_points(runif(10))
106 110
 draw(anno, test = "anno_points")
... ...
@@ -111,6 +115,15 @@ draw(anno, test = "anno_points")
111 115
 anno = anno_points(cbind(c(1:5, 1:5), c(5:1, 5:1)), gp = gpar(col = 2:3))
112 116
 draw(anno, test = "matrix")
113 117
 
118
+##### test anno_lines ###
119
+anno = anno_lines(runif(10))
120
+draw(anno, test = "anno_lines")
121
+anno = anno_lines(cbind(c(1:5, 1:5), c(5:1, 5:1)), gp = gpar(col = 2:3))
122
+draw(anno, test = "matrix")
123
+anno = anno_lines(cbind(c(1:5, 1:5), c(5:1, 5:1)), gp = gpar(col = 2:3),
124
+	add_points = TRUE, pt_gp = gpar(col = 5:6), pch = c(1, 16))
125
+draw(anno, test = "matrix")
126
+
114 127
 
115 128
 ###### test anno_text #######
116 129
 anno = anno_text(month.name)
... ...
@@ -1,6 +1,6 @@
1 1
 m = matrix(rnorm(100), 10)
2 2
 dend1 = as.dendrogram(hclust(dist(m)))
3
-dend1 = adjust_dend_by_x(dend1, x = sort(runif(10)))
3
+dend1 = adjust_dend_by_x(dend1, sort(runif(10)))
4 4
 
5 5
 m = matrix(rnorm(50), nr = 5)
6 6
 dend2 = as.dendrogram(hclust(dist(m)))
... ...
@@ -24,9 +24,40 @@ grid.dendrogram(dend_merge, test = TRUE, facing = "left", order = "reverse")
24 24
 grid.dendrogram(dend_merge, test = TRUE, facing = "right", order = "reverse")
25 25
 
26 26
 
27
+m = matrix(rnorm(100), 10)
27 28
 dend1 = as.dendrogram(hclust(dist(m)))
28
-dend1 = adjust_dend_by_x(dend1, x = unit(1:10, "cm"))
29
+dend1 = adjust_dend_by_x(dend1, unit(1:10, "cm"))
29 30
 grid.dendrogram(dend1, test = TRUE)
30 31
 
31 32
 dl = cut_dendrogram(dend1, k = 3)
32 33
 grid.dendrogram(dl$upper, test = TRUE)
34
+
35
+
36
+m1 = matrix(rnorm(100), nr = 10)
37
+m2 = matrix(rnorm(80), nr = 8)
38
+m3 = matrix(rnorm(50), nr = 5)
39
+dend1 = as.dendrogram(hclust(dist(m1)))
40
+dend2 = as.dendrogram(hclust(dist(m2)))
41
+dend3 = as.dendrogram(hclust(dist(m3)))
42
+dend_p = as.dendrogram(hclust(dist(rbind(colMeans(m1), colMeans(m2), colMeans(m3)))))
43
+dend_m = merge(dend_p, list(dend1, dend2, dend3))
44
+grid.dendrogram(dend_m, test = T)
45
+
46
+dend_m = merge(dend_p, list(dend1, dend2, dend3), only_parent = TRUE)
47
+grid.dendrogram(dend_m, test = T)
48
+
49
+require(dendextend)
50
+dend1 = color_branches(dend1, k = 1, col = "red")
51
+dend2 = color_branches(dend2, k = 1, col = "blue")
52
+dend3 = color_branches(dend3, k = 1, col = "green")
53
+dend_p = color_branches(dend_p, k = 1, col = "orange")
54
+dend_m = merge(dend_p, list(dend1, dend2, dend3))
55
+grid.dendrogram(dend_m, test = T)
56
+
57
+
58
+m = matrix(rnorm(120), nc = 12)
59
+colnames(m) = letters[1:12]
60
+fa = rep(c("a", "b", "c"), times = c(2, 4, 6))
61
+dend = cluster_within_group(m, fa)
62
+grid.dendrogram(dend, test = TRUE)
63
+