Browse code

remove old vignettes

jokergoo authored on 30/10/2018 12:52:23
Showing 1 changed files
1 1
deleted file mode 100755
... ...
@@ -1,652 +0,0 @@
1
-<!--
2
-%\VignetteEngine{knitr}
3
-%\VignetteIndexEntry{4. Heatmap Annotations}
4
-
5
-Heatmap Annotations
6
-========================================
7
-
8
-**Author**: Zuguang Gu ( z.gu@dkfz.de )
9
-
10
-**Date**: `r Sys.Date()`
11
-
12
-
13
-```{r global_settings, echo = FALSE, message = FALSE}
14
-library(markdown)
15
-options(markdown.HTML.options = c(options('markdown.HTML.options')[[1]], "toc"))
16
-
17
-library(knitr)
18
-knitr::opts_chunk$set(
19
-    error = FALSE,
20
-    tidy  = FALSE,
21
-    message = FALSE,
22
-    fig.align = "center",
23
-    fig.width = 5,
24
-    fig.height = 5)
25
-options(markdown.HTML.stylesheet = "custom.css")
26
-
27
-options(width = 100)
28
-```
29
-
30
-The annotation graphics actually are quite general. The only common characteristic for annotations
31
-is that they are aligned to the columns or rows of the heatmap. Here there is a `HeatmapAnnotation` class which is used to 
32
-define annotations on columns or rows.
33
-
34
-## Column annotation
35
-
36
-### Simple annotation
37
-
38
-A simple annotation is defined as a vector which contains discrete classes or continuous values.
39
-Since the simple annotation is represented as a vector, multiple simple annotations can be specified
40
-as a data frame. Colors for the simple annotations can be specified by `col` with a vector or
41
-color mapping functions, depending on whether the simple annotations are discrete or continuous.
42
-
43
-In the heatmap, simple annotations will be represented as rows of grids.
44
-
45
-There is a `draw()` method for the `HeatmapAnnotation` class. `draw()` is used internally and here
46
-we just use it for demonstration.
47
-
48
-```{r heatmap_annotation, fig.width = 7, fig.height = 0.5}
49
-library(ComplexHeatmap)
50
-library(circlize)
51
-
52
-df = data.frame(type = c(rep("a", 5), rep("b", 5)))
53
-ha = HeatmapAnnotation(df = df)
54
-ha
55
-draw(ha, 1:10)
56
-```
57
-
58
-The color of simple annotation should be specified as a list with names for which names in the color list (here it is `type` in following example)
59
-correspond to the names in the data frame. Each color vector should better has names as well to map to 
60
-the levels of annotations.
61
-
62
-```{r heatmap_annotation_col, fig.width = 7, fig.height = 0.5}
63
-ha = HeatmapAnnotation(df = df, col = list(type = c("a" =  "red", "b" = "blue")))
64
-ha
65
-draw(ha, 1:10)
66
-```
67
-
68
-For continuous annotation, colors should be a color mapping function.
69
-
70
-```{r heatmap_annotation_colfun, fig.width = 7, fig.height = 0.5}
71
-ha = HeatmapAnnotation(df = data.frame(age = sample(1:20, 10)),
72
-    col = list(age = colorRamp2(c(0, 20), c("white", "red"))))
73
-ha
74
-draw(ha, 1:10)
75
-```
76
-
77
-Color for `NA` can be set by `na_col`:
78
-
79
-```{r, fig.width = 7, fig.height = 1}
80
-df2 = data.frame(type = c(rep("a", 5), rep("b", 5)),
81
-                age = sample(1:20, 10))
82
-df2$type[5] = NA
83
-df2$age[5] = NA
84
-ha = HeatmapAnnotation(df = df2, 
85
-  col = list(type = c("a" =  "red", "b" = "blue"),
86
-             age = colorRamp2(c(0, 20), c("white", "red"))),
87
-  na_col = "grey")
88
-draw(ha, 1:10)
89
-```
90
-
91
-Put more than one annotations by a data frame.
92
-
93
-```{r heatmap_annotation_mixed, fig.width = 7, fig.height = 1}
94
-df = data.frame(type = c(rep("a", 5), rep("b", 5)),
95
-                age = sample(1:20, 10))
96
-ha = HeatmapAnnotation(df = df,
97
-    col = list(type = c("a" = "red", "b" = "blue"),
98
-               age = colorRamp2(c(0, 20), c("white", "red")))
99
-)
100
-ha
101
-draw(ha, 1:10)
102
-```
103
-
104
-Also individual annotations can be directly specified as vectors:
105
-
106
-```{r heatmap_annotation_vector, fig.width = 7, fig.height = 1}
107
-ha = HeatmapAnnotation(type = c(rep("a", 5), rep("b", 5)),
108
-                       age = sample(1:20, 10),
109
-    col = list(type = c("a" = "red", "b" = "blue"),
110
-               age = colorRamp2(c(0, 20), c("white", "red")))
111
-)
112
-ha
113
-draw(ha, 1:10)
114
-```
115
-
116
-To put column annotation to the heatmap, specify `top_annotation` and `bottom_annotation` in `Heatmap()`.
117
-
118
-```{r heatmap_column_annotation}
119
-ha1 = HeatmapAnnotation(df = df,
120
-    col = list(type = c("a" = "red", "b" = "blue"),
121
-               age = colorRamp2(c(0, 20), c("white", "red")))
122
-)
123
-ha2 = HeatmapAnnotation(df = data.frame(age = sample(1:20, 10)),
124
-    col = list(age = colorRamp2(c(0, 20), c("white", "red"))))
125
-
126
-set.seed(123)
127
-mat = matrix(rnorm(80, 2), 8, 10)
128
-mat = rbind(mat, matrix(rnorm(40, -2), 4, 10))
129
-rownames(mat) = paste0("R", 1:12)
130
-colnames(mat) = paste0("C", 1:10)
131
-
132
-Heatmap(mat, top_annotation = ha1, bottom_annotation = ha2)
133
-```
134
-
135
-### Complex annotations
136
-
137
-Besides simple annotations, there are complex annotations. The complex annotations are always
138
-represented as self-defined graphic functions. Actually, for each column annotation, there will be a viewport
139
-created waiting for graphics. The annotation function here defines how to put the graphics to
140
-this viewport. The only argument of the function is an index of column which is already adjusted by column clustering.
141
-
142
-In following example, an annotation of points is created. Please note how we define `xscale` so that positions
143
-of points correspond to middle points of the columns if the annotation is added to the heatmap.
144
-
145
-```{r heatmap_annotation_complex, fig.width = 7, fig.height = 1}
146
-value = rnorm(10)
147
-column_anno = function(index) {
148
-    n = length(index)
149
-    # since middle of columns are in 1, 2, ..., n and each column has width 1
150
-    # then the most left should be 1 - 0.5 and the most right should be n + 0.5
151
-    pushViewport(viewport(xscale = c(0.5, n + 0.5), yscale = range(value)))
152
-    # since order of columns will be adjusted by clustering, here we also 
153
-    # need to change the order by `[index]`
154
-    grid.points(index, value[index], pch = 16, default.unit = "native")
155
-    # this is very important in order not to mess up the layout
156
-    upViewport() 
157
-}
158
-ha = HeatmapAnnotation(points = column_anno)  # here the name is arbitrary
159
-ha
160
-draw(ha, 1:10)
161
-```
162
-
163
-Above code is only for demonstration. You don't realy need to define a points annotation,
164
-there are already several annotation generators provided in the package such as `anno_points()` or `anno_barplot()`
165
-which generate such complex annotation function:
166
-
167
-- `anno_points()`
168
-- `anno_barplot()`
169
-- `anno_boxplot()`
170
-- `anno_histogram()`
171
-- `anno_density()`
172
-- `anno_text()`
173
-
174
-The input value for these `anno_*` functions is quite straightforward. It should be a numeric vector 
175
-(e.g. for `anno_points()` and `anno_barplot()`), a matrix or list (for `anno_boxplot()`, `anno_histogram()` 
176
-or `anno_density()`), or a character vector (for `anno_text()`).
177
-
178
-```{r heatmap_annotation_points, fig.width = 7, fig.height = 1}
179
-ha = HeatmapAnnotation(points = anno_points(value))
180
-draw(ha, 1:10)
181
-```
182
-
183
-```{r heatmap_annotation_barplot, fig.width = 7, fig.height = 1}
184
-ha = HeatmapAnnotation(barplot = anno_barplot(value))
185
-draw(ha, 1:10)
186
-```
187
-
188
-`anno_boxplot()` generates boxplot for each column in the matrix.
189
-
190
-```{r heatmap_annotation_boxplot, fig.width = 7, fig.height = 1}
191
-ha = HeatmapAnnotation(boxplot = anno_boxplot(mat))
192
-draw(ha, 1:10)
193
-```
194
-
195
-You can mix simple annotations and complex annotations:
196
-
197
-```{r heatmap_annotation_mixed_with_complex, fig.width = 7, fig.height = 2}
198
-ha = HeatmapAnnotation(df = df, 
199
-                       points = anno_points(value),
200
-    col = list(type = c("a" = "red", "b" = "blue"),
201
-               age = colorRamp2(c(0, 20), c("white", "red"))))
202
-ha
203
-draw(ha, 1:10)
204
-```
205
-
206
-Since simple annotations can also be specified as vectors, actually you arrange annotations in any order:
207
-
208
-```{r, fig.width = 7, fig.height = 2}
209
-ha = HeatmapAnnotation(type = c(rep("a", 5), rep("b", 5)),
210
-                       points = anno_points(value),
211
-                       age = sample(1:20, 10), 
212
-                       bars = anno_barplot(value),
213
-    col = list(type = c("a" = "red", "b" = "blue"),
214
-               age = colorRamp2(c(0, 20), c("white", "red"))))
215
-ha
216
-draw(ha, 1:10)
217
-```
218
-
219
-For some of the `anno_*` functions, graphic parameters can be set by `gp` argument.
220
-Also note how we specify `baseline` in `anno_barplot()`.
221
-
222
-```{r heatmap_annotation_anno_gp, fig.width = 7, fig.height = 3}
223
-ha = HeatmapAnnotation(barplot1 = anno_barplot(value, baseline = 0, gp = gpar(fill = ifelse(value > 0, "red", "green"))),
224
-                       points = anno_points(value, gp = gpar(col = rep(1:2, 5))),
225
-                       barplot2 = anno_barplot(value, gp = gpar(fill = rep(3:4, 5))))
226
-ha
227
-draw(ha, 1:10)
228
-```
229
-
230
-If there are more than one annotations, you can control height of each annotation by `annotation_height`.
231
-The value of `annotation_height` can either be numeric values or `unit` objects.
232
-
233
-```{r, fig.width = 7, fig.height = 3}
234
-# set annotation height as relative values
235
-ha = HeatmapAnnotation(df = df, points = anno_points(value), boxplot = anno_boxplot(mat),
236
-    col = list(type = c("a" = "red", "b" = "blue"),
237
-               age = colorRamp2(c(0, 20), c("white", "red"))),
238
-    annotation_height = c(1, 2, 3, 4))
239
-draw(ha, 1:10)
240
-```
241
-
242
-```{r, fig.width = 7, fig.height = 3}
243
-# set annotation height as absolute units
244
-ha = HeatmapAnnotation(df = df, points = anno_points(value), boxplot = anno_boxplot(mat),
245
-    col = list(type = c("a" = "red", "b" = "blue"),
246
-               age = colorRamp2(c(0, 20), c("white", "red"))),
247
-    annotation_height = unit.c((unit(1, "npc") - unit(4, "cm"))*0.5, (unit(1, "npc") - unit(4, "cm"))*0.5, 
248
-        unit(2, "cm"), unit(2, "cm")))
249
-draw(ha, 1:10)
250
-```
251
-
252
-With the annotation constructed, you can assign to the heatmap either by `top_annotation` or `bottom_annotation`.
253
-Also you can control the size of total column annotations by `top_annotation_height` and `bottom_annotation_height`
254
-if the height of the annotations are relative values.
255
-
256
-If the annotation has proper size (high enough), it would be helpful to add axis on it. `anno_points()`, `anno_barplot()` 
257
-and `anno_boxplot()` support axes. Please note we didn't pre-allocate space for axes particularly, 
258
-we only assume there are already empty spaces for showing axes.
259
-
260
-```{r add_annotation}
261
-ha = HeatmapAnnotation(df = df, points = anno_points(value),
262
-    col = list(type = c("a" = "red", "b" = "blue"),
263
-               age = colorRamp2(c(0, 20), c("white", "red"))))
264
-ha_boxplot = HeatmapAnnotation(boxplot = anno_boxplot(mat, axis = TRUE))
265
-Heatmap(mat, name = "foo", top_annotation = ha, bottom_annotation = ha_boxplot, 
266
-    bottom_annotation_height = unit(3, "cm"))
267
-```
268
-
269
-Gaps below each annotation can be specified by `gap` in `HeatmapAnnotation()`. 
270
-
271
-```{r}
272
-ha = HeatmapAnnotation(df = df, points = anno_points(value), gap = unit(c(2, 4), "mm"),
273
-    col = list(type = c("a" = "red", "b" = "blue"),
274
-               age = colorRamp2(c(0, 20), c("white", "red"))))
275
-Heatmap(mat, name = "foo", top_annotation = ha)
276
-```
277
-
278
-You can suppress some of the annotation legend by specifying `show_legend` to `FALSE` when creating the `HeatmapAnnotation` object.
279
-
280
-```{r annotation_show}
281
-ha = HeatmapAnnotation(df = df, show_legend = c(FALSE, TRUE),
282
-    col = list(type = c("a" = "red", "b" = "blue"),
283
-               age = colorRamp2(c(0, 20), c("white", "red"))))
284
-Heatmap(mat, name = "foo", top_annotation = ha)
285
-```
286
-
287
-More types of annotations which show data distribution in corresponding columns are supported
288
-by `anno_histogram()` and `anno_density()`.
289
-
290
-```{r annotation_more, fig.height = 10, fig.width = 7}
291
-ha_mix_top = HeatmapAnnotation(histogram = anno_histogram(mat, gp = gpar(fill = rep(2:3, each = 5))),
292
-    density_line = anno_density(mat, type = "line", gp = gpar(col = rep(2:3, each = 5))),
293
-    violin = anno_density(mat, type = "violin", gp = gpar(fill = rep(2:3, each = 5))),
294
-    heatmap = anno_density(mat, type = "heatmap"))
295
-Heatmap(mat, name = "foo", top_annotation = ha_mix_top, top_annotation_height = unit(8, "cm"))
296
-```
297
-
298
-Text is also one of the annotaiton graphics. `anno_text()` supports adding text as heatmap annotations. With this annotation
299
-function, it is easy to simulate column names with rotations. 
300
-Note you need to calcualte the space for the text annotations by hand and the package doesn't garentee
301
-that all the rotated text are shown in the plot (In following figure, if row names and legend are not drawn,
302
-'C10C10C10' will show completely, but there are some tricks which can be found in the [**Examples**](s9.examples.html) vignette).
303
-
304
-```{r rotated_column_names}
305
-long_cn = do.call("paste0", rep(list(colnames(mat)), 3))  # just to construct long text
306
-ha_rot_cn = HeatmapAnnotation(text = anno_text(long_cn, rot = 45, just = "left", offset = unit(2, "mm")))
307
-Heatmap(mat, name = "foo", top_annotation = ha_rot_cn, top_annotation_height = unit(2, "cm"))
308
-```
309
-
310
-## Row annotations
311
-
312
-Row annotation is also defined by the `HeatmapAnnotation` class, but with specifying
313
-`which` to `row`.
314
-
315
-```{r row_annotation, fig.width = 1, fig.height = 7}
316
-df = data.frame(type = c(rep("a", 6), rep("b", 6)))
317
-ha = HeatmapAnnotation(df = df, col = list(type = c("a" = "red", "b" = "blue")),
318
-    which = "row", width = unit(1, "cm"))
319
-draw(ha, 1:12)
320
-```
321
-
322
-There is a helper function `rowAnnotation()` which is same as `HeatmapAnnotation(..., which = "row")`.
323
-
324
-```{r, eval = FALSE}
325
-ha = rowAnnotation(df = df, col = list(type = c("a" = "red", "b" = "blue")), width = unit(1, "cm"))
326
-```
327
-
328
-`anno_*` functions also works for row annotations, by you need to add `which = "row"` in the function.
329
-E.g:
330
-
331
-```{r, eval = FALSE}
332
-ha = rowAnnotation(points = anno_points(runif(10), which = "row"))
333
-```
334
-
335
-Similar as `rowAnnotation()`, there are corresponding wrapper `anno_*` functions. There functions
336
-are almost same as the original functions except pre-defined `which` argument to `row`.
337
-
338
-- `row_anno_points()`
339
-- `row_anno_barplot()`
340
-- `row_anno_boxplot()`
341
-- `row_anno_histogram()`
342
-- `row_anno_density()`
343
-- `row_anno_text()`
344
-
345
-Similar, there can be more than one row annotations. 
346
-
347
-```{r, fig.width = 3, fig.height = 7}
348
-ha_combined = rowAnnotation(df = df, boxplot = row_anno_boxplot(mat), 
349
-    col = list(type = c("a" = "red", "b" = "blue")),
350
-    annotation_width = c(1, 3))
351
-draw(ha_combined, 1:12)
352
-```
353
-
354
-### Mix heatmaps and row annotations
355
-
356
-Essentially, row annotations and column annotations are identical graphics, but in practice,
357
-there is some difference. In **ComplexHeatmap** package, row annotations have the same place as the heatmap
358
-while column annotations are just like accessory components of heatmaps. The idea here is that row annotations
359
-can be corresponded to all the heatmaps in the list while column annotations can only be corresponded to its own heatmap. 
360
-For row annotations, similar
361
-as heatmaps, you can append the row annotations to heatmap or heatmap list or even row annotation object itself.
362
-The order of elements in row annotations will be adjusted by the clustering of heatmaps.
363
-
364
-```{r heatmap_list_with_row_annotation, fig.width = 9}
365
-ha = rowAnnotation(df = df, col = list(type = c("a" = "red", "b" = "blue")),
366
-    width = unit(1, "cm"))
367
-ht1 = Heatmap(mat, name = "ht1")
368
-ht2 = Heatmap(mat, name = "ht2")
369
-ht1 + ha + ht2
370
-```
371
-
372
-If `km` or `split` is set in the main heatmap, the row annotations are
373
-splitted as well.
374
-
375
-```{r heatmap_list_with_row_annotation_complex}
376
-ht1 = Heatmap(mat, name = "ht1", km = 2)
377
-ha = rowAnnotation(df = df, col = list(type = c("a" = "red", "b" = "blue")),
378
-    boxplot = row_anno_boxplot(mat, axis = TRUE), 
379
-    annotation_width = unit(c(1, 5), "cm"))
380
-ha + ht1
381
-```
382
-
383
-When row split is applied, graphical parameters for annotation function can be specified as with the same length
384
-as the number of row slices.
385
-
386
-```{r heatmap_list_with_row_annotation_graphical_parameter}
387
-ha = rowAnnotation(boxplot = row_anno_boxplot(mat, gp = gpar(fill = c("red", "blue"))), 
388
-    width = unit(2, "cm"))
389
-ha + ht1
390
-```
391
-
392
-Since only row clustering and row titles for the main heatmap are kept, they can be adjusted to the most left or right side
393
-of the plot by setting `row_hclust_side` and `row_sub_title_side`:
394
-
395
-```{r heatmap_list_hclust_title_side}
396
-draw(ha + ht1, row_dend_side = "left", row_sub_title_side = "right")
397
-```
398
-
399
-### Self define row annotations
400
-
401
-Self-defining row annotations is same as self-defining column annotations. The only
402
-difference is that x coordinate and y coordinate are switched. If row annotations
403
-are split by rows, the argument `index` will automatically be the index in the 'current' row slice.
404
-
405
-```{r}
406
-value = rowMeans(mat)
407
-row_anno = function(index) {
408
-    n = length(index)
409
-    pushViewport(viewport(xscale = range(value), yscale = c(0.5, n + 0.5)))
410
-    grid.rect()
411
-    # recall row order will be adjusted, here we specify `value[index]`
412
-    grid.points(value[index], seq_along(index), pch = 16, default.unit = "native")
413
-    upViewport()
414
-}
415
-ha = rowAnnotation(points = row_anno, width = unit(1, "cm"))
416
-ht1 + ha
417
-```
418
-
419
-For the self-defined annotation function, there can be a second argument `k` which gives the index of 'current' row slice.
420
-
421
-```{r}
422
-row_anno = function(index, k) {
423
-    n = length(index)
424
-    col = c("blue", "red")[k]
425
-    pushViewport(viewport(xscale = range(value), yscale = c(0.5, n + 0.5)))
426
-    grid.rect()
427
-    grid.points(value[index], seq_along(index), pch = 16, default.unit = "native", gp = gpar(col = col))
428
-    upViewport()
429
-}
430
-ha = rowAnnotation(points = row_anno, width = unit(1, "cm"))
431
-ht1 + ha
432
-```
433
-
434
-### Heatmap with zero row
435
-
436
-If you only want to visualize meta data of your matrix, you can set the matrix with zero row.
437
-In this case, only one heatmap is allowed.
438
-
439
-```{r zero_row_heatmap, fig.height = 2}
440
-ha = HeatmapAnnotation(df = data.frame(value = runif(10), type = rep(letters[1:2], 5)),
441
-    barplot = anno_barplot(runif(10)),
442
-    points = anno_points(runif(10)))
443
-zero_row_mat = matrix(nrow = 0, ncol = 10)
444
-colnames(zero_row_mat) = letters[1:10]
445
-Heatmap(zero_row_mat, top_annotation = ha, column_title = "only annotations")
446
-```
447
-
448
-This feature is very useful if you want to compare multiple metrics. Axes and labels in following plot
449
-are added by [heatmap decoration](s6.heatmap_decoration.html). Also notice how we adjust 
450
-paddings of the plotting regions to give enough space for hte axis labels. 
451
-
452
-```{r, fig.height = 5}
453
-ha = HeatmapAnnotation(df = data.frame(value = runif(10), type = rep(letters[1:2], 5)),
454
-    barplot = anno_barplot(runif(10), axis = TRUE),
455
-    points = anno_points(runif(10), axis = TRUE),
456
-    annotation_height = unit(c(0.5, 0.5, 4, 4), "cm"))
457
-zero_row_mat = matrix(nrow = 0, ncol = 10)
458
-colnames(zero_row_mat) = letters[1:10]
459
-ht = Heatmap(zero_row_mat, top_annotation = ha, column_title = "only annotations")
460
-draw(ht, padding = unit(c(2, 20, 2, 2), "mm"))
461
-decorate_annotation("value", {grid.text("value", unit(-2, "mm"), just = "right")})
462
-decorate_annotation("type", {grid.text("type", unit(-2, "mm"), just = "right")})
463
-decorate_annotation("barplot", {
464
-    grid.text("barplot", unit(-10, "mm"), just = "bottom", rot = 90)
465
-    grid.lines(c(0, 1), unit(c(0.2, 0.2), "native"), gp = gpar(lty = 2, col = "blue"))
466
-})
467
-decorate_annotation("points", {
468
-    grid.text("points", unit(-10, "mm"), just = "bottom", rot = 90)
469
-})
470
-```
471
-
472
-### Heatmap with zero column
473
-
474
-If no heatmap is needed to draw and users only want to arrange a list of row annotations, an empty
475
-matrix with no column can be added to the heatmap list. Within the zero-column matrix, you can either
476
-split row annotaitons:
477
-
478
-```{r all_row_annotations, fig.width = 4}
479
-ha_boxplot = rowAnnotation(boxplot = row_anno_boxplot(mat), width = unit(3, "cm"))
480
-ha = rowAnnotation(df = df, col = list(type = c("a" = "red", "b" = "blue")), width = unit(2, "cm"))
481
-text = paste0("row", seq_len(nrow(mat)))
482
-ha_text = rowAnnotation(text = row_anno_text(text), width = max_text_width(text))
483
-nr = nrow(mat)
484
-Heatmap(matrix(nrow = nr, ncol = 0), split = sample(c("A", "B"), nr, replace = TRUE)) + 
485
-    ha_boxplot + ha + ha_text
486
-```
487
-
488
-or add dendrograms to the row annotations:
489
-
490
-```{r no_heatmap_but_with_cluster, fig.width = 4}
491
-dend = hclust(dist(mat))
492
-Heatmap(matrix(nrow = nr, ncol = 0), cluster_rows = dend) + 
493
-    ha_boxplot + ha + ha_text
494
-```
495
-
496
-Remember it is not allowed to only concantenate row annotations because row annotations don't provide
497
-information of number of rows.
498
-
499
-### Use heatmap instead of simple row annotations
500
-
501
-Finally, if your row annotations are simple annotations, I recommand to use heatmap instead.
502
-Following two methods generate similar figures.
503
-
504
-```{r}
505
-df = data.frame(type = c(rep("a", 6), rep("b", 6)))
506
-Heatmap(mat) + rowAnnotation(df = df, col = list(type = c("a" = "red", "b" = "blue")), 
507
-    width = unit(1, "cm"))
508
-Heatmap(mat) + Heatmap(df, name = "type", col = c("a" = "red", "b" = "blue"), 
509
-    width = unit(1, "cm"))
510
-```
511
-
512
-## Axes for annotations
513
-
514
-Axes for complex annotations are important to show range and direction of the data. `anno_*` functions
515
-provide `axis` and `axis_side` arguments to control the axes.
516
-
517
-```{r}
518
-ha1 = HeatmapAnnotation(b1 = anno_boxplot(mat, axis = TRUE),
519
-    p1 = anno_points(colMeans(mat), axis = TRUE))
520
-ha2 = rowAnnotation(b2 = row_anno_boxplot(mat, axis = TRUE),
521
-    p2 = row_anno_points(rowMeans(mat), axis = TRUE), width = unit(2, "cm"))
522
-Heatmap(mat, top_annotation = ha1, top_annotation_height = unit(2, "cm")) + ha2
523
-```
524
-
525
-For row annotations, by default direction of the data is from left to right. But it may confuse people
526
-if the row annotation is placed on the left of the heatmap. You can change axis directions for row annotations
527
-by `axis_direction`. Compare following two plots:
528
-
529
-```{r, fig.width = 10}
530
-pushViewport(viewport(layout = grid.layout(nr = 1, nc = 2)))
531
-pushViewport(viewport(layout.pos.row = 1, layout.pos.col = 1))
532
-ha = rowAnnotation(boxplot = row_anno_boxplot(mat, axis = TRUE), width = unit(3, "cm"))
533
-ht_list = ha + Heatmap(mat)
534
-draw(ht_list, column_title = "normal axis direction", newpage = FALSE)
535
-upViewport()
536
-
537
-pushViewport(viewport(layout.pos.row = 1, layout.pos.col = 2))
538
-ha = rowAnnotation(boxplot = row_anno_boxplot(mat, axis = TRUE, axis_direction = "reverse"), 
539
-    width = unit(3, "cm"))
540
-ht_list = ha + Heatmap(mat)
541
-draw(ht_list, column_title = "reverse axis direction", newpage = FALSE)
542
-upViewport(2)
543
-```
544
-
545
-## Stacked barplots
546
-
547
-Barplot annotation can be stacked barplots if the input (let's say `x`) is a matrix with columns larger than one.
548
-In this case, if graphic parameters are specified as a vector, the length can only be one or
549
-the number of columns in `x`. Since barplots are stacked, each row can only have all positive values
550
-or all negative values.
551
-
552
-Note the drawback is there is no legend for the stacked barplots, you need to generate it manually (check [this section](s5.legend.html#toc_3))
553
-
554
-```{r}
555
-foo1 = matrix(abs(rnorm(20)), ncol = 2)
556
-foo1[1, ] = -foo1[1, ]
557
-column_ha = HeatmapAnnotation(foo1 = anno_barplot(foo1, axis = TRUE))
558
-foo2 = matrix(abs(rnorm(24)), ncol = 2)
559
-row_ha = rowAnnotation(foo2 = row_anno_barplot(foo2, axis = TRUE, axis_side = "top",
560
-    gp = gpar(fill = c("red", "blue"))), width = unit(2, "cm"))
561
-Heatmap(mat, top_annotation = column_ha, top_annotation_height = unit(2, "cm"), km = 2) + row_ha
562
-```
563
-
564
-## Add annotation names
565
-
566
-From version 1.11.5, `HeatmapAnnotation()` supports adding annotation names directly to the annotations.
567
-However, due to the design of the package, sometimes the names will be positioned outside of the plot
568
-or overlap to other heatmap compoments, thus, by default it is turned off.
569
-
570
-```{r}
571
-df = data.frame(type = c(rep("a", 5), rep("b", 5)),
572
-                age = sample(1:20, 10))
573
-value = rnorm(10)
574
-ha = HeatmapAnnotation(df = df, points = anno_points(value, axis = TRUE),
575
-    col = list(type = c("a" = "red", "b" = "blue"),
576
-               age = colorRamp2(c(0, 20), c("white", "red"))),
577
-    annotation_height = unit(c(0.5, 0.5, 2), "cm"),
578
-    show_annotation_name = TRUE,
579
-    annotation_name_offset = unit(2, "mm"),
580
-    annotation_name_rot = c(0, 0, 90))
581
-Heatmap(mat, name = "foo", top_annotation = ha)
582
-```
583
-
584
-Or the row annotation names: Note we manually adjust `padding` to fully show the text of "points".
585
-
586
-```{r}
587
-df = data.frame(type = c(rep("a", 6), rep("b", 6)),
588
-                age = sample(1:20, 12))
589
-value = rnorm(12)
590
-ha = rowAnnotation(df = df, points = row_anno_points(value, axis = TRUE),
591
-    col = list(type = c("a" = "red", "b" = "blue"),
592
-               age = colorRamp2(c(0, 20), c("white", "red"))),
593
-    annotation_width = unit(c(0.5, 0.5, 2), "cm"),
594
-    show_annotation_name = c(TRUE, FALSE, TRUE),
595
-    annotation_name_offset = unit(c(2, 2, 8), "mm"),
596
-    annotation_name_rot = c(90, 90, 0))
597
-ht = Heatmap(mat, name = "foo") + ha
598
-draw(ht, padding = unit(c(4, 2, 2, 2), "mm"))
599
-```
600
-
601
-## Adjust positions of column names
602
-
603
-In the layout of the heatmap components, column names are put directly below the heatmap body. This will cause
604
-problems when annotations are put at the bottom of the heatmap as well:
605
-
606
-```{r}
607
-ha = HeatmapAnnotation(type = df$type,
608
-    col = list(type = c("a" = "red", "b" = "blue")))
609
-Heatmap(mat, bottom_annotation = ha)
610
-```
611
-
612
-To solve this problem, we can replace column names with text annotations, which is, we suppress columns
613
-when making the heamtap and create a text annotation which is formed by column names.
614
-
615
-```{r}
616
-ha = HeatmapAnnotation(type = df$type, 
617
-    colname = anno_text(colnames(mat), rot = 90, just = "right", offset = unit(1, "npc") - unit(2, "mm")),
618
-    col = list(type = c("a" = "red", "b" = "blue")),
619
-    annotation_height = unit.c(unit(5, "mm"), max_text_width(colnames(mat)) + unit(2, "mm")))
620
-Heatmap(mat, show_column_names = FALSE, bottom_annotation = ha)
621
-```
622
-
623
-When add a text annotation, the maximum width of the text should be calculated and set as the height of the 
624
-text annotation viewport so that all text can be completely shown in the plot. Sometimes, you also need to 
625
-set `rot`, `just` and `offset` to align the text to the correct anchor positions.
626
-
627
-## Mark some of the rows/columns
628
-
629
-From version 1.8.0, a new annotation function `anno_link()` was added which connects labels and subset of the rows
630
-by links. It is helpful when there are many rows/columns and we want to mark some of the rows (e.g. in a gene expression
631
-matrix, we want to mark some important genes of interest.)
632
-
633
-```{r}
634
-mat = matrix(rnorm(10000), nr = 1000)
635
-rownames(mat) = sprintf("%.2f", rowMeans(mat))
636
-subset = sample(1000, 20)
637
-labels = rownames(mat)[subset]
638
-Heatmap(mat, show_row_names = FALSE, show_row_dend = FALSE, show_column_dend = FALSE) + 
639
-rowAnnotation(link = row_anno_link(at = subset, labels = labels),
640
-  width = unit(1, "cm") + max_text_width(labels))
641
-# here unit(1, "cm") is width of segments
642
-```
643
-
644
-There are also two shortcut functions: `row_anno_link()` and `column_anno_link()`.
645
-
646
-## Session info
647
-
648
-```{r}
649
-sessionInfo()
650
-```
Browse code

a backup push

Zuguang Gu authored on 18/09/2018 10:40:29
Showing 1 changed files
1 1
new file mode 100755
... ...
@@ -0,0 +1,652 @@
1
+<!--
2
+%\VignetteEngine{knitr}
3
+%\VignetteIndexEntry{4. Heatmap Annotations}
4
+-->
5
+
6
+Heatmap Annotations
7
+========================================
8
+
9
+**Author**: Zuguang Gu ( z.gu@dkfz.de )
10
+
11
+**Date**: `r Sys.Date()`
12
+
13
+-------------------------------------------------------------
14
+
15
+```{r global_settings, echo = FALSE, message = FALSE}
16
+library(markdown)
17
+options(markdown.HTML.options = c(options('markdown.HTML.options')[[1]], "toc"))
18
+
19
+library(knitr)
20
+knitr::opts_chunk$set(
21
+    error = FALSE,
22
+    tidy  = FALSE,
23
+    message = FALSE,
24
+    fig.align = "center",
25
+    fig.width = 5,
26
+    fig.height = 5)
27
+options(markdown.HTML.stylesheet = "custom.css")
28
+
29
+options(width = 100)
30
+```
31
+
32
+The annotation graphics actually are quite general. The only common characteristic for annotations
33
+is that they are aligned to the columns or rows of the heatmap. Here there is a `HeatmapAnnotation` class which is used to 
34
+define annotations on columns or rows.
35
+
36
+## Column annotation
37
+
38
+### Simple annotation
39
+
40
+A simple annotation is defined as a vector which contains discrete classes or continuous values.
41
+Since the simple annotation is represented as a vector, multiple simple annotations can be specified
42
+as a data frame. Colors for the simple annotations can be specified by `col` with a vector or
43
+color mapping functions, depending on whether the simple annotations are discrete or continuous.
44
+
45
+In the heatmap, simple annotations will be represented as rows of grids.
46
+
47
+There is a `draw()` method for the `HeatmapAnnotation` class. `draw()` is used internally and here
48
+we just use it for demonstration.
49
+
50
+```{r heatmap_annotation, fig.width = 7, fig.height = 0.5}
51
+library(ComplexHeatmap)
52
+library(circlize)
53
+
54
+df = data.frame(type = c(rep("a", 5), rep("b", 5)))
55
+ha = HeatmapAnnotation(df = df)
56
+ha
57
+draw(ha, 1:10)
58
+```
59
+
60
+The color of simple annotation should be specified as a list with names for which names in the color list (here it is `type` in following example)
61
+correspond to the names in the data frame. Each color vector should better has names as well to map to 
62
+the levels of annotations.
63
+
64
+```{r heatmap_annotation_col, fig.width = 7, fig.height = 0.5}
65
+ha = HeatmapAnnotation(df = df, col = list(type = c("a" =  "red", "b" = "blue")))
66
+ha
67
+draw(ha, 1:10)
68
+```
69
+
70
+For continuous annotation, colors should be a color mapping function.
71
+
72
+```{r heatmap_annotation_colfun, fig.width = 7, fig.height = 0.5}
73
+ha = HeatmapAnnotation(df = data.frame(age = sample(1:20, 10)),
74
+    col = list(age = colorRamp2(c(0, 20), c("white", "red"))))
75
+ha
76
+draw(ha, 1:10)
77
+```
78
+
79
+Color for `NA` can be set by `na_col`:
80
+
81
+```{r, fig.width = 7, fig.height = 1}
82
+df2 = data.frame(type = c(rep("a", 5), rep("b", 5)),
83
+                age = sample(1:20, 10))
84
+df2$type[5] = NA
85
+df2$age[5] = NA
86
+ha = HeatmapAnnotation(df = df2, 
87
+  col = list(type = c("a" =  "red", "b" = "blue"),
88
+             age = colorRamp2(c(0, 20), c("white", "red"))),
89
+  na_col = "grey")
90
+draw(ha, 1:10)
91
+```
92
+
93
+Put more than one annotations by a data frame.
94
+
95
+```{r heatmap_annotation_mixed, fig.width = 7, fig.height = 1}
96
+df = data.frame(type = c(rep("a", 5), rep("b", 5)),
97
+                age = sample(1:20, 10))
98
+ha = HeatmapAnnotation(df = df,
99
+    col = list(type = c("a" = "red", "b" = "blue"),
100
+               age = colorRamp2(c(0, 20), c("white", "red")))
101
+)
102
+ha
103
+draw(ha, 1:10)
104
+```
105
+
106
+Also individual annotations can be directly specified as vectors:
107
+
108
+```{r heatmap_annotation_vector, fig.width = 7, fig.height = 1}
109
+ha = HeatmapAnnotation(type = c(rep("a", 5), rep("b", 5)),
110
+                       age = sample(1:20, 10),
111
+    col = list(type = c("a" = "red", "b" = "blue"),
112
+               age = colorRamp2(c(0, 20), c("white", "red")))
113
+)
114
+ha
115
+draw(ha, 1:10)
116
+```
117
+
118
+To put column annotation to the heatmap, specify `top_annotation` and `bottom_annotation` in `Heatmap()`.
119
+
120
+```{r heatmap_column_annotation}
121
+ha1 = HeatmapAnnotation(df = df,
122
+    col = list(type = c("a" = "red", "b" = "blue"),
123
+               age = colorRamp2(c(0, 20), c("white", "red")))
124
+)
125
+ha2 = HeatmapAnnotation(df = data.frame(age = sample(1:20, 10)),
126
+    col = list(age = colorRamp2(c(0, 20), c("white", "red"))))
127
+
128
+set.seed(123)
129
+mat = matrix(rnorm(80, 2), 8, 10)
130
+mat = rbind(mat, matrix(rnorm(40, -2), 4, 10))
131
+rownames(mat) = paste0("R", 1:12)
132
+colnames(mat) = paste0("C", 1:10)
133
+
134
+Heatmap(mat, top_annotation = ha1, bottom_annotation = ha2)
135
+```
136
+
137
+### Complex annotations
138
+
139
+Besides simple annotations, there are complex annotations. The complex annotations are always
140
+represented as self-defined graphic functions. Actually, for each column annotation, there will be a viewport
141
+created waiting for graphics. The annotation function here defines how to put the graphics to
142
+this viewport. The only argument of the function is an index of column which is already adjusted by column clustering.
143
+
144
+In following example, an annotation of points is created. Please note how we define `xscale` so that positions
145
+of points correspond to middle points of the columns if the annotation is added to the heatmap.
146
+
147
+```{r heatmap_annotation_complex, fig.width = 7, fig.height = 1}
148
+value = rnorm(10)
149
+column_anno = function(index) {
150
+    n = length(index)
151
+    # since middle of columns are in 1, 2, ..., n and each column has width 1
152
+    # then the most left should be 1 - 0.5 and the most right should be n + 0.5
153
+    pushViewport(viewport(xscale = c(0.5, n + 0.5), yscale = range(value)))
154
+    # since order of columns will be adjusted by clustering, here we also 
155
+    # need to change the order by `[index]`
156
+    grid.points(index, value[index], pch = 16, default.unit = "native")
157
+    # this is very important in order not to mess up the layout
158
+    upViewport() 
159
+}
160
+ha = HeatmapAnnotation(points = column_anno)  # here the name is arbitrary
161
+ha
162
+draw(ha, 1:10)
163
+```
164
+
165
+Above code is only for demonstration. You don't realy need to define a points annotation,
166
+there are already several annotation generators provided in the package such as `anno_points()` or `anno_barplot()`
167
+which generate such complex annotation function:
168
+
169
+- `anno_points()`
170
+- `anno_barplot()`
171
+- `anno_boxplot()`
172
+- `anno_histogram()`
173
+- `anno_density()`
174
+- `anno_text()`
175
+
176
+The input value for these `anno_*` functions is quite straightforward. It should be a numeric vector 
177
+(e.g. for `anno_points()` and `anno_barplot()`), a matrix or list (for `anno_boxplot()`, `anno_histogram()` 
178
+or `anno_density()`), or a character vector (for `anno_text()`).
179
+
180
+```{r heatmap_annotation_points, fig.width = 7, fig.height = 1}
181
+ha = HeatmapAnnotation(points = anno_points(value))
182
+draw(ha, 1:10)
183
+```
184
+
185
+```{r heatmap_annotation_barplot, fig.width = 7, fig.height = 1}
186
+ha = HeatmapAnnotation(barplot = anno_barplot(value))
187
+draw(ha, 1:10)
188
+```
189
+
190
+`anno_boxplot()` generates boxplot for each column in the matrix.
191
+
192
+```{r heatmap_annotation_boxplot, fig.width = 7, fig.height = 1}
193
+ha = HeatmapAnnotation(boxplot = anno_boxplot(mat))
194
+draw(ha, 1:10)
195
+```
196
+
197
+You can mix simple annotations and complex annotations:
198
+
199
+```{r heatmap_annotation_mixed_with_complex, fig.width = 7, fig.height = 2}
200
+ha = HeatmapAnnotation(df = df, 
201
+                       points = anno_points(value),
202
+    col = list(type = c("a" = "red", "b" = "blue"),
203
+               age = colorRamp2(c(0, 20), c("white", "red"))))
204
+ha
205
+draw(ha, 1:10)
206
+```
207
+
208
+Since simple annotations can also be specified as vectors, actually you arrange annotations in any order:
209
+
210
+```{r, fig.width = 7, fig.height = 2}
211
+ha = HeatmapAnnotation(type = c(rep("a", 5), rep("b", 5)),
212
+                       points = anno_points(value),
213
+                       age = sample(1:20, 10), 
214
+                       bars = anno_barplot(value),
215
+    col = list(type = c("a" = "red", "b" = "blue"),
216
+               age = colorRamp2(c(0, 20), c("white", "red"))))
217
+ha
218
+draw(ha, 1:10)
219
+```
220
+
221
+For some of the `anno_*` functions, graphic parameters can be set by `gp` argument.
222
+Also note how we specify `baseline` in `anno_barplot()`.
223
+
224
+```{r heatmap_annotation_anno_gp, fig.width = 7, fig.height = 3}
225
+ha = HeatmapAnnotation(barplot1 = anno_barplot(value, baseline = 0, gp = gpar(fill = ifelse(value > 0, "red", "green"))),
226
+                       points = anno_points(value, gp = gpar(col = rep(1:2, 5))),
227
+                       barplot2 = anno_barplot(value, gp = gpar(fill = rep(3:4, 5))))
228
+ha
229
+draw(ha, 1:10)
230
+```
231
+
232
+If there are more than one annotations, you can control height of each annotation by `annotation_height`.
233
+The value of `annotation_height` can either be numeric values or `unit` objects.
234
+
235
+```{r, fig.width = 7, fig.height = 3}
236
+# set annotation height as relative values
237
+ha = HeatmapAnnotation(df = df, points = anno_points(value), boxplot = anno_boxplot(mat),
238
+    col = list(type = c("a" = "red", "b" = "blue"),