Browse code

oncoPrint is vectorized

Zuguang Gu authored on 25/09/2018 07:59:43
Showing12 changed files

... ...
@@ -118,6 +118,7 @@ export("anno_simple")
118 118
 export("anno_text")
119 119
 export("cluster_within_group")
120 120
 export("columnAnnotation")
121
+export("convertXY_in_vp")
121 122
 export("decorate_annotation")
122 123
 export("decorate_column_dend")
123 124
 export("decorate_column_names")
... ...
@@ -145,6 +146,7 @@ export("max_text_height")
145 146
 export("max_text_width")
146 147
 export("oncoPrint")
147 148
 export("packLegend")
149
+export("pindex")
148 150
 export("rowAnnotation")
149 151
 export("row_anno_barplot")
150 152
 export("row_anno_boxplot")
... ...
@@ -1,3 +1,12 @@
1
+CHANGES in VERSION 1.99.0
2
+
3
+This a major update of the package. The main changes are:
4
+* support column split
5
+* support align heatmaps vertically
6
+* add a naive `AnnotationFunction` class to handle annotation functions
7
+
8
+=======================
9
+
1 10
 CHANGES in VERSION 1.19.1
2 11
 
3 12
 * `Heatmap()`: no column name added if the input matrix is a one-column matrix.
... ...
@@ -88,7 +88,10 @@ setMethod(f = "draw_heatmap_body",
88 88
         do.call(device_fun, c(list(filename = temp_image, width = max(c(heatmap_width*raster_quality, 1)), height = max(c(heatmap_height*raster_quality, 1))), raster_device_param))
89 89
         grid.rect(x[expand_index[[2]]], y[expand_index[[1]]], width = unit(1/nc, 'npc'), height = unit(1/nr, 'npc'), gp = do.call('gpar', c(list(fill = col_matrix), gp)))
90 90
         if(is.function(layer_fun)) {
91
-            layer_fun(row_order, column_order)
91
+            layer_fun(column_order[ expand_index[[2]] ], row_order[ expand_index[[1]] ], 
92
+                x[expand_index[[2]]], y[expand_index[[1]]],
93
+                unit(rep(1/nc, nrow(expand_index)), "npc"), unit(rep(1/nr, nrow(expand_index)), "npc"),
94
+                as.vector(col_matrix))
92 95
         }
93 96
         dev.off2()
94 97
         
... ...
@@ -149,12 +152,20 @@ setMethod(f = "draw_heatmap_body",
149 152
         }
150 153
 
151 154
         if(is.function(cell_fun)) {
152
-            for(i in row_order) {
153
-                for(j in column_order) {
154
-                    cell_fun(j, i, unit(x[which(column_order == j)], "npc"), unit(y[which(row_order == i)], "npc"), unit(1/nc, "npc"), unit(1/nr, "npc"), col_matrix[which(row_order == i), which(column_order == j)])
155
+            for(i in seq_len(nr)) {
156
+                for(j in seq_len(nc)) {
157
+                    cell_fun(column_order[j], row_order[i], unit(x[j], "npc"), unit(y[i], "npc"), 
158
+                        unit(1/nc, "npc"), unit(1/nr, "npc"), 
159
+                        col_matrix[i, j])
155 160
                 }
156 161
             }
157 162
         }
163
+        if(is.function(layer_fun)) {
164
+            layer_fun(column_order[ expand_index[[2]] ], row_order[ expand_index[[1]] ], 
165
+                x[expand_index[[2]]], y[expand_index[[1]]],
166
+                unit(rep(1/nc, nrow(expand_index)), "npc"), unit(rep(1/nr, nrow(expand_index)), "npc"),
167
+                as.vector(col_matrix))
168
+        }
158 169
     }
159 170
 
160 171
     if(!identical(border, FALSE)) {
... ...
@@ -225,6 +225,7 @@ setMethod(f = "add_heatmap",
225 225
 # -ht_gap = gap, 
226 226
 # -main_heatmap = which(sapply(object@ht_list, inherits, "Heatmap"))[1],
227 227
 # -padding = NULL,
228
+# -adjust_annotation_name adjust_annotation_name
228 229
 # -row_dend_side = c("original", "left", "right"),
229 230
 # -row_sub_title_side = c("original", "left", "right"),
230 231
 # -column_dend_side = c("original", "top", "bottom"),
... ...
@@ -308,6 +309,7 @@ setMethod(f = "draw",
308 309
 
309 310
     main_heatmap = which(sapply(object@ht_list, inherits, "Heatmap"))[1],
310 311
     padding = NULL,
312
+    adjust_annotation_name = FALSE,
311 313
 
312 314
     row_dend_side = c("original", "left", "right"),
313 315
     row_sub_title_side = c("original", "left", "right"),
... ...
@@ -389,6 +391,8 @@ setMethod(f = "draw",
389 391
     object@heatmap_legend_param$offset = heatmap_legend_offset
390 392
     object@annotation_legend_param$offset = annotation_legend_offset
391 393
 
394
+    object@ht_list_param$adjust_annotation_name = adjust_annotation_name
395
+
392 396
     object = make_layout(
393 397
         object, 
394 398
         row_title = row_title, 
... ...
@@ -474,34 +478,34 @@ setMethod(f = "draw",
474 478
     # calculate proper padding
475 479
     if(is.null(padding)) {
476 480
         padding = GLOBAL_PADDING
477
-        if(!has_heatmap_list_component(object, "heatmap_legend_bottom") && 
478
-           !has_heatmap_list_component(object, "annotation_legend_bottom") &&
479
-           !has_heatmap_list_component(object, "column_title_bottom")) {
480
-            if(object@layout$row_anno_max_bottom_extended[[1]] > object@layout$max_bottom_component_height[[1]]) {
481
-                padding[1] = object@layout$row_anno_max_bottom_extended - object@layout$max_bottom_component_height + GLOBAL_PADDING[1]
482
-            }
483
-        }
484
-        if(!has_heatmap_list_component(object, "heatmap_legend_left") && 
485
-           !has_heatmap_list_component(object, "annotation_legend_left") &&
486
-           !has_heatmap_list_component(object, "row_title_left")) {
487
-            if(object@layout$column_anno_max_left_extended[[1]] > object@layout$max_left_component_width[[1]]) {
488
-                padding[2] = object@layout$column_anno_max_left_extended - object@layout$max_left_component_width + GLOBAL_PADDING[2]
489
-            }
490
-        }
491
-        if(!has_heatmap_list_component(object, "heatmap_legend_top") && 
492
-           !has_heatmap_list_component(object, "annotation_legend_top") &&
493
-           !has_heatmap_list_component(object, "column_title_top")) {
494
-            if(object@layout$row_anno_max_top_extended[[1]] > object@layout$max_top_component_height[[1]]) {
495
-                padding[3] = object@layout$row_anno_max_top_extended - object@layout$max_top_component_height + GLOBAL_PADDING[3]
496
-            }
497
-        }
498
-        if(!has_heatmap_list_component(object, "heatmap_legend_right") && 
499
-           !has_heatmap_list_component(object, "annotation_legend_right") &&
500
-           !has_heatmap_list_component(object, "row_title_right")) {
501
-            if(object@layout$column_anno_max_right_extended[[1]] > object@layout$max_right_component_width[[1]]) {
502
-                padding[4] = object@layout$column_anno_max_right_extended - object@layout$max_right_component_width + GLOBAL_PADDING[4]
503
-            }
504
-        }
481
+        # if(!has_heatmap_list_component(object, "heatmap_legend_bottom") && 
482
+        #    !has_heatmap_list_component(object, "annotation_legend_bottom") &&
483
+        #    !has_heatmap_list_component(object, "column_title_bottom")) {
484
+        #     if(object@layout$row_anno_max_bottom_extended[[1]] > object@layout$max_bottom_component_height[[1]]) {
485
+        #         padding[1] = object@layout$row_anno_max_bottom_extended - object@layout$max_bottom_component_height + GLOBAL_PADDING[1]
486
+        #     }
487
+        # }
488
+        # if(!has_heatmap_list_component(object, "heatmap_legend_left") && 
489
+        #    !has_heatmap_list_component(object, "annotation_legend_left") &&
490
+        #    !has_heatmap_list_component(object, "row_title_left")) {
491
+        #     if(object@layout$column_anno_max_left_extended[[1]] > object@layout$max_left_component_width[[1]]) {
492
+        #         padding[2] = object@layout$column_anno_max_left_extended - object@layout$max_left_component_width + GLOBAL_PADDING[2]
493
+        #     }
494
+        # }
495
+        # if(!has_heatmap_list_component(object, "heatmap_legend_top") && 
496
+        #    !has_heatmap_list_component(object, "annotation_legend_top") &&
497
+        #    !has_heatmap_list_component(object, "column_title_top")) {
498
+        #     if(object@layout$row_anno_max_top_extended[[1]] > object@layout$max_top_component_height[[1]]) {
499
+        #         padding[3] = object@layout$row_anno_max_top_extended - object@layout$max_top_component_height + GLOBAL_PADDING[3]
500
+        #     }
501
+        # }
502
+        # if(!has_heatmap_list_component(object, "heatmap_legend_right") && 
503
+        #    !has_heatmap_list_component(object, "annotation_legend_right") &&
504
+        #    !has_heatmap_list_component(object, "row_title_right")) {
505
+        #     if(object@layout$column_anno_max_right_extended[[1]] > object@layout$max_right_component_width[[1]]) {
506
+        #         padding[4] = object@layout$column_anno_max_right_extended - object@layout$max_right_component_width + GLOBAL_PADDING[4]
507
+        #     }
508
+        # }
505 509
         object@ht_list_param$padding = padding
506 510
     }
507 511
 
... ...
@@ -453,19 +453,28 @@ setMethod(f = "draw_heatmap_list",
453 453
 
454 454
     n = length(object@ht_list)
455 455
     ht_gap = object@ht_list_param$ht_gap
456
+    adjust_annotation_name = object@ht_list_param$adjust_annotation_name
456 457
 
457
-#     padding = unit(c(0, 0, 0, 0), "mm")
458
+    padding = unit(c(0, 0, 0, 0), "mm")
458 459
 
459
-#     if((has_heatmap_list_component(object, "heatmap_legend_right") || 
460
-#        has_heatmap_list_component(object, "annotation_legend_right")) &&
461
-#        !has_heatmap_list_component(object, "row_title_right")) {
462
-#         if(object@layout$column_anno_max_right_extended[[1]] > object@layout$max_right_component_width[[1]]) {
463
-#             padding[4] = object@layout$column_anno_max_right_extended - object@layout$max_right_component_width + GLOBAL_PADDING[4]
464
-#         }
465
-#     }
466
-# browser()
467
-#     pushViewport(viewport(x = padding[2], y = padding[1], width = unit(1, "npc") - padding[2] - padding[4],
468
-#         height = unit(1, "npc") - padding[1] - padding[3], just = c("left", "bottom")))
460
+    if(adjust_annotation_name) {
461
+        if(object@layout$row_anno_max_bottom_extended[[1]] > object@layout$max_bottom_component_height[[1]]) {
462
+            padding[1] = object@layout$row_anno_max_bottom_extended - object@layout$max_bottom_component_height
463
+        }
464
+        if(object@layout$column_anno_max_left_extended[[1]] > object@layout$max_left_component_width[[1]]) {
465
+            padding[2] = object@layout$column_anno_max_left_extended - object@layout$max_left_component_width + GLOBAL_PADDING[2]
466
+        }
467
+            
468
+        if(object@layout$row_anno_max_top_extended[[1]] > object@layout$max_top_component_height[[1]]) {
469
+            padding[3] = object@layout$row_anno_max_top_extended - object@layout$max_top_component_height + GLOBAL_PADDING[3]
470
+        }
471
+        if(object@layout$column_anno_max_right_extended[[1]] > object@layout$max_right_component_width[[1]]) {
472
+            padding[4] = object@layout$column_anno_max_right_extended - object@layout$max_right_component_width + GLOBAL_PADDING[4]
473
+        }
474
+    }
475
+
476
+    pushViewport(viewport(x = padding[2], y = padding[1], width = unit(1, "npc") - padding[2] - padding[4],
477
+        height = unit(1, "npc") - padding[1] - padding[3], just = c("left", "bottom")))
469 478
 
470 479
     if(object@direction == "horizontal") {
471 480
 
... ...
@@ -579,7 +588,7 @@ setMethod(f = "draw_heatmap_list",
579 588
 
580 589
         upViewport()
581 590
     }
582
-    # upViewport()
591
+    upViewport()
583 592
 
584 593
 })
585 594
 
... ...
@@ -109,7 +109,7 @@ ht_opt = setGlobalOptions(
109 109
 			}
110 110
 		},
111 111
 		.length = 1),
112
-	show_vp_border = FALSE,
112
+	show_vp_border = TRUE,
113 113
 	anno_simple_row_size = unit(5, "mm")
114 114
 )
115 115
 
... ...
@@ -10,6 +10,7 @@
10 10
 #           determines how to extract them. Only work when ``mat`` is a matrix.
11 11
 # -alter_fun a single function or a list of functions which define how to add graphics for different alterations.
12 12
 #                 If it is a list, the names of the list should cover all alteration types.
13
+# -alter_fun_is_vectorized
13 14
 # -col a vector of color for which names correspond to alteration types.
14 15
 # -top_annotation
15 16
 # -right_annotation
... ...
@@ -46,6 +47,7 @@
46 47
 oncoPrint = function(mat, 
47 48
 	get_type = function(x) x,
48 49
 	alter_fun, 
50
+	alter_fun_is_vectorized = NULL,
49 51
 	col, 
50 52
 
51 53
 	top_annotation = HeatmapAnnotation(column_barplot = anno_oncoprint_barplot(),
... ...
@@ -114,89 +116,135 @@ oncoPrint = function(mat,
114 116
 
115 117
 	cat("All mutation types:", paste(all_type, collapse = ", "), "\n")
116 118
 
117
-	if(missing(alter_fun) && missing(col)) {
118
-		if(length(mat_list) == 1) {
119
-			af = function(x, y, w, h, v, j, i) {
120
-				grid.rect(x, y, w, h, gp = gpar(fill = "#CCCCCC", col = NA))
121
-				if(v[1]) grid.rect(x, y, w*0.9, h*0.9, gp = gpar(fill = "red", col = NA))
119
+
120
+	# type as the third dimension
121
+	arr = array(FALSE, dim = c(dim(mat_list[[1]]), length(all_type)), dimnames = c(dimnames(mat_list[[1]]), list(all_type)))
122
+	for(i in seq_along(all_type)) {
123
+		arr[, , i] = mat_list[[i]]
124
+	}
125
+
126
+	oncoprint_row_order = function() {
127
+		order(rowSums(count_matrix), n_mut, decreasing = TRUE)
128
+	}
129
+
130
+	oncoprint_column_order = function() {
131
+		scoreCol = function(x) {
132
+			score = 0
133
+			for(i in 1:length(x)) {
134
+				if(x[i]) {
135
+					score = score + 2^(length(x)-i*1/x[i])
136
+				}
122 137
 			}
138
+			return(score)
139
+		}
140
+		scores = apply(count_matrix[row_order, ,drop = FALSE], 2, scoreCol)
141
+		order(scores, decreasing=TRUE)
142
+	}
143
+
144
+	if(missing(alter_fun)) {
145
+		if(length(mat_list) == 1) {
146
+			af = list(
147
+				background = function(x, y, w, h, j, i) {
148
+					grid.rect(x, y, w, h, gp = gpar(fill = "#CCCCCC", col = NA))
149
+				},
150
+				function(x, y, w, h, j, i) {
151
+					grid.rect(x, y, w*0.9, h*0.9, gp = gpar(fill = "red", col = NA))
152
+				}
153
+			)
154
+			alter_fun_is_vectorized = TRUE
155
+			names(af) = c("background", names(mat_list))
123 156
 			col = "red"
124 157
 		} else if(length(mat_list) == 2) {
125
-			af = function(x, y, w, h, v, j, i) {
126
-				grid.rect(x, y, w, h, gp = gpar(fill = "#CCCCCC", col = NA))
127
-				if(v[1]) grid.rect(x, y, w*0.9, h*0.9, gp = gpar(fill = "red", col = NA))
128
-		        if(v[2]) grid.rect(x, y, w*0.9, h*0.4, gp = gpar(fill = "blue", col = NA))
129
-		    }
130
-		    col = c("red", "blue")
158
+			af = list(
159
+				background = function(x, y, w, h, j, i) {
160
+					grid.rect(x, y, w, h, gp = gpar(fill = "#CCCCCC", col = NA))
161
+				},
162
+				function(x, y, w, h, j, i) {
163
+					grid.rect(x, y, w*0.9, h*0.9, gp = gpar(fill = "red", col = NA))
164
+				},
165
+				function(x, y, w, h, j, i) {
166
+					grid.rect(x, y, w*0.9, h*0.4, gp = gpar(fill = "blue", col = NA))
167
+				}
168
+			)
169
+			alter_fun_is_vectorized = TRUE
170
+			names(af) = c("background", names(mat_list))
171
+			col = c("red", "blue")
131 172
 		} else {
132 173
 			stop("`alter_fun` should be specified.")
133 174
 		}
134 175
 		names(col) = names(mat_list)
135
-	} else if(is.list(alter_fun)) {
176
+		warning("Using default `alter_fun` graphics and reset `col`.")
177
+	}
178
+
179
+	if(is.list(alter_fun)) {
136 180
 
137 181
 		# validate the list first
138 182
 		if(is.null(alter_fun$background)) alter_fun$background = function(x, y, w, h) grid.rect(x, y, w, h, gp = gpar(fill = "#CCCCCC", col = NA))
139 183
 		sdf = setdiff(all_type, names(alter_fun))
140 184
 		if(length(sdf) > 0) {
141
-			stop(paste0("You should define shape function for: ", paste(sdf, collapse = ", ")))
185
+			stop(paste0("You should define graphic function for: ", paste(sdf, collapse = ", ")))
142 186
 		}
143 187
 
144 188
 		alter_fun = alter_fun[unique(c("background", intersect(names(alter_fun), all_type)))]
145 189
 
146
-		af = function(x, y, w, h, v, j, i) {
147
-			if(!is.null(alter_fun$background)) alter_fun$background(x, y, w, h)
148
-
149
-			alter_fun = alter_fun[names(alter_fun) != "background"]
190
+		if(is.null(alter_fun_is_vectorized)) {
191
+			alter_fun_is_vectorized = guess_alter_fun_is_vectorized(alter_fun)
192
+		}
150 193
 
151
-			if(sum(v)) {
152
-				for(nm in names(alter_fun)) {
153
-					if(v[nm]) {
154
-						if(length(formals(alter_fun[[nm]])) == 6) {
155
-							alter_fun[[nm]](x, y, w, h, j, i)
156
-						} else {
157
-							alter_fun[[nm]](x, y, w, h)
158
-						}
194
+		if(alter_fun_is_vectorized) {
195
+			layer_fun = function(j, i, x, y, w, h, fill) {
196
+				alter_fun$background(x, y, w, h)
197
+				for(nm in all_type) {
198
+					m = arr[, , nm]
199
+					l = pindex(m, i, j)
200
+					if(sum(l)) {
201
+						alter_fun[[nm]](x[l], y[l], w[l], h[l])
202
+					}
203
+				}
204
+			}
205
+			cell_fun = NULL
206
+		} else {
207
+			layer_fun = NULL
208
+			cell_fun = function(j, i, x, y, w, h, fill) {
209
+				alter_fun$background(x, y, w, h)
210
+				for(nm in all_type) {
211
+					if(arr[i, j, nm]) {
212
+						alter_fun[[nm]](x, y, w, h)
159 213
 					}
160 214
 				}
161 215
 			}
162 216
 		}
163
-	} else {
164
-		if(length(formals(alter_fun)) == 7) {
165
-			af = function(x, y, w, h, v, j, i) {
166
-				alter_fun(x, y, w, h, v, j, i)
217
+	} else if(is.function(alter_fun)) {
218
+		
219
+		if(length(formals(alter_fun)) == 5) {
220
+			af = function(x, y, w, h, v, j, i) alter_fun(x, y, w, h, v)
221
+		} else {
222
+			af = alter_fun
223
+		}
224
+
225
+		if(is.null(alter_fun_is_vectorized)) {
226
+			alter_fun_is_vectorized = FALSE
227
+		}
228
+
229
+		if(alter_fun_is_vectorized) {
230
+			layer_fun = function(j, i, x, y, w, h, fill) {
231
+				v = pindex(arr, i, j)
232
+				af(x, y, w, h, v, j, i)
167 233
 			}
234
+			cell_fun = NULL
168 235
 		} else {
169
-			af = function(x, y, w, h, v, j, i) {
170
-				alter_fun(x, y, w, h, v)
236
+			layer_fun = NULL
237
+			cell_fun = function(j, i, x, y, w, h, fill) {
238
+				v = arr[i, j, ]
239
+				af(x, y, w, h, v, j, i)
171 240
 			}
172 241
 		}
242
+	} else {
243
+		stop("You need to set `alter_fun`.")
173 244
 	}
174 245
 
175 246
 	col = col[intersect(names(col), all_type)]
176 247
 
177
-	# type as the third dimension
178
-	arr = array(FALSE, dim = c(dim(mat_list[[1]]), length(all_type)), dimnames = c(dimnames(mat_list[[1]]), list(all_type)))
179
-	for(i in seq_along(all_type)) {
180
-		arr[, , i] = mat_list[[i]]
181
-	}
182
-
183
-	oncoprint_row_order = function() {
184
-		order(rowSums(count_matrix), n_mut, decreasing = TRUE)
185
-	}
186
-
187
-	oncoprint_column_order = function() {
188
-		scoreCol = function(x) {
189
-			score = 0
190
-			for(i in 1:length(x)) {
191
-				if(x[i]) {
192
-					score = score + 2^(length(x)-i*1/x[i])
193
-				}
194
-			}
195
-			return(score)
196
-		}
197
-		scores = apply(count_matrix[row_order, ,drop = FALSE], 2, scoreCol)
198
-		order(scores, decreasing=TRUE)
199
-	}
200 248
 
201 249
 	count_matrix = apply(arr, c(1, 2), sum)
202 250
 	n_mut = rowSums(apply(arr, 1:2, any))
... ...
@@ -268,11 +316,7 @@ oncoPrint = function(mat,
268 316
 		rect_gp = gpar(type = "none"), 
269 317
 		cluster_rows = FALSE, cluster_columns = FALSE, 
270 318
 		row_order = row_order, column_order = column_order,
271
-		cell_fun = function(j, i, x, y, width, height, fill) {
272
-			z = arr[i, j, ]
273
-			names(z) = dimnames(arr)[[3]]
274
-			af(x, y, width, height, z, j, i)
275
-		},
319
+		cell_fun = cell_fun, layer_fun = layer_fun,
276 320
 		top_annotation = top_annotation,
277 321
 		left_annotation = left_annotation,
278 322
 		right_annotation = right_annotation,
... ...
@@ -364,4 +408,27 @@ anno_oncoprint_barplot = function(type = all_type, which = c("column", "row"),
364 408
 	}
365 409
 }
366 410
 
411
+guess_alter_fun_is_vectorized = function(alter_fun) {
412
+	n = 50
413
+	if(is.list(alter_fun)) {
414
+		x = 1:n
415
+		y = 1:n
416
+		w = unit(1:n, "mm")
417
+		h = unit(1:n, "mm")
418
+		dev.null()
419
+		oe = try({
420
+			for(i in seq_along(alter_fun)) {
421
+				alter_fun[[i]](x, y, w, h)
422
+			}
423
+		}, silent = TRUE)
424
+		dev.off2()
425
+		if(inherits(oe, "try-error")) {
426
+			return(FALSE)
427
+		} else {
428
+			return(TRUE)
429
+		}
430
+	} else {
431
+		return(FALSE)
432
+	}
433
+}
367 434
 
... ...
@@ -502,3 +502,85 @@ recycle_param = function(x, all_names, default) {
502 502
         return(x)
503 503
     }
504 504
 }
505
+
506
+# == title
507
+# Convert XY in a parent viewport
508
+#
509
+# == param
510
+# -u a list of two units which is x and y
511
+# -vp_name the name of the parent viewport
512
+#
513
+# == example
514
+# grid.newpage()
515
+# pushViewport(viewport(x = 0.5, y = 0.5, width = 0.5, height = 0.5, just = c("left", "bottom")))
516
+# u = list(x = unit(2, "cm"), y = unit(2, "cm"))
517
+# convertXY_in_vp(u)
518
+convertXY_in_vp = function(u, vp_name = "ROOT") {
519
+    vp = current.viewport()
520
+    current_vp_name = vp$name
521
+    original_vp_name = current_vp_name
522
+    while(current_vp_name != vp_name) {
523
+
524
+        if(current_vp_name == "ROOT") {
525
+            return(u)
526
+        }
527
+
528
+        u$x = convertX(u$x, "mm")
529
+        u$y = convertX(u$y, "mm")
530
+        current_vp_x = convertX(vp$x - vp$width*vp$valid.just[1], "mm")
531
+        current_vp_y = convertY(vp$y - vp$height*vp$valid.just[2], "mm")
532
+
533
+        upViewport(1)
534
+        offset_x = convertX(current_vp_x, "mm")
535
+        offset_y = convertY(current_vp_y, "mm")
536
+        u$x = u$x + offset_x
537
+        u$y = u$y + offset_y
538
+
539
+        vp = current.viewport()
540
+        current_vp_name = vp$name
541
+    }
542
+    seekViewport(original_vp_name)
543
+
544
+    return(u)
545
+}
546
+
547
+# == title
548
+# Get values in a matrix by pair-wise indices
549
+#
550
+# == param
551
+# -m a matrix or a 3d array
552
+# -i row indices
553
+# -j column indicies
554
+#
555
+# == example
556
+# m = matrix(rnorm(100), 10)
557
+# m2 = m[m > 0]
558
+# ind = do.call("rbind", lapply(1:10, function(ci) {
559
+#     i = which(m[, ci] > 0)
560
+#     cbind(i = i, j = rep(ci, length(i)))
561
+# }))
562
+# pindex(m, ind[, 1], ind[, 2])
563
+# identical(pindex(m, ind[, 1], ind[, 2]), m[m > 0])
564
+#
565
+# # 3d array
566
+# arr = array(1:27, dim = c(3, 3, 3))
567
+# pindex(arr, 1:2, 2:3)
568
+# identical(pindex(arr, 1:2, 2:3),
569
+#    rbind(arr[1, 2, ], arr[2, 3, ]))
570
+pindex = function(m, i, j) {
571
+    nr = nrow(m)
572
+    nc = ncol(m)
573
+    ind = (j-1)*nr + i
574
+    dm = dim(m)
575
+    if(length(dm) == 2) {
576
+        v = as.vector(m)
577
+        v[ind]
578
+    } else if(length(dm) == 3) {
579
+        v = m
580
+        dim(v) = c(dm[1]*dm[2], dm[3])
581
+        v[ind, , drop = FALSE]
582
+    } else {
583
+        stop("dimension of `m` can only be 2 and 3.")
584
+    }
585
+}
586
+
505 587
new file mode 100644
... ...
@@ -0,0 +1,23 @@
1
+\name{convertXY_in_vp}
2
+\alias{convertXY_in_vp}
3
+\title{
4
+Convert XY in a parent viewport
5
+}
6
+\description{
7
+Convert XY in a parent viewport
8
+}
9
+\usage{
10
+convertXY_in_vp(u, vp_name = "ROOT")
11
+}
12
+\arguments{
13
+
14
+  \item{u}{a list of two units which is x and y}
15
+  \item{vp_name}{the name of the parent viewport}
16
+
17
+}
18
+\examples{
19
+grid.newpage()
20
+pushViewport(viewport(x = 0.5, y = 0.5, width = 0.5, height = 0.5, just = c("left", "bottom")))
21
+u = list(x = unit(2, "cm"), y = unit(2, "cm"))
22
+convertXY_in_vp(u)
23
+}
... ...
@@ -32,6 +32,7 @@ Draw a list of heatmaps
32 32
     
33 33
     main_heatmap = which(sapply(object@ht_list, inherits, "Heatmap"))[1],
34 34
     padding = NULL,
35
+    adjust_annotation_name = FALSE,
35 36
     
36 37
     row_dend_side = c("original", "left", "right"),
37 38
     row_sub_title_side = c("original", "left", "right"),
... ...
@@ -104,6 +105,7 @@ Draw a list of heatmaps
104 105
   \item{ht_gap}{= gap, }
105 106
   \item{main_heatmap}{= which(sapply(object@ht_list, inherits, "Heatmap"))[1],}
106 107
   \item{padding}{= NULL,}
108
+  \item{adjust_annotation_name}{adjust_annotation_name}
107 109
   \item{row_dend_side}{= c("original", "left", "right"),}
108 110
   \item{row_sub_title_side}{= c("original", "left", "right"),}
109 111
   \item{column_dend_side}{= c("original", "top", "bottom"),}
... ...
@@ -10,6 +10,7 @@ Make oncoPrint
10 10
 oncoPrint(mat,
11 11
     get_type = function(x) x,
12 12
     alter_fun,
13
+    alter_fun_is_vectorized = NULL,
13 14
     col,
14 15
     
15 16
     top_annotation = HeatmapAnnotation(column_barplot = anno_oncoprint_barplot(),
... ...
@@ -37,6 +38,7 @@ oncoPrint(mat,
37 38
   \item{mat}{a character matrix which encodes mulitple alterations or a list of matrix for which every matrix contains binary value representing the alteration is present or absent. When it is a list, the names represent alteration types. You can use \code{\link{unify_mat_list}} to make all matrix having same row names and column names.}
38 39
   \item{get_type}{If different alterations are encoded in the matrix, this self-defined function determines how to extract them. Only work when \code{mat} is a matrix.}
39 40
   \item{alter_fun}{a single function or a list of functions which define how to add graphics for different alterations. If it is a list, the names of the list should cover all alteration types.}
41
+  \item{alter_fun_is_vectorized}{-alter_fun_is_vectorized}
40 42
   \item{col}{a vector of color for which names correspond to alteration types.}
41 43
   \item{top_annotation}{-top_annotation}
42 44
   \item{right_annotation}{-right_annotation}
43 45
new file mode 100644
... ...
@@ -0,0 +1,34 @@
1
+\name{pindex}
2
+\alias{pindex}
3
+\title{
4
+Get values in a matrix by pair-wise indices
5
+}
6
+\description{
7
+Get values in a matrix by pair-wise indices
8
+}
9
+\usage{
10
+pindex(m, i, j)
11
+}
12
+\arguments{
13
+
14
+  \item{m}{a matrix or a 3d array}
15
+  \item{i}{row indices}
16
+  \item{j}{column indicies}
17
+
18
+}
19
+\examples{
20
+m = matrix(rnorm(100), 10)
21
+m2 = m[m > 0]
22
+ind = do.call("rbind", lapply(1:10, function(ci) {
23
+    i = which(m[, ci] > 0)
24
+    cbind(i = i, j = rep(ci, length(i)))
25
+}))
26
+pindex(m, ind[, 1], ind[, 2])
27
+identical(pindex(m, ind[, 1], ind[, 2]), m[m > 0])
28
+
29
+# 3d array
30
+arr = array(1:27, dim = c(3, 3, 3))
31
+pindex(arr, 1:2, 2:3)
32
+identical(pindex(arr, 1:2, 2:3),
33
+   rbind(arr[1, 2, ], arr[2, 3, ]))
34
+}