1 | 1 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,18 @@ |
1 |
+Package: mheatmap |
|
2 |
+Type: Package |
|
3 |
+Title: plot multiple heatmaps |
|
4 |
+Version: 0.99.0 |
|
5 |
+Date: 2014-10-6 |
|
6 |
+Author: Zuguang Gu |
|
7 |
+Maintainer: Zuguang Gu <z.gu@dkfz.de> |
|
8 |
+Depends: R (>= 3.1.0), methods, grid |
|
9 |
+Imports: circlize (>= 0.2.3), GetoptLong, RColorBrewer |
|
10 |
+Suggests: testthat (>= 0.3), knitr |
|
11 |
+VignetteBuilder: knitr |
|
12 |
+Description: plot multiple heatmaps |
|
13 |
+biocViews: Software, Visualization, Sequencing |
|
14 |
+URL: https://github.com/jokergoo/mheatmap |
|
15 |
+License: GPL (>= 2) |
|
16 |
+Packaged: 2014-10-6 00:00:00 UTC; Administrator |
|
17 |
+Repository: Bioconductor |
|
18 |
+Date/Publication: 2014-10-6 00:00:00 |
0 | 19 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,34 @@ |
1 |
+exportMethods(draw_annotation_legend) |
|
2 |
+exportMethods(component_height) |
|
3 |
+exportClasses(ColorMapping) |
|
4 |
+exportMethods(draw_hclust) |
|
5 |
+exportMethods(make_layout) |
|
6 |
+exportMethods(draw_annotation) |
|
7 |
+exportMethods(draw_dimnames) |
|
8 |
+exportClasses(Heatmap) |
|
9 |
+exportMethods(annotation_legend_size) |
|
10 |
+export("+.Heatmap") |
|
11 |
+exportClasses(HeatmapList) |
|
12 |
+exportMethods(legend) |
|
13 |
+exportMethods(component_width) |
|
14 |
+exportMethods(draw_heatmap_list) |
|
15 |
+export(dist2) |
|
16 |
+exportMethods(map) |
|
17 |
+exportMethods(draw_title) |
|
18 |
+exportMethods(draw) |
|
19 |
+exportMethods(draw_heatmap_legend) |
|
20 |
+exportMethods(draw_heatmap_body) |
|
21 |
+exportMethods(add_heatmap) |
|
22 |
+exportMethods(initialize) |
|
23 |
+exportMethods(heatmap_legend_size) |
|
24 |
+export("+.HeatmapList") |
|
25 |
+ |
|
26 |
+import(grid) |
|
27 |
+import(methods) |
|
28 |
+importFrom("RColorBrewer", brewer.pal) |
|
29 |
+importFrom("circlize", colorRamp2) |
|
30 |
+importFrom("circlize", rand_color) |
|
31 |
+importFrom("GetoptLong", qq) |
|
32 |
+importFrom("GetoptLong", qqcat) |
|
33 |
+importFrom("GetoptLong", qq.options) |
|
34 |
+ |
0 | 35 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,49 @@ |
1 |
+ |
|
2 |
+set_generic_functions = function(fname) { |
|
3 |
+ |
|
4 |
+ op = qq.options(READ.ONLY = FALSE) |
|
5 |
+ on.exit(qq.options(op)) |
|
6 |
+ qq.options(code.pattern = "@\\{CODE\\}") |
|
7 |
+ |
|
8 |
+ for(f in unique(fname)) { |
|
9 |
+ |
|
10 |
+ eval(parse(text = qq(" |
|
11 |
+if(!isGeneric('@{f}')) { |
|
12 |
+ if(is.function('@{f}')) { |
|
13 |
+ fun = @{f} |
|
14 |
+ } else { |
|
15 |
+ fun = function(object, ...) standardGeneric('@{f}', ...) |
|
16 |
+ } |
|
17 |
+ setGeneric('@{f}', fun) |
|
18 |
+} |
|
19 |
+"))) |
|
20 |
+ } |
|
21 |
+} |
|
22 |
+ |
|
23 |
+set_generic_functions(c( |
|
24 |
+ "map", |
|
25 |
+ "legend", |
|
26 |
+ |
|
27 |
+ "add_heatmap", |
|
28 |
+ "draw_heatmap_body", |
|
29 |
+ "draw_hclust", |
|
30 |
+ "draw_dimnames", |
|
31 |
+ "draw_title", |
|
32 |
+ "draw_annotation", |
|
33 |
+ "component_width", |
|
34 |
+ "component_height", |
|
35 |
+ "set_component_height", |
|
36 |
+ "draw", |
|
37 |
+ |
|
38 |
+ "add_heatmap", |
|
39 |
+ "make_layout", |
|
40 |
+ "draw", |
|
41 |
+ "component_width", |
|
42 |
+ "component_height", |
|
43 |
+ "draw_heatmap_list", |
|
44 |
+ "draw_title", |
|
45 |
+ "draw_heatmap_legend", |
|
46 |
+ "draw_annotation_legend", |
|
47 |
+ "heatmap_legend_size", |
|
48 |
+ "annotation_legend_size" |
|
49 |
+)) |
... | ... |
@@ -1,13 +1,34 @@ |
1 | 1 |
|
2 | 2 |
##################################### |
3 |
-# class to map values to colors |
|
3 |
+# class and methods to map values to colors |
|
4 | 4 |
# |
5 |
-# 1. map values to colors, both discrete and continuous |
|
6 |
-# 2. generate a legend which corresponds to color mapping |
|
7 |
-# 3. return the size of the legend |
|
8 | 5 |
|
9 |
-ColorMapping = setRefClass("ColorMapping", |
|
10 |
- fields = list( |
|
6 |
+# == title |
|
7 |
+# class to map values to colors |
|
8 |
+# |
|
9 |
+# == details |
|
10 |
+# The `ColorMapping` class can handle color mapping with both discrete values and continuous values. |
|
11 |
+# |
|
12 |
+# == constructor |
|
13 |
+# |
|
14 |
+# ColorMapping(name, colors = NULL, levels = NULL, |
|
15 |
+# col_fun = NULL, breaks = NULL) |
|
16 |
+# |
|
17 |
+# -name name for this color mapping |
|
18 |
+# -colors discrete colors |
|
19 |
+# -levels levels that correspond to ``colors`` |
|
20 |
+# -col_fun color mapping function that maps continuous values to colors |
|
21 |
+# -breaks breaks for the continuous color mapping |
|
22 |
+# |
|
23 |
+# ``colors`` and ``levels`` are for discrete color mapping, ``col_fun`` and |
|
24 |
+# ``breaks`` are for continuous color mapping. If ``col_fun`` is generated from |
|
25 |
+# `circlize::colorRamp2`, ``breaks`` does not need to be specified. |
|
26 |
+# |
|
27 |
+# == author |
|
28 |
+# Zuguang Gu <z.gu@dkfz.de> |
|
29 |
+# |
|
30 |
+ColorMapping = setClass("ColorMapping", |
|
31 |
+ slots = list( |
|
11 | 32 |
colors = "character", # a list of colors |
12 | 33 |
levels = "character", # levels which colors correspond to |
13 | 34 |
col_fun = "function", # function to map values to colors |
... | ... |
@@ -16,8 +37,19 @@ ColorMapping = setRefClass("ColorMapping", |
16 | 37 |
) |
17 | 38 |
) |
18 | 39 |
|
19 |
-# constructor |
|
20 |
-suppressWarnings(ColorMapping$methods(initialize = function(name, colors = NULL, levels = NULL, |
|
40 |
+# == title |
|
41 |
+# initialize |
|
42 |
+# |
|
43 |
+# == param |
|
44 |
+# -name name |
|
45 |
+# -colors colors |
|
46 |
+# -levels levels |
|
47 |
+# -col_fun color function |
|
48 |
+# -breaks breaks |
|
49 |
+# |
|
50 |
+setMethod(f = "initialize", |
|
51 |
+ signature = "ColorMapping", |
|
52 |
+ definition = function(.Object, name, colors = NULL, levels = NULL, |
|
21 | 53 |
col_fun = NULL, breaks = NULL) { |
22 | 54 |
|
23 | 55 |
if(is.null(name)) { |
... | ... |
@@ -33,10 +65,15 @@ suppressWarnings(ColorMapping$methods(initialize = function(name, colors = NULL, |
33 | 65 |
if(length(colors) != length(levels)) { |
34 | 66 |
stop("length of colors and length of levels should be the same.\n") |
35 | 67 |
} |
36 |
- .self$colors = colors |
|
37 |
- .self$levels = levels |
|
38 |
- names(.self$colors) = levels |
|
39 |
- .self$type = "discrete" |
|
68 |
+ .Object@colors = colors |
|
69 |
+ if(is.numeric(levels)) { |
|
70 |
+ .Object@levels = as.character(levels) |
|
71 |
+ attr(.Object@levels, "numeric") = TRUE |
|
72 |
+ } else { |
|
73 |
+ .Object@levels = levels |
|
74 |
+ } |
|
75 |
+ names(.Object@colors) = levels |
|
76 |
+ .Object@type = "discrete" |
|
40 | 77 |
} else if(!is.null(col_fun)) { |
41 | 78 |
if(is.null(breaks)) { |
42 | 79 |
breaks = attr(col_fun, "breaks") |
... | ... |
@@ -45,52 +82,72 @@ suppressWarnings(ColorMapping$methods(initialize = function(name, colors = NULL, |
45 | 82 |
} |
46 | 83 |
} |
47 | 84 |
le = grid.pretty(range(breaks)) |
48 |
- .self$colors = col_fun(le) |
|
49 |
- .self$levels = as.character(le) |
|
50 |
- .self$col_fun = col_fun |
|
51 |
- .self$type = "continuous" |
|
85 |
+ .Object@colors = col_fun(le) |
|
86 |
+ .Object@levels = as.character(le) |
|
87 |
+ .Object@col_fun = col_fun |
|
88 |
+ .Object@type = "continuous" |
|
52 | 89 |
} else { |
53 | 90 |
stop("initialization failed. Either specify `colors` + `levels` or `col_fun` + `breaks` (optional)\n") |
54 | 91 |
} |
55 | 92 |
|
56 |
- .self$name = name |
|
93 |
+ .Object@name = name |
|
57 | 94 |
|
58 |
- return(invisible(.self)) |
|
59 |
-})) |
|
95 |
+ return(.Object) |
|
96 |
+}) |
|
60 | 97 |
|
61 |
-ColorMapping$methods(show = function(x) { |
|
62 |
- if(.self$type == "discrete") { |
|
98 |
+setMethod(f = "show", |
|
99 |
+ signature = "ColorMapping", |
|
100 |
+ definition = function(object) { |
|
101 |
+ if(object@type == "discrete") { |
|
63 | 102 |
cat("Discrete color mapping:\n") |
64 | 103 |
cat("levels:\n") |
65 |
- print(.self$levels) |
|
104 |
+ print(object@levels) |
|
66 | 105 |
cat("\n") |
67 | 106 |
cat("colors:\n") |
68 |
- col = .self$colors; names(col) = NULL |
|
107 |
+ col = object@colors; names(col) = NULL |
|
69 | 108 |
print(col) |
70 | 109 |
cat("\n") |
71 |
- } else if(.self$type == "continuous") { |
|
110 |
+ } else if(object@type == "continuous") { |
|
72 | 111 |
cat("Continuous color mapping:\n") |
73 | 112 |
cat("breaks:\n") |
74 |
- print(.self$levels) |
|
113 |
+ print(object@levels) |
|
75 | 114 |
cat("\n") |
76 | 115 |
cat("colors:\n") |
77 |
- col = .self$colors; names(col) = NULL |
|
116 |
+ col = object@colors; names(col) = NULL |
|
78 | 117 |
print(col) |
79 | 118 |
cat("\n") |
80 | 119 |
} |
81 | 120 |
}) |
82 | 121 |
|
83 |
-# map values to colors and keep the attributes (in case it is a matrix) |
|
84 |
-ColorMapping$methods(map = function(x) { |
|
122 |
+# == title |
|
123 |
+# map values to colors |
|
124 |
+# |
|
125 |
+# == param |
|
126 |
+# -object a `ColorMapping` object |
|
127 |
+# -x input values |
|
128 |
+# |
|
129 |
+# == details |
|
130 |
+# It maps a vector of values to a vector of colors |
|
131 |
+# |
|
132 |
+# == value |
|
133 |
+# a vector of colors |
|
134 |
+# |
|
135 |
+# == author |
|
136 |
+# Zuguang Gu <z.gu@dkfz.de> |
|
137 |
+# |
|
138 |
+setMethod(f = "map", |
|
139 |
+ signature = "ColorMapping", |
|
140 |
+ definition = function(object, x) { |
|
85 | 141 |
original_attr = attributes(x) |
86 |
- if(.self$type == "discrete") { |
|
87 |
- if(any(! x %in% .self$levels)) { |
|
88 |
- msg = paste0("Cannot map some of the levels:\n", paste(setdiff(x, .self$levels), sep = ", ", collapse = ", ")) |
|
142 |
+ if(object@type == "discrete") { |
|
143 |
+ if(is.numeric(x)) x = as.character(x) |
|
144 |
+ if(any(! x %in% object@levels)) { |
|
145 |
+ msg = paste0("Cannot map some of the levels:\n", paste(setdiff(x, object@levels), sep = ", ", collapse = ", ")) |
|
89 | 146 |
stop(msg) |
90 | 147 |
} |
91 |
- x = .self$colors[x] |
|
148 |
+ x = object@colors[x] |
|
92 | 149 |
} else { |
93 |
- x = .self$col_fun(x) |
|
150 |
+ x = object@col_fun(x) |
|
94 | 151 |
} |
95 | 152 |
|
96 | 153 |
# keep original attributes, such as dimension |
... | ... |
@@ -98,36 +155,59 @@ ColorMapping$methods(map = function(x) { |
98 | 155 |
return(x) |
99 | 156 |
}) |
100 | 157 |
|
101 |
-# add legend to the plot, or just return the size of the legend |
|
102 |
-ColorMapping$methods(legend = function(..., plot = TRUE, legend_grid_height = unit(3, "mm"), |
|
103 |
- legend_grid_width = unit(5, "mm"), legend_title_gp = gpar(fontsize = 12), |
|
158 |
+ |
|
159 |
+# == title |
|
160 |
+# generate legend based on color mapping |
|
161 |
+# |
|
162 |
+# == param |
|
163 |
+# -object a `ColorMapping` object |
|
164 |
+# -... pass to `grid::viewport` |
|
165 |
+# -plot whether to plot or just return the size of the legend grob |
|
166 |
+# -legend_grid_height height of each legend grid |
|
167 |
+# -legend_grid_width width of each legend grid |
|
168 |
+# -legend_title_gp graphic parameter for legend title |
|
169 |
+# -legend_label_gp graphic parameter for legend label |
|
170 |
+# |
|
171 |
+# == details |
|
172 |
+# This function adds legend to the plot, or just returns the size of the legend. |
|
173 |
+# |
|
174 |
+# == value |
|
175 |
+# A `grid::unit` object with length two. |
|
176 |
+# |
|
177 |
+# == author |
|
178 |
+# Zuguang Gu <z.gu@dkfz.de> |
|
179 |
+# |
|
180 |
+setMethod(f = "legend", |
|
181 |
+ signature = "ColorMapping", |
|
182 |
+ definition = function(object, ..., plot = TRUE, legend_grid_height = unit(3, "mm"), |
|
183 |
+ legend_grid_width = unit(5, "mm"), legend_title_gp = gpar(fontsize = 10), |
|
104 | 184 |
legend_label_gp = gpar(fontsize = 10)) { |
105 | 185 |
|
106 | 186 |
# add title |
107 |
- legend_title_grob = textGrob(.self$name, unit(0, "npc"), unit(1, "npc"), just = c("left", "top"), |
|
187 |
+ legend_title_grob = textGrob(object@name, unit(0, "npc"), unit(1, "npc"), just = c("left", "top"), |
|
108 | 188 |
gp = legend_title_gp) |
109 | 189 |
legend_title_height = grobHeight(legend_title_grob) |
110 | 190 |
legend_title_width = grobWidth(legend_title_grob) |
111 | 191 |
|
112 |
- nlevel = length(.self$levels) |
|
192 |
+ nlevel = length(object@levels) |
|
113 | 193 |
x = unit(rep(0, nlevel), "npc") |
114 |
- y = unit(1, "npc") - 1.5*legend_title_height - (0:(nlevel-1))*(legend_grid_height + unit(1, "mm")) |
|
194 |
+ y = 1.5*legend_title_height + (0:(nlevel-1))*(legend_grid_height + unit(1, "mm")) |
|
115 | 195 |
|
116 |
- legend_label_max_width = max(do.call("unit.c", lapply(.self$levels, function(x) { |
|
196 |
+ legend_label_max_width = max(do.call("unit.c", lapply(object@levels, function(x) { |
|
117 | 197 |
grobWidth(textGrob(x, gp = legend_label_gp)) |
118 | 198 |
}))) |
119 | 199 |
vp_width = max(unit.c(legend_title_width, |
120 |
- legend_grid_width + unit(2, "mm") + legend_label_max_width )) |
|
200 |
+ legend_grid_width + unit(1, "mm") + legend_label_max_width )) |
|
121 | 201 |
vp_height = legend_title_height*1.5 + nlevel*(legend_grid_height + unit(1, "mm")) |
122 | 202 |
|
123 | 203 |
if(plot) { |
124 |
- pushViewport(viewport(..., width = vp_width, height = vp_height, name = paste0("legend_", .self$name))) |
|
204 |
+ pushViewport(viewport(..., width = vp_width, height = vp_height, name = paste0("legend_", object@name))) |
|
125 | 205 |
|
126 |
- grid.text(.self$name, unit(0, "npc"), unit(1, "npc"), just = c("left", "top"), |
|
206 |
+ grid.text(object@name, unit(0, "npc"), unit(1, "npc"), just = c("left", "top"), |
|
127 | 207 |
gp = legend_title_gp) |
128 | 208 |
grid.rect(x, y, width = legend_grid_width, height = legend_grid_height, just = c("left", "top"), |
129 |
- gp = gpar(col = NA, fill = .self$colors)) |
|
130 |
- grid.text(.self$levels, x + legend_grid_width + unit(2, "mm"), y - legend_grid_height*0.5, |
|
209 |
+ gp = gpar(col = NA, fill = object@colors)) |
|
210 |
+ grid.text(object@levels, x + legend_grid_width + unit(1, "mm"), y - legend_grid_height*0.5, |
|
131 | 211 |
just = c("left", "center"), gp = legend_label_gp) |
132 | 212 |
upViewport() |
133 | 213 |
} |
134 | 214 |
deleted file mode 100644 |
... | ... |
@@ -1,19 +0,0 @@ |
1 |
-setGeneric("draw", function(x, ...) { |
|
2 |
- standardGeneric("draw") |
|
3 |
-}) |
|
4 |
- |
|
5 |
-setMethod("draw", |
|
6 |
- c(x = "Heatmap"), |
|
7 |
- function(x, ...) { |
|
8 |
- ht_list = new("HeatmapList") |
|
9 |
- ht_list$add_heatmap(x) |
|
10 |
- ht_list$draw(...) |
|
11 |
- } |
|
12 |
-) |
|
13 |
- |
|
14 |
-setMethod("draw", |
|
15 |
- c(x = "HeatmapList"), |
|
16 |
- function(x, ...) { |
|
17 |
- x$draw(...) |
|
18 |
- } |
|
19 |
-) |
... | ... |
@@ -2,709 +2,975 @@ |
2 | 2 |
############################### |
3 | 3 |
# class for single heatmap |
4 | 4 |
# |
5 |
-# this class would be a private class. The plotting of heatmap |
|
6 |
-# is really taken care by HeatmapList class. |
|
7 |
-# |
|
8 |
-# the draw method only plots the heatmap body, cluster, annotation and dimnames |
|
9 |
-# |
|
5 |
+ |
|
10 | 6 |
|
11 | 7 |
# the layout of the heatmap is 7 x 9 |
12 |
-Heatmap = setRefClass("Heatmap", |
|
13 |
- fields = list( |
|
14 |
- name = "character", |
|
15 |
- matrix = "matrix", # original order |
|
16 |
- row_hclust = "ANY", |
|
17 |
- column_hclust = "ANY", |
|
18 |
- column_anno = "ANY", # annotation data frame, order of columns are same as matrix |
|
19 |
- column_anno_color_mapping = "list", # a list of ColorMapping class objects |
|
20 |
- matrix_color_mapping = "ANY", |
|
21 |
- |
|
22 |
- layout = "list", |
|
23 |
- gp_list = "list" |
|
8 |
+ |
|
9 |
+# == title |
|
10 |
+# class for single heatmap |
|
11 |
+# |
|
12 |
+# == details |
|
13 |
+# The components for a heamtap is |
|
14 |
+# |
|
15 |
+# +------+ |
|
16 |
+# +------+ |
|
17 |
+# +------+ |
|
18 |
+# +------+ |
|
19 |
+# +-+-+-+------+-+-+-+ |
|
20 |
+# | | | | | | | | |
|
21 |
+# +-+-+-+------+-+-+-+ |
|
22 |
+# +------+ |
|
23 |
+# +------+ |
|
24 |
+# +------+ |
|
25 |
+# +------+ |
|
26 |
+# |
|
27 |
+Heatmap = setClass("Heatmap", |
|
28 |
+ slots = list( |
|
29 |
+ name = "character", |
|
30 |
+ matrix = "matrix", # original order |
|
31 |
+ row_hclust = "ANY", |
|
32 |
+ column_hclust = "ANY", |
|
33 |
+ column_anno = "ANY", # annotation data frame, order of columns are same as matrix |
|
34 |
+ column_anno_color_mapping = "list", # a list of ColorMapping objects |
|
35 |
+ matrix_color_mapping = "ANY", |
|
36 |
+ |
|
37 |
+ layout = "environment", |
|
38 |
+ gp_list = "list" |
|
24 | 39 |
) |
25 | 40 |
) |
26 | 41 |
|
42 |
+# default colors for matrix or annotations |
|
43 |
+# this function should be improved later |
|
27 | 44 |
default_col = function(x, main_matrix = FALSE) { |
28 | 45 |
|
29 |
- if(length(unique(x)) == 1) { |
|
30 |
- x = as.character(x) |
|
31 |
- } |
|
32 |
- |
|
33 |
- if(is.character(x)) { # discrete |
|
34 |
- levels = unique(x) |
|
35 |
- colors = rand_color(length(levels)) |
|
36 |
- names(colors) = levels |
|
37 |
- return(colors) |
|
38 |
- } else if(is.numeric(x)) { |
|
39 |
- if(main_matrix) { |
|
40 |
- col_fun = colorRamp2(seq(min(x), max(x), length.out = 11), |
|
41 |
- rev(brewer.pal(11, "RdYlBu"))) |
|
42 |
- } else { |
|
43 |
- col_fun = colorRamp2(range(min(x), max(x)), c("white", rand_color(1))) |
|
44 |
- } |
|
45 |
- return(col_fun) |
|
46 |
- } |
|
46 |
+ if(is.factor(x)) { |
|
47 |
+ x = as.character(x) |
|
48 |
+ } |
|
49 |
+ |
|
50 |
+ if(length(unique(x)) == 1) { |
|
51 |
+ x = as.character(x) |
|
52 |
+ } |
|
53 |
+ |
|
54 |
+ attributes(x) = NULL |
|
55 |
+ |
|
56 |
+ if(is.character(x)) { # discrete |
|
57 |
+ levels = unique(x) |
|
58 |
+ colors = rand_color(length(levels)) |
|
59 |
+ names(colors) = levels |
|
60 |
+ return(colors) |
|
61 |
+ } else if(is.numeric(x)) { |
|
62 |
+ if(main_matrix) { |
|
63 |
+ col_fun = colorRamp2(seq(min(x), max(x), length.out = 11), |
|
64 |
+ rev(brewer.pal(11, "RdYlBu"))) |
|
65 |
+ } else { |
|
66 |
+ col_fun = colorRamp2(range(min(x), max(x)), c("white", rand_color(1))) |
|
67 |
+ } |
|
68 |
+ return(col_fun) |
|
69 |
+ } |
|
47 | 70 |
} |
48 | 71 |
|
49 |
-# matrix can be a numeric matrix or a character matrix |
|
50 |
-Heatmap$methods(initialize = function(matrix, col, name, rect_gp = gpar(col = NA), |
|
51 |
- row_title = character(0), row_title_side = c("left", "right"), row_title_gp = gpar(fontsize = 14), |
|
52 |
- column_title = character(0), column_title_side = c("top", "bottom"), column_title_gp = gpar(fontsize = 14), |
|
53 |
- cluster_rows = TRUE, clustering_distance_rows = "euclidean", clustering_method_rows = "complete", |
|
54 |
- row_hclust_side = c("left", "right"), row_hclust_width = unit(10, "mm"), show_row_hclust = TRUE, row_hclust_gp = gpar(), |
|
55 |
- cluster_columns = TRUE, clustering_distance_columns = "euclidean", clustering_method_columns = "complete", |
|
56 |
- column_hclust_side = c("top", "bottom"), column_hclust_height = unit(10, "mm"), show_column_hclust = TRUE, column_hclust_gp = gpar(), |
|
57 |
- rownames_side = c("right", "left"), show_rownames = TRUE, rownames_gp = gpar(fontsize = 12), |
|
58 |
- colnames_side = c("bottom", "top"), show_colnames = TRUE, colnames_gp = gpar(fontsize = 12), |
|
59 |
- annotation = NULL, annotation_color = NULL, annotation_side = c("top", "bottom"), |
|
60 |
- annotation_height = if(is.null(annotation)) unit(0, "null") else ncol(annotation)*unit(4, "mm"), annotation_gp = gpar() |
|
61 |
- ) { |
|
62 |
- |
|
63 |
- .self$gp_list = list(rect_gp = rect_gp, |
|
64 |
- row_title_gp = row_title_gp, |
|
65 |
- column_title_gp = column_title_gp, |
|
66 |
- row_hclust_gp = rownames_gp, |
|
67 |
- column_hclust_gp = column_hclust_gp, |
|
68 |
- rownames_gp = rownames_gp, |
|
69 |
- colnames_gp = colnames_gp, |
|
70 |
- annotation_gp = annotation_gp) |
|
71 |
- |
|
72 |
- if(missing(col)) { |
|
73 |
- col = default_col(matrix, main_matrix = TRUE) |
|
74 |
- } |
|
75 |
- |
|
76 |
- if(missing(name)) { |
|
77 |
- name = paste0("matrix", get_n_heatmap() + 1) |
|
78 |
- increase_n_heatmap() |
|
79 |
- } |
|
80 |
- |
|
81 |
- if(is.function(col)) { |
|
82 |
- .self$matrix_color_mapping = ColorMapping(col_fun = col, name = name) |
|
83 |
- } else { |
|
84 |
- .self$matrix_color_mapping = ColorMapping(colors = col, name = name) |
|
85 |
- } |
|
86 |
- .self$name = name |
|
87 |
- |
|
88 |
- if(cluster_rows) { |
|
89 |
- .self$row_hclust = hclust(get_dist(matrix, clustering_distance_rows), method = clustering_method_rows) |
|
90 |
- row_order = row_hclust$order |
|
91 |
- } else { |
|
92 |
- row_hclust_width = unit(0, "null") |
|
93 |
- .self$row_hclust = NULL |
|
94 |
- row_order = seq_len(nrow(matrix)) |
|
95 |
- } |
|
96 |
- |
|
97 |
- if(cluster_columns) { |
|
98 |
- .self$column_hclust = hclust(get_dist(t(matrix), clustering_distance_columns), method = clustering_method_columns) |
|
99 |
- column_order = column_hclust$order |
|
100 |
- } else { |
|
101 |
- column_hclust_height = unit(0, "null") |
|
102 |
- .self$column_hclust = NULL |
|
103 |
- column_order = seq_len(ncol(matrix)) |
|
104 |
- } |
|
105 |
- |
|
106 |
- .self$matrix = matrix[row_order, column_order, drop = FALSE] |
|
107 |
- |
|
108 |
- if(is.null(annotation)) { |
|
109 |
- # don't need to consider annotation_color |
|
110 |
- } else if(is.data.frame(annotation)) { |
|
111 |
- # if there is rownames |
|
112 |
- if(is.null(rownames(annotation))) { |
|
113 |
- .self$column_anno = annotation[col_order, , drop = FALSE] |
|
114 |
- } else { |
|
115 |
- .self$column_anno = annotation[colnames(matrix), , drop = FALSE] |
|
116 |
- } |
|
117 |
- |
|
118 |
- if(is.null(colnames(annotation))) { |
|
119 |
- stop("`annotation` should have colnames.") |
|
120 |
- } |
|
121 |
- |
|
122 |
- if(is.null(annotation_color)) { |
|
123 |
- annotation_color = lapply(annotation, default_col) |
|
124 |
- } |
|
125 |
- |
|
126 |
- if(is.null(names(annotation_color))) { |
|
127 |
- stop("`annotation_color` should have names to map to `annotation`.") |
|
128 |
- } |
|
129 |
- |
|
130 |
- if(!setequal(colnames(annotation), names(annotation_color))) { |
|
131 |
- stop("You should provide colors for all annotations.") |
|
132 |
- } else { |
|
133 |
- annotation_color = annotation_color[colnames(annotation)] |
|
134 |
- annotation_name = names(annotation_color) |
|
135 |
- column_anno_color_mapping = list() |
|
136 |
- for(i in seq_along(annotation_color)) { |
|
137 |
- if(is.atomic(annotation_color[[i]])) { |
|
138 |
- .self$column_anno_color_mapping[[i]] = ColorMapping(name = annotation_name[i], |
|
139 |
- colors = annotation_color[[i]]) |
|
140 |
- } else if(is.function(annotation_color[[i]])) { |
|
141 |
- .self$column_anno_color_mapping[[i]] = ColorMapping(name = annotation_name[i], |
|
142 |
- col_fun = annotation_color[[i]]) |
|
143 |
- } |
|
144 |
- } |
|
145 |
- } |
|
146 |
- } else { |
|
147 |
- stop("`annotation` should be a data frame.") |
|
148 |
- } |
|
149 |
- |
|
150 |
- # settings for positin of each component |
|
151 |
- .self$layout = list( |
|
152 |
- layout_column_title_top_height = NULL, |
|
153 |
- layout_column_hclust_top_height = NULL, |
|
154 |
- layout_column_anno_top_height = NULL, |
|
155 |
- layout_colnames_top_height = NULL, |
|
156 |
- layout_column_title_bottom_height = NULL, |
|
157 |
- layout_column_hclust_bottom_height = NULL, |
|
158 |
- layout_column_anno_bottom_height = NULL, |
|
159 |
- layout_colnames_bottom_height = NULL, |
|
160 |
- |
|
161 |
- layout_row_title_left_width = NULL, |
|
162 |
- layout_row_hclust_left_width = NULL, |
|
163 |
- layout_rownames_left_width = NULL, |
|
164 |
- layout_row_hclust_right_width = NULL, |
|
165 |
- layout_rownames_right_width = NULL, |
|
166 |
- layout_row_title_right_width = NULL, |
|
167 |
- |
|
168 |
- layout_index = matrix(nrow = 0, ncol = 2), |
|
169 |
- graphic_fun_list = list() |
|
170 |
- ) |
|
72 |
+# == title |
|
73 |
+# constructor of `Heatmap` class |
|
74 |
+# |
|
75 |
+# == param |
|
76 |
+# -matrix matrix |
|
77 |
+# -col color |
|
78 |
+# -name name |
|
79 |
+# -rect_gp graphic parameters for drawing rectangles |
|
80 |
+# -row_title title on rows |
|
81 |
+# -row_title_side side |
|
82 |
+# -row_title_gp gp |
|
83 |
+# -column_title foo |
|
84 |
+# -column_title_side foo |
|
85 |
+# -column_title_gp foo |
|
86 |
+# -cluster_rows foo |
|
87 |
+# -clustering_distance_rows foo |
|
88 |
+# -clustering_method_rows foo |
|
89 |
+# -row_hclust_side foo |
|
90 |
+# -row_hclust_width foo |
|
91 |
+# -show_row_hclust foo |
|
92 |
+# -row_hclust_gp foo |
|
93 |
+# -cluster_columns foo |
|
94 |
+# -column_hclust_height foo |
|
95 |
+# -show_column_hclust foo |
|
96 |
+# -column_hclust_side foo |
|
97 |
+# -column_hclust_height foo |
|
98 |
+# -show_column_hclust foo |
|
99 |
+# -column_hclust_gp foo |
|
100 |
+# -rownames_side foo |
|
101 |
+# -show_rownames foo |
|
102 |
+# -rownames_gp foo |
|
103 |
+# -colnames_side foo |
|
104 |
+# -show_colnames foo |
|
105 |
+# -colnames_gp foo |
|
106 |
+# -annotation foo |
|
107 |
+# -annotation_color foo |
|
108 |
+# -annotation_side foo |
|
109 |
+# -annotation_height foo |
|
110 |
+# -annotation_gp foo |
|
111 |
+# |
|
112 |
+# == value |
|
113 |
+# a `Heatmap` object |
|
114 |
+# |
|
115 |
+# == author |
|
116 |
+# Zuguang Gu <z.gu@dkfz.de> |
|
117 |
+# |
|
118 |
+setMethod(f = "initialize", |
|
119 |
+ signature = "Heatmap", |
|
120 |
+ definition = function(.Object, matrix, col, name, rect_gp = gpar(col = NA), |
|
121 |
+ row_title = character(0), row_title_side = c("left", "right"), row_title_gp = gpar(fontsize = 14), |
|
122 |
+ column_title = character(0), column_title_side = c("top", "bottom"), column_title_gp = gpar(fontsize = 14), |
|
123 |
+ cluster_rows = TRUE, clustering_distance_rows = "euclidean", clustering_method_rows = "complete", |
|
124 |
+ row_hclust_side = c("left", "right"), row_hclust_width = unit(10, "mm"), show_row_hclust = TRUE, row_hclust_gp = gpar(), |
|
125 |
+ cluster_columns = TRUE, clustering_distance_columns = "euclidean", clustering_method_columns = "complete", |
|
126 |
+ column_hclust_side = c("top", "bottom"), column_hclust_height = unit(10, "mm"), show_column_hclust = TRUE, column_hclust_gp = gpar(), |
|
127 |
+ rownames_side = c("right", "left"), show_rownames = TRUE, rownames_gp = gpar(fontsize = 12), |
|
128 |
+ colnames_side = c("bottom", "top"), show_colnames = TRUE, colnames_gp = gpar(fontsize = 12), |
|
129 |
+ annotation = NULL, annotation_color = NULL, annotation_side = c("top", "bottom"), |
|
130 |
+ annotation_height = if(is.null(annotation)) unit(0, "null") else ncol(annotation)*unit(4, "mm"), annotation_gp = gpar(col = NA) |
|
131 |
+ ) { |
|
132 |
+ |
|
133 |
+ .Object@gp_list = list(rect_gp = rect_gp, |
|
134 |
+ row_title_gp = row_title_gp, |
|
135 |
+ column_title_gp = column_title_gp, |
|
136 |
+ row_hclust_gp = rownames_gp, |
|
137 |
+ column_hclust_gp = column_hclust_gp, |
|
138 |
+ rownames_gp = rownames_gp, |
|
139 |
+ colnames_gp = colnames_gp, |
|
140 |
+ colnames_annotation_gp = annotation_gp) |
|
141 |
+ |
|
142 |
+ if(!is.matrix(matrix)) { |
|
143 |
+ matrix = matrix(matrix, ncol = 1) |
|
144 |
+ } |
|
145 |
+ |
|
146 |
+ if(missing(col)) { |
|
147 |
+ col = default_col(matrix, main_matrix = TRUE) |
|
148 |
+ } |
|
171 | 149 |
|
172 |
- .self$layout$layout_index = rbind(c(5, 4)) |
|
173 |
- .self$layout$graphic_fun_list = list(function() .self$draw_heatmap_body()) |
|
174 |
- |
|
175 |
- ############################################ |
|
176 |
- ## title on top or bottom |
|
177 |
- column_title_side = match.arg(column_title_side)[1] |
|
178 |
- if(length(column_title) == 0) { |
|
179 |
- column_title = character(0) |
|
180 |
- } else if(is.na(column_title)) { |
|
181 |
- column_title = character(0) |
|
182 |
- } else if(column_title == "") { |
|
183 |
- column_title = character(0) |
|
184 |
- } |
|
150 |
+ if(missing(name)) { |
|
151 |
+ name = paste0("matrix", get_heatmap_index() + 1) |
|
152 |
+ increase_heatmap_index() |
|
153 |
+ } |
|
154 |
+ |
|
155 |
+ if(is.function(col)) { |
|
156 |
+ .Object@matrix_color_mapping = ColorMapping(col_fun = col, name = name) |
|
157 |
+ } else { |
|
158 |
+ .Object@matrix_color_mapping = ColorMapping(colors = col, name = name) |
|
159 |
+ } |
|
160 |
+ .Object@name = name |
|
161 |
+ |
|
162 |
+ if(cluster_rows) { |
|
163 |
+ .Object@row_hclust = hclust(get_dist(matrix, clustering_distance_rows), method = clustering_method_rows) |
|
164 |
+ row_order = .Object@row_hclust$order |
|
165 |
+ } else { |
|
166 |
+ row_hclust_width = unit(0, "null") |
|
167 |
+ .Object@row_hclust = NULL |
|
168 |
+ row_order = seq_len(nrow(matrix)) |
|
169 |
+ } |
|
170 |
+ |
|
171 |
+ if(cluster_columns) { |
|
172 |
+ .Object@column_hclust = hclust(get_dist(t(matrix), clustering_distance_columns), method = clustering_method_columns) |
|
173 |
+ column_order = .Object@column_hclust$order |
|
174 |
+ } else { |
|
175 |
+ column_hclust_height = unit(0, "null") |
|
176 |
+ .Object@column_hclust = NULL |
|
177 |
+ column_order = seq_len(ncol(matrix)) |
|
178 |
+ } |
|
179 |
+ |
|
180 |
+ .Object@matrix = matrix[row_order, column_order, drop = FALSE] |
|
181 |
+ |
|
182 |
+ if(is.null(annotation)) { |
|
183 |
+ # don't need to consider annotation_color |
|
184 |
+ } else if(is.data.frame(annotation)) { |
|
185 |
+ |
|
186 |
+ for(i in seq_len(ncol(annotation))) { |
|
187 |
+ if(is.factor(annotation[[i]])) { |
|
188 |
+ annotation[[i]] = as.character(annotation[[i]]) |
|
189 |
+ } |
|
190 |
+ } |
|
191 |
+ |
|
192 |
+ # if there is rownames |
|
193 |
+ if(is.null(rownames(annotation))) { |
|
194 |
+ .Object@column_anno = annotation[column_order, , drop = FALSE] |
|
195 |
+ } else { |
|
196 |
+ .Object@column_anno = annotation[colnames(matrix), , drop = FALSE] |
|
197 |
+ } |
|
198 |
+ |
|
199 |
+ if(is.null(colnames(annotation))) { |
|
200 |
+ stop("`annotation` should have colnames.") |
|
201 |
+ } |
|
202 |
+ |
|
203 |
+ if(is.null(annotation_color)) { |
|
204 |
+ annotation_color = lapply(annotation, default_col) |
|
205 |
+ } |
|
206 |
+ |
|
207 |
+ if(is.null(names(annotation_color))) { |
|
208 |
+ stop("`annotation_color` should have names to map to `annotation`.") |
|
209 |
+ } |
|
210 |
+ |
|
211 |
+ if(!setequal(colnames(annotation), names(annotation_color))) { |
|
212 |
+ stop("You should provide colors for all annotations.") |
|
213 |
+ } else { |
|
214 |
+ annotation_color = annotation_color[colnames(annotation)] |
|
215 |
+ annotation_name = names(annotation_color) |
|
216 |
+ .Object@column_anno_color_mapping = list() |
|
217 |
+ |
|
218 |
+ for(i in seq_along(annotation_color)) { |
|
219 |
+ if(is.atomic(annotation_color[[i]])) { |
|
220 |
+ .Object@column_anno_color_mapping[[i]] = ColorMapping(name = annotation_name[i], |
|
221 |
+ colors = annotation_color[[i]]) |
|
222 |
+ } else if(is.function(annotation_color[[i]])) { |
|
223 |
+ .Object@column_anno_color_mapping[[i]] = ColorMapping(name = annotation_name[i], |
|
224 |
+ col_fun = annotation_color[[i]]) |
|
225 |
+ } |
|
226 |
+ } |
|
227 |
+ } |
|
228 |
+ } else { |
|
229 |
+ stop("`annotation` should be a data frame.") |
|
230 |
+ } |
|
231 |
+ |
|
232 |
+ # settings for positin of each component |
|
233 |
+ .Object@layout = as.environment(list( |
|
234 |
+ layout_column_title_top_height = NULL, |
|
235 |
+ layout_column_hclust_top_height = NULL, |
|
236 |
+ layout_column_anno_top_height = NULL, |
|
237 |
+ layout_colnames_top_height = NULL, |
|
238 |
+ layout_column_title_bottom_height = NULL, |
|
239 |
+ layout_column_hclust_bottom_height = NULL, |
|
240 |
+ layout_column_anno_bottom_height = NULL, |
|
241 |
+ layout_colnames_bottom_height = NULL, |
|
242 |
+ |
|
243 |
+ layout_row_title_left_width = NULL, |
|
244 |
+ layout_row_hclust_left_width = NULL, |
|
245 |
+ layout_rownames_left_width = NULL, |
|
246 |
+ layout_row_hclust_right_width = NULL, |
|
247 |
+ layout_rownames_right_width = NULL, |
|
248 |
+ layout_row_title_right_width = NULL, |
|
249 |
+ |
|
250 |
+ layout_index = matrix(nrow = 0, ncol = 2), |
|
251 |
+ graphic_fun_list = list() |
|
252 |
+ )) |
|
253 |
+ |
|
254 |
+ .Object@layout$layout_index = rbind(c(5, 4)) |
|
255 |
+ .Object@layout$graphic_fun_list = list(function(object) draw_heatmap_body(object)) |
|
256 |
+ |
|
257 |
+ ############################################ |
|
258 |
+ ## title on top or bottom |
|
259 |
+ column_title_side = match.arg(column_title_side)[1] |
|
260 |
+ if(length(column_title) == 0) { |
|
261 |
+ column_title = character(0) |
|
262 |
+ } else if(is.na(column_title)) { |
|
263 |
+ column_title = character(0) |
|
264 |
+ } else if(column_title == "") { |
|
265 |
+ column_title = character(0) |
|
266 |
+ } |
|
185 | 267 |
if(length(column_title) > 0) { |
186 |
- column_title = column_title |
|
187 |
- if(column_title_side == "top") { |
|
188 |
- .self$layout$layout_column_title_top_height = grobHeight(textGrob(column_title, gp = column_title_gp))*2 |
|
189 |
- .self$layout$layout_column_title_bottom_height = unit(0, "null") |
|
190 |
- .self$layout$layout_index = rbind(layout$layout_index, c(1, 4)) |
|
191 |
- } else { |
|
192 |
- .self$layout$layout_column_title_bottom_height = grobHeight(textGrob(column_title, gp = column_title_gp))*2 |
|
193 |
- .self$layout$layout_column_title_top_height = unit(0, "null") |
|
194 |
- .self$layout$layout_index = rbind(layout$layout_index, c(9, 4)) |
|
195 |
- } |
|
196 |
- .self$layout$graphic_fun_list = c(layout$graphic_fun_list, function() .self$draw_title(column_title, which = "column", side = column_title_side)) |
|
268 |
+ column_title = column_title |
|
269 |
+ if(column_title_side == "top") { |
|
270 |
+ .Object@layout$layout_column_title_top_height = grobHeight(textGrob(column_title, gp = column_title_gp))*2 |
|
271 |
+ .Object@layout$layout_column_title_bottom_height = unit(0, "null") |
|
272 |
+ .Object@layout$layout_index = rbind(.Object@layout$layout_index, c(1, 4)) |
|
273 |
+ } else { |
|
274 |
+ .Object@layout$layout_column_title_bottom_height = grobHeight(textGrob(column_title, gp = column_title_gp))*2 |
|
275 |
+ .Object@layout$layout_column_title_top_height = unit(0, "null") |
|
276 |
+ .Object@layout$layout_index = rbind(.Object@layout$layout_index, c(9, 4)) |
|
277 |
+ } |
|
278 |
+ .Object@layout$graphic_fun_list = c(.Object@layout$graphic_fun_list, function(object) draw_title(object, column_title, which = "column", side = column_title_side)) |
|
197 | 279 |
} else { |
198 |
- .self$layout$layout_column_title_top_height = unit(0, "null") |
|
199 |
- .self$layout$layout_column_title_bottom_height = unit(0, "null") |
|
280 |
+ .Object@layout$layout_column_title_top_height = unit(0, "null") |
|
281 |
+ .Object@layout$layout_column_title_bottom_height = unit(0, "null") |
|
200 | 282 |
} |
201 | 283 |
|
202 | 284 |
############################################ |
203 |
- ## title on left or right |
|
204 |
- row_title_side = match.arg(row_title_side)[1] |
|
205 |
- if(length(row_title) == 0) { |
|
206 |
- row_title = character(0) |
|
207 |
- } else if(is.na(row_title)) { |
|
208 |
- row_title = character(0) |
|
209 |
- } else if(row_title == "") { |
|
210 |
- row_title = character(0) |
|
211 |
- } |
|
285 |
+ ## title on left or right |
|
286 |
+ row_title_side = match.arg(row_title_side)[1] |
|
287 |
+ if(length(row_title) == 0) { |
|
288 |
+ row_title = character(0) |
|
289 |
+ } else if(is.na(row_title)) { |
|
290 |
+ row_title = character(0) |
|
291 |
+ } else if(row_title == "") { |
|
292 |
+ row_title = character(0) |
|
293 |
+ } |
|
212 | 294 |
if(length(row_title) > 0) { |
213 |
- row_title = row_title |
|
214 |
- if(row_title_side == "left") { |
|
215 |
- .self$layout$layout_row_title_left_width = grobHeight(textGrob(row_title, gp = row_title_gp))*2 |
|
216 |
- .self$layout$layout_row_title_right_width = unit(0, "null") |
|
217 |
- .self$layout$layout_index = rbind(layout$layout_index, c(5, 1)) |
|
218 |
- } else { |
|
219 |
- .self$layout$layout_row_title_right_width = grobHeight(textGrob(row_title, gp = row_title_gp))*2 |
|
220 |
- .self$layout$layout_row_title_left_width = unit(0, "null") |
|
221 |
- .self$layout$layout_index = rbind(layout$layout_index, c(5, 7)) |
|
222 |
- } |
|
223 |
- .self$layout$graphic_fun_list = c(layout$graphic_fun_list, function() .self$draw_title(row_title, which = "row", side = row_title_side)) |
|
295 |
+ row_title = row_title |
|
296 |
+ if(row_title_side == "left") { |
|
297 |
+ .Object@layout$layout_row_title_left_width = grobHeight(textGrob(row_title, gp = row_title_gp))*2 |
|
298 |
+ .Object@layout$layout_row_title_right_width = unit(0, "null") |
|
299 |
+ .Object@layout$layout_index = rbind(.Object@layout$layout_index, c(5, 1)) |
|
300 |
+ } else { |
|
301 |
+ .Object@layout$layout_row_title_right_width = grobHeight(textGrob(row_title, gp = row_title_gp))*2 |
|
302 |
+ .Object@layout$layout_row_title_left_width = unit(0, "null") |
|
303 |
+ .Object@layout$layout_index = rbind(.Object@layout$layout_index, c(5, 7)) |
|
304 |
+ } |
|
305 |
+ .Object@layout$graphic_fun_list = c(.Object@layout$graphic_fun_list, function(object) draw_title(object, row_title, which = "row", side = row_title_side)) |
|
224 | 306 |
} else { |
225 |
- .self$layout$layout_row_title_left_width = unit(0, "null") |
|
226 |
- .self$layout$layout_row_title_right_width = unit(0, "null") |
|
307 |
+ .Object@layout$layout_row_title_left_width = unit(0, "null") |
|
308 |
+ .Object@layout$layout_row_title_right_width = unit(0, "null") |
|
227 | 309 |
} |
228 | 310 |
|
229 | 311 |
########################################## |
230 | 312 |
## hclust on left or right |
231 | 313 |
row_hclust_side = match.arg(row_hclust_side)[1] |
232 | 314 |
if(show_row_hclust) { |
233 |
- if(row_hclust_side == "left") { |
|
234 |
- .self$layout$layout_row_hclust_left_width = row_hclust_width |
|
235 |
- .self$layout$layout_row_hclust_right_width = unit(0, "null") |
|
236 |
- .self$layout$layout_index = rbind(layout$layout_index, c(5, 2)) |
|
237 |
- } else { |
|
238 |
- .self$layout$layout_row_hclust_right_width = row_hclust_width |
|
239 |
- .self$layout$layout_row_hclust_left_width = unit(0, "null") |
|
240 |
- .self$layout$layout_index = rbind(layout$layout_index, c(5, 6)) |
|
241 |
- } |
|
242 |
- .self$layout$graphic_fun_list = c(layout$graphic_fun_list, function() .self$draw_hclust(which = "row", side = row_hclust_side)) |
|
315 |
+ if(row_hclust_side == "left") { |
|
316 |
+ .Object@layout$layout_row_hclust_left_width = row_hclust_width |
|
317 |
+ .Object@layout$layout_row_hclust_right_width = unit(0, "null") |
|
318 |
+ .Object@layout$layout_index = rbind(.Object@layout$layout_index, c(5, 2)) |
|
319 |
+ } else { |
|
320 |
+ .Object@layout$layout_row_hclust_right_width = row_hclust_width |
|
321 |
+ .Object@layout$layout_row_hclust_left_width = unit(0, "null") |
|
322 |
+ .Object@layout$layout_index = rbind(.Object@layout$layout_index, c(5, 6)) |
|
323 |
+ } |
|
324 |
+ .Object@layout$graphic_fun_list = c(.Object@layout$graphic_fun_list, function(object) draw_hclust(object, which = "row", side = row_hclust_side)) |
|
243 | 325 |
} else { |
244 |
- .self$layout$layout_row_hclust_right_width = unit(0, "null") |
|
245 |
- .self$layout$layout_row_hclust_left_width = unit(0, "null") |
|
326 |
+ .Object@layout$layout_row_hclust_right_width = unit(0, "null") |
|
327 |
+ .Object@layout$layout_row_hclust_left_width = unit(0, "null") |
|
246 | 328 |
} |
247 | 329 |
|
248 | 330 |
########################################## |
249 | 331 |
## hclust on top or bottom |
250 | 332 |
column_hclust_side = match.arg(column_hclust_side)[1] |
251 | 333 |
if(show_column_hclust) { |
252 |
- if(column_hclust_side == "top") { |
|
253 |
- .self$layout$layout_column_hclust_top_height = column_hclust_height |
|
254 |
- .self$layout$layout_column_hclust_bottom_height = unit(0, "null") |
|
255 |
- .self$layout$layout_index = rbind(layout$layout_index, c(2, 4)) |
|
256 |
- } else { |
|
257 |
- .self$layout$layout_column_hclust_bottom_height = column_hclust_height |
|
258 |
- .self$layout$layout_column_hclust_top_height = unit(0, "null") |
|
259 |
- .self$layout$layout_index = rbind(layout$layout_index, c(8, 4)) |
|
260 |
- } |
|
261 |
- .self$layout$graphic_fun_list = c(layout$graphic_fun_list, function() .self$draw_hclust(which = "column", side = column_hclust_side)) |
|
334 |
+ if(column_hclust_side == "top") { |
|
335 |
+ .Object@layout$layout_column_hclust_top_height = column_hclust_height |
|
336 |
+ .Object@layout$layout_column_hclust_bottom_height = unit(0, "null") |
|
337 |
+ .Object@layout$layout_index = rbind(.Object@layout$layout_index, c(2, 4)) |
|
338 |
+ } else { |
|
339 |
+ .Object@layout$layout_column_hclust_bottom_height = column_hclust_height |
|
340 |
+ .Object@layout$layout_column_hclust_top_height = unit(0, "null") |
|
341 |
+ .Object@layout$layout_index = rbind(.Object@layout$layout_index, c(8, 4)) |
|
342 |
+ } |
|
343 |
+ .Object@layout$graphic_fun_list = c(.Object@layout$graphic_fun_list, function(object) draw_hclust(object, which = "column", side = column_hclust_side)) |
|
262 | 344 |
} else { |
263 |
- .self$layout$layout_column_hclust_top_height = unit(0, "null") |
|
264 |
- .self$layout$layout_column_hclust_bottom_height = unit(0, "null") |
|
345 |
+ .Object@layout$layout_column_hclust_top_height = unit(0, "null") |
|
346 |
+ .Object@layout$layout_column_hclust_bottom_height = unit(0, "null") |
|
265 | 347 |
} |
266 | 348 |
|
267 | 349 |
####################################### |
268 | 350 |
## rownames on left or right |
269 | 351 |
rownames_side = match.arg(rownames_side)[1] |
270 | 352 |
if(is.null(rownames(matrix))) { |
271 |
- show_rownames = FALSE |
|
353 |
+ show_rownames = FALSE |
|
272 | 354 |
} |
273 | 355 |
if(show_rownames) { |
274 |
- rownames_width = max(do.call("unit.c", lapply(rownames(matrix), function(x) { |
|
275 |
- grobWidth(textGrob(x, gp = rownames_gp)) |
|
276 |
- }))) + unit(2, "mm") |
|
277 |
- if(rownames_side == "left") { |
|
278 |
- .self$layout$layout_rownames_left_width = rownames_width |
|
279 |
- .self$layout$layout_rownames_right_width = unit(0, "null") |
|
280 |
- .self$layout$layout_index = rbind(layout$layout_index, c(5, 3)) |
|
281 |
- } else { |
|
282 |
- .self$layout$layout_rownames_right_width = rownames_width |
|
283 |
- .self$layout$layout_rownames_left_width = unit(0, "null") |
|
284 |
- .self$layout$layout_index = rbind(layout$layout_index, c(5, 5)) |
|
285 |
- } |
|
286 |
- .self$layout$graphic_fun_list = c(layout$graphic_fun_list, function() .self$draw_dimnames(which = "row", side = rownames_side)) |
|
356 |
+ rownames_width = max(do.call("unit.c", lapply(rownames(matrix), function(x) { |
|
357 |
+ grobWidth(textGrob(x, gp = rownames_gp)) |
|
358 |
+ }))) + unit(2, "mm") |
|
359 |
+ if(rownames_side == "left") { |
|
360 |
+ .Object@layout$layout_rownames_left_width = rownames_width |
|
361 |
+ .Object@layout$layout_rownames_right_width = unit(0, "null") |
|
362 |
+ .Object@layout$layout_index = rbind(.Object@layout$layout_index, c(5, 3)) |
|
363 |
+ } else { |
|
364 |
+ .Object@layout$layout_rownames_right_width = rownames_width |
|
365 |
+ .Object@layout$layout_rownames_left_width = unit(0, "null") |
|
366 |
+ .Object@layout$layout_index = rbind(.Object@layout$layout_index, c(5, 5)) |
|
367 |
+ } |
|
368 |
+ .Object@layout$graphic_fun_list = c(.Object@layout$graphic_fun_list, function(object) draw_dimnames(object, which = "row", side = rownames_side)) |
|
287 | 369 |
} else { |
288 |
- .self$layout$layout_rownames_left_width = unit(0, "null") |
|
289 |
- .self$layout$layout_rownames_right_width = unit(0, "null") |
|
370 |
+ .Object@layout$layout_rownames_left_width = unit(0, "null") |
|
371 |
+ .Object@layout$layout_rownames_right_width = unit(0, "null") |
|
290 | 372 |
} |
291 | 373 |
|
292 | 374 |
######################################### |
293 | 375 |
## colnames on top or bottom |
294 | 376 |
colnames_side = match.arg(colnames_side)[1] |
295 | 377 |
if(is.null(colnames(matrix))) { |
296 |
- show_colnames = FALSE |
|
378 |
+ show_colnames = FALSE |
|
297 | 379 |
} |
298 | 380 |
if(show_colnames) { |
299 |
- colnames_height = max(do.call("unit.c", lapply(colnames(matrix), function(x) { |
|
300 |
- grobWidth(textGrob(x, gp = colnames_gp)) |
|
301 |
- }))) + unit(2, "mm") |
|
302 |
- if(colnames_side == "top") { |
|
303 |
- .self$layout$layout_colnames_top_height = colnames_height |
|
304 |
- .self$layout$layout_colnames_bottom_height = unit(0, "null") |
|
305 |
- .self$layout$layout_index = rbind(layout$layout_index, c(4, 4)) |
|
306 |
- } else { |
|
307 |
- .self$layout$layout_colnames_bottom_height = colnames_height |
|
308 |
- .self$layout$layout_colnames_top_height = unit(0, "null") |
|
309 |
- .self$layout$layout_index = rbind(layout$layout_index, c(6, 4)) |
|
310 |
- } |
|
311 |
- .self$layout$graphic_fun_list = c(layout$graphic_fun_list, function() .self$draw_dimnames(which = "column", side = colnames_side)) |
|
381 |
+ colnames_height = max(do.call("unit.c", lapply(colnames(matrix), function(x) { |
|
382 |
+ grobWidth(textGrob(x, gp = colnames_gp)) |
|
383 |
+ }))) + unit(2, "mm") |
|
384 |
+ if(colnames_side == "top") { |
|
385 |
+ .Object@layout$layout_colnames_top_height = colnames_height |
|
386 |
+ .Object@layout$layout_colnames_bottom_height = unit(0, "null") |
|
387 |
+ .Object@layout$layout_index = rbind(.Object@layout$layout_index, c(4, 4)) |
|
388 |
+ } else { |
|
389 |
+ .Object@layout$layout_colnames_bottom_height = colnames_height |
|
390 |
+ .Object@layout$layout_colnames_top_height = unit(0, "null") |
|
391 |
+ .Object@layout$layout_index = rbind(.Object@layout$layout_index, c(6, 4)) |
|
392 |
+ } |
|
393 |
+ .Object@layout$graphic_fun_list = c(.Object@layout$graphic_fun_list, function(object) draw_dimnames(object, which = "column", side = colnames_side)) |
|
312 | 394 |
} else { |
313 |
- .self$layout$layout_colnames_top_height = unit(0, "null") |
|
314 |
- .self$layout$layout_colnames_bottom_height = unit(0, "null") |
|
395 |
+ .Object@layout$layout_colnames_top_height = unit(0, "null") |
|
396 |
+ .Object@layout$layout_colnames_bottom_height = unit(0, "null") |
|
315 | 397 |
} |
316 | 398 |
|
317 | 399 |
########################################## |
318 | 400 |
## annotation on top or bottom |
319 |
- column_anno_side = match.arg(annotation_side)[1] |
|
320 |
- if(is.null(annotation)) { |
|
321 |
- .self$layout$layout_column_anno_top_height = unit(0, "null") |
|
322 |
- .self$layout$layout_column_anno_bottom_height = unit(0, "null") |
|
323 |
- } else { |
|
324 |
- if(column_anno_side == "top") { |
|
325 |
- .self$layout$layout_column_anno_top_height = annotation_height |
|
326 |
- .self$layout$layout_column_anno_bottom_height = unit(0, "null") |
|
327 |
- .self$layout$layout_index = rbind(layout$layout_index, c(3, 4)) |
|
328 |
- } else { |
|
329 |
- .self$layout$layout_column_anno_bottom_height = annotation_height |
|
330 |
- .self$layout$layout_column_anno_top_height = unit(0, "null") |
|
331 |
- .self$layout$layout_index = rbind(layout$layout_index, c(7, 4)) |
|
332 |
- } |
|
333 |
- .self$layout$graphic_fun_list = c(layout$graphic_fun_list, function() .self$draw_annotation()) |
|
334 |
- } |
|
335 |
- |
|
336 |
- return(invisible(.self)) |
|
401 |
+ column_anno_side = match.arg(annotation_side)[1] |
|
402 |
+ if(is.null(annotation)) { |
|
403 |
+ .Object@layout$layout_column_anno_top_height = unit(0, "null") |
|
404 |
+ .Object@layout$layout_column_anno_bottom_height = unit(0, "null") |
|
405 |
+ } else { |
|
406 |
+ if(column_anno_side == "top") { |
|
407 |
+ .Object@layout$layout_column_anno_top_height = annotation_height |
|
408 |
+ .Object@layout$layout_column_anno_bottom_height = unit(0, "null") |
|
409 |
+ .Object@layout$layout_index = rbind(.Object@layout$layout_index, c(3, 4)) |
|
410 |
+ } else { |
|
411 |
+ .Object@layout$layout_column_anno_bottom_height = annotation_height |
|
412 |
+ .Object@layout$layout_column_anno_top_height = unit(0, "null") |
|
413 |
+ .Object@layout$layout_index = rbind(.Object@layout$layout_index, c(7, 4)) |
|
414 |
+ } |
|
415 |
+ .Object@layout$graphic_fun_list = c(.Object@layout$graphic_fun_list, function(object) draw_annotation(object)) |
|
416 |
+ } |
|
417 |
+ |
|
418 |
+ return(.Object) |
|
337 | 419 |
}) |
338 | 420 |
|
339 | 421 |
# show method is in fact a plot method |
340 |
-Heatmap$methods(show = function() { |
|
341 |
- cat("A Heatmap class instance:\n") |
|
342 |
- cat("name:", .self$name, "\n") |
|
343 |
- cat("dim:", nrow(.self$matrix), "x", ncol(.self$matrix), "\n") |
|
422 |
+setMethod(f = "show", |
|
423 |
+ signature = "Heatmap", |
|
424 |
+ definition = function(object) { |
|
425 |
+ |
|
426 |
+ cat("A Heatmap object:\n") |
|
427 |
+ cat("name:", object@name, "\n") |
|
428 |
+ cat("dim:", nrow(object@matrix), "x", ncol(object@matrix), "\n") |
|
429 |
+ |
|
344 | 430 |
}) |
345 | 431 |
|
346 |
-Heatmap$methods(add_heatmap = function(ht) { |
|
347 |
- ht_list = new("HeatmapList") |
|
348 |
- ht_list$add_heatmap(.self) |
|
349 |
- ht_list$add_heatmap(ht) |
|
432 |
+# == title |
|
433 |
+# add two heatmaps as a heatmap list |
|
434 |
+# |
|
435 |
+# == param |
|
436 |
+# -object a `Heatmap` object |
|
437 |
+# -ht a `Heatmap` object |
|
438 |
+# |
|
439 |
+# == value |
|
440 |
+# a `HeatmapList` object |
|
441 |
+# |
|
442 |
+# == author |
|
443 |
+# Zuguang Gu <z.gu@dkfz.de> |
|
444 |
+# |
|
445 |
+setMethod(f = "add_heatmap", |
|
446 |
+ signature = "Heatmap", |
|
447 |
+ definition = function(object, ht) { |
|
448 |
+ |
|
449 |
+ ht_list = new("HeatmapList") |
|
450 |
+ ht_list = add_heatmap(ht_list, object) |
|
451 |
+ ht_list = add_heatmap(ht_list, ht) |
|
452 |
+ return(ht_list) |
|
453 |
+ |
|
350 | 454 |
}) |
351 | 455 |
|
352 |
-# add the heatmap body |
|
353 |
-# 100% covered the viewport |
|
354 |
-Heatmap$methods(draw_heatmap_body = function(gp = .self$gp_list$rect_gp) { |
|
355 |
- pushViewport(viewport(name = paste(.self$name, "heatmap_body", sep = "-"))) |
|
356 |
- col_matrix = .self$matrix_color_mapping$map(.self$matrix) |
|
357 |
- |
|
358 |
- nc = ncol(.self$matrix) |
|
359 |
- nr = nrow(.self$matrix) |
|
360 |
- x = (seq_len(nc) - 0.5) / nc |
|
361 |
- y = (rev(seq_len(nr)) - 0.5) / nr |
|
362 |
- expand_index = expand.grid(seq_len(nr), seq_len(nc)) |
|
363 |
- grid.rect(x[expand_index[[2]]], y[expand_index[[1]]], width = 1/nc, height = 1/nr, gp = do.call("gpar", c(list(fill = col_matrix), gp))) |
|
364 |
- upViewport() |
|
456 |
+# == title |
|
457 |
+# plot the heatmap body |
|
458 |
+# |
|
459 |
+# == param |
|
460 |
+# -object a `Heatmap` object |
|
461 |
+# -gp graphic parameters for drawing rectangles |
|
462 |
+# |
|
463 |
+# == details |
|
464 |
+# the heatmap body 100% covers the viewport |
|
465 |
+# |
|
466 |
+# == value |
|
467 |
+# this function returns no value |
|
468 |
+# |
|
469 |
+# == author |
|
470 |
+# Zuguang Gu <z.gu@dkfz.de> |
|
471 |
+# |
|
472 |
+setMethod(f = "draw_heatmap_body", |
|
473 |
+ signature = "Heatmap", |
|
474 |
+ definition = function(object, gp = object@gp_list$rect_gp) { |
|
475 |
+ |
|
476 |
+ pushViewport(viewport(name = paste(object@name, "heatmap_body", sep = "-"))) |
|
477 |
+ col_matrix = map(object@matrix_color_mapping, object@matrix) |
|
478 |
+ |
|
479 |
+ nc = ncol(object@matrix) |
|
480 |
+ nr = nrow(object@matrix) |
|
481 |
+ x = (seq_len(nc) - 0.5) / nc |
|
482 |
+ y = (rev(seq_len(nr)) - 0.5) / nr |
|
483 |
+ expand_index = expand.grid(seq_len(nr), seq_len(nc)) |
|
484 |
+ grid.rect(x[expand_index[[2]]], y[expand_index[[1]]], width = 1/nc, height = 1/nr, gp = do.call("gpar", c(list(fill = col_matrix), gp))) |
|
485 |
+ upViewport() |
|
486 |
+ |
|
365 | 487 |
}) |
366 | 488 |
|
367 |
-# 100% percent to covert the whole viewport |
|
368 |
-Heatmap$methods(draw_hclust = function(which = c("row", "column"), |
|
369 |
- side = ifelse(which == "row", "left", "top"), gp = NULL) { |
|
370 |
- |
|
371 |
- which = match.arg(which)[1] |
|
372 |
- |
|
373 |
- side = side[1] |
|
374 |
- if(which == "row" && side %in% c("top", "bottom")) { |
|
375 |
- stop("`side` can only be set to 'left' or 'right' if `which` is 'row'.") |
|
376 |
- } |
|
377 |
- |
|
378 |
- if(which == "column" && side %in% c("left", "right")) { |
|
379 |
- stop("`side` can only be set to 'top' or 'bottom' if `which` is 'column'.") |
|
380 |
- } |
|
381 |
- |
|
382 |
- hc = switch(which, |
|
383 |
- "row" = .self$row_hclust, |
|
384 |
- "column" = .self$column_hclust) |
|
385 |
- |
|
386 |
- if(is.null(gp)) { |
|
387 |
- gp = switch(which, |
|
388 |
- "row" = .self$gp_list$row_hclust_gp, |
|
389 |
- "column" = .self$gp_list$column_hclust_gp) |
|
390 |
- } |
|
391 |
- |
|
392 |
- if(is.null(hc)) { |
|
393 |
- return(invisible(NULL)) |
|
394 |
- } |
|
395 |
- |
|
396 |
- h = hc$height / max(hc$height) |
|
397 |
- m = hc$merge |
|
398 |
- o = hc$order |
|
399 |
- n = length(o) |
|
400 |
- |
|
401 |
- m[m > 0] = n + m[m > 0] |
|
402 |
- m[m < 0] = abs(m[m < 0]) |
|
403 |
- |
|
404 |
- dist = matrix(0, nrow = 2 * n - 1, ncol = 2, dimnames = list(NULL, c("x", "y"))) |
|
405 |
- dist[1:n, 1] = 1 / n / 2 + (1 / n) * (match(1:n, o) - 1) |
|
406 |
- |
|
407 |
- for(i in 1:nrow(m)){ |
|
408 |
- dist[n + i, 1] = (dist[m[i, 1], 1] + dist[m[i, 2], 1]) / 2 |
|
409 |
- dist[n + i, 2] = h[i] |
|
410 |
- } |
|
411 |
- |
|
412 |
- draw_connection = function(x1, x2, y1, y2, y, horizontal = FALSE, gp = gpar()){ |
|
413 |
- |
|
414 |
- if(horizontal) { |
|
415 |
- grid.lines(y = c(x1, x1), x = c(y1, y), gp = gp) |
|
416 |
- grid.lines(y = c(x2, x2), x = c(y2, y), gp = gp) |
|
417 |
- grid.lines(y = c(x1, x2), x = c(y, y), gp = gp) |
|
418 |
- } else { |
|
419 |
- grid.lines(x = c(x1, x1), y = c(y1, y), gp = gp) |
|
420 |
- grid.lines(x = c(x2, x2), y = c(y2, y), gp = gp) |
|
421 |
- grid.lines(x = c(x1, x2), y = c(y, y), gp = gp) |
|
422 |
- } |
|
423 |
- } |
|
424 |
- |
|
425 |
- if(which == "row" && side == "right") { |
|
426 |
- #dist[, 1] = 1 - dist[, 1] |
|
427 |
- } else if(which == "row" && side == "left") { |
|
428 |
- #dist[, 1] = 1 - dist[, 1] |
|
429 |
- dist[, 2] = 1 - dist[, 2] |
|
430 |
- h = 1 - h |
|
431 |
- } else if(which == "column" && side == "bottom") { |
|
432 |
- dist[, 2] = 1 - dist[, 2] |
|
433 |
- h = 1 - h |
|
434 |
- } |
|
435 |
- |
|
436 |
- if(which == "row") { |
|
437 |
- pushViewport(viewport(name = paste(.self$name, "hclust_row", sep = "-") )) |
|
438 |
- for(i in 1:nrow(m)){ |
|
439 |
- draw_connection(dist[m[i, 1], 1], dist[m[i, 2], 1], dist[m[i, 1], 2], dist[m[i, 2], 2], h[i], horizontal = TRUE, gp = gp) |
|
440 |
- } |
|
441 |
- } else { |
|
442 |
- pushViewport(viewport(name = paste(.self$name, "hclust_col", sep = "-") )) |
|
443 |
- for(i in 1:nrow(m)){ |
|
444 |
- draw_connection(dist[m[i, 1], 1], dist[m[i, 2], 1], dist[m[i, 1], 2], dist[m[i, 2], 2], h[i], horizontal = FALSE, gp = gp) |
|
445 |
- } |
|
446 |
- } |
|
447 |
- |
|
448 |
- upViewport() |
|
489 |
+# == title |
|
490 |
+# plot the dendrogram on rows or columns |
|
491 |
+# |
|
492 |
+# == param |
|
493 |
+# -object a `Heatmap` object |
|
494 |
+# -which the dendrogram should be plotted on rows or columns |
|
495 |
+# -side side of the dendrogram |
|
496 |
+# -gp graphic parameters for drawing lines |
|
497 |
+# |
|
498 |
+# == details |
|
499 |
+# the dendrogram 100% covers the viewport |
|
500 |
+# |
|
501 |
+# == value |
|
502 |
+# this function returns no value |
|
503 |
+# |
|
504 |
+# == author |
|
505 |
+# Zuguang Gu <z.gu@dkfz.de> |
|
506 |
+# |
|
507 |
+setMethod(f = "draw_hclust", |
|
508 |
+ signature = "Heatmap", |
|
509 |
+ definition = function(object, which = c("row", "column"), |
|
510 |
+ side = ifelse(which == "row", "left", "top"), gp = NULL) { |
|
511 |
+ |
|
512 |
+ which = match.arg(which)[1] |
|
513 |
+ |
|
514 |
+ side = side[1] |
|
515 |
+ if(which == "row" && side %in% c("top", "bottom")) { |
|
516 |
+ stop("`side` can only be set to 'left' or 'right' if `which` is 'row'.") |
|
517 |
+ } |
|
518 |
+ |
|
519 |
+ if(which == "column" && side %in% c("left", "right")) { |
|
520 |
+ stop("`side` can only be set to 'top' or 'bottom' if `which` is 'column'.") |
|
521 |
+ } |
|
522 |
+ |
|
523 |
+ hc = switch(which, |
|
524 |
+ "row" = object@row_hclust, |
|
525 |
+ "column" = object@column_hclust) |
|
526 |
+ |
|
527 |
+ if(is.null(gp)) { |
|
528 |
+ gp = switch(which, |
|
529 |
+ "row" = object@gp_list$row_hclust_gp, |
|
530 |
+ "column" = object@gp_list$column_hclust_gp) |
|
531 |
+ } |
|
532 |
+ |
|
533 |
+ if(is.null(hc)) { |
|
534 |
+ return(invisible(NULL)) |
|
535 |
+ } |
|
536 |
+ |
|
537 |
+ h = hc$height / max(hc$height) |
|
538 |
+ m = hc$merge |
|
539 |
+ o = hc$order |
|
540 |
+ n = length(o) |
|
541 |
+ |
|
542 |
+ m[m > 0] = n + m[m > 0] |
|
543 |
+ m[m < 0] = abs(m[m < 0]) |
|
544 |
+ |
|
545 |
+ dist = matrix(0, nrow = 2 * n - 1, ncol = 2, dimnames = list(NULL, c("x", "y"))) |
|
546 |
+ dist[1:n, 1] = 1 / n / 2 + (1 / n) * (match(1:n, o) - 1) |
|
547 |
+ |
|
548 |
+ for(i in 1:nrow(m)){ |
|
549 |
+ dist[n + i, 1] = (dist[m[i, 1], 1] + dist[m[i, 2], 1]) / 2 |
|
550 |
+ dist[n + i, 2] = h[i] |
|
551 |
+ } |
|
552 |
+ |
|
553 |
+ draw_connection = function(x1, x2, y1, y2, y, horizontal = FALSE, gp = gpar()){ |
|
554 |
+ |
|
555 |
+ if(horizontal) { |
|
556 |
+ grid.lines(y = c(x1, x1), x = c(y1, y), gp = gp) |
|
557 |
+ grid.lines(y = c(x2, x2), x = c(y2, y), gp = gp) |
|
558 |
+ grid.lines(y = c(x1, x2), x = c(y, y), gp = gp) |
|
559 |
+ } else { |
|
560 |
+ grid.lines(x = c(x1, x1), y = c(y1, y), gp = gp) |
|
561 |
+ grid.lines(x = c(x2, x2), y = c(y2, y), gp = gp) |
|
562 |
+ grid.lines(x = c(x1, x2), y = c(y, y), gp = gp) |
|
563 |
+ } |
|
564 |
+ } |
|
565 |
+ |
|
566 |
+ if(which == "row" && side == "right") { |
|
567 |
+ #dist[, 1] = 1 - dist[, 1] |
|
568 |
+ } else if(which == "row" && side == "left") { |
|
569 |
+ #dist[, 1] = 1 - dist[, 1] |
|
570 |
+ dist[, 2] = 1 - dist[, 2] |
|
571 |
+ h = 1 - h |
|
572 |
+ } else if(which == "column" && side == "bottom") { |
|
573 |
+ dist[, 2] = 1 - dist[, 2] |
|
574 |
+ h = 1 - h |
|
575 |
+ } |
|
576 |
+ |
|
577 |
+ if(which == "row") { |
|
578 |
+ pushViewport(viewport(name = paste(object@name, "hclust_row", sep = "-") )) |
|
579 |
+ for(i in 1:nrow(m)){ |
|
580 |
+ draw_connection(dist[m[i, 1], 1], dist[m[i, 2], 1], dist[m[i, 1], 2], dist[m[i, 2], 2], h[i], horizontal = TRUE, gp = gp) |
|
581 |
+ } |
|
582 |
+ } else { |
|
583 |
+ pushViewport(viewport(name = paste(object@name, "hclust_col", sep = "-") )) |
|
584 |
+ for(i in 1:nrow(m)){ |
|
585 |
+ draw_connection(dist[m[i, 1], 1], dist[m[i, 2], 1], dist[m[i, 1], 2], dist[m[i, 2], 2], h[i], horizontal = FALSE, gp = gp) |
|
586 |
+ } |
|
587 |
+ } |
|
588 |
+ |
|
589 |
+ upViewport() |
|
449 | 590 |
}) |
450 | 591 |
|
451 |
-# width is fixed |
|
452 |
-Heatmap$methods(draw_dimnames = function(which = c("row", "column"), |
|
453 |
- side = ifelse(which == "row", "right", "bottom"), gp = NULL) { |
|
454 |
- |
|
455 |
- which = match.arg(which)[1] |
|
456 |
- |
|
457 |
- side = side[1] |
|
458 |
- if(which == "row" && side %in% c("bottom", "top")) { |
|
459 |
- stop("`side` can only be set to 'left' or 'right' if `which` is 'row'.") |
|
460 |
- } |
|
461 |
- |
|
462 |
- if(which == "column" && side %in% c("left", "right")) { |
|
463 |
- stop("`side` can only be set to 'top' or 'bottom' if `which` is 'column'.") |
|
464 |
- } |
|
465 |
- |
|
466 |
- nm = switch(which, |
|
467 |
- "row" = rownames(.self$matrix), |
|
468 |
- "column" = colnames(.self$matrix)) |
|
469 |
- |
|
470 |
- if(is.null(gp)) { |
|
471 |
- gp = switch(which, |
|
472 |
- "row" = .self$gp_list$row_hclust_gp, |
|
473 |
- "column" = .self$gp_list$column_hclust_gp) |
|
474 |
- } |
|
475 |
- |
|
476 |
- if(is.null(nm)) { |
|
477 |
- return(invisible(NULL)) |
|
478 |
- } |
|
479 |
- |
|
480 |
- n = length(nm) |
|
481 |
- |
|
482 |
- if(which == "row") { |
|
483 |
- pushViewport(viewport(name = paste(.self$name, "rownames", sep = "-") )) |
|
484 |
- if(side == "left") { |
|
485 |
- x = unit(1, "npc") - unit(2, "mm") |
|
486 |
- just = c("right", "center") |
|
487 |
- } else { |
|