Mercurial > repos > artbio > ngsplot
comparison lib/plotlib.r @ 0:3ca58369469c draft
planemo upload for repository https://github.com/ARTbio/tools-artbio/tree/master/tools/ngsplot commit b'e9fcc157a7f2f2fa9d6ac9a58d425ff17c975f5c\n'
author | artbio |
---|---|
date | Wed, 06 Dec 2017 19:01:53 -0500 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:3ca58369469c |
---|---|
1 #### plotlib.r #### | |
2 # This contains the library for plotting related functions. | |
3 # | |
4 # Authors: Li Shen, Ningyi Shao | |
5 # | |
6 # Created: Feb 19, 2013 | |
7 # Last updated: May 21, 2013 | |
8 # | |
9 | |
10 SetupHeatmapDevice <- function(reg.list, uniq.reg, ng.list, pts, font.size=12, | |
11 unit.width=4, reduce.ratio=30) { | |
12 # Configure parameters for heatmap output device. The output is used by | |
13 # external procedures to setup pdf device ready for heatmap plotting. | |
14 # Args: | |
15 # reg.list: region list as in config file. | |
16 # uniq.reg: unique region list. | |
17 # ng.list: number of genes per heatmap in the order as config file. | |
18 # pts: data points (number of columns of heatmaps). | |
19 # font.size: font size. | |
20 # unit.width: image width per heatmap. | |
21 # reduce.ratio: how compressed are genes in comparison to data points? This | |
22 # controls image height. | |
23 | |
24 # Number of plots per region. | |
25 reg.np <- sapply(uniq.reg, function(r) sum(reg.list==r)) | |
26 | |
27 # Number of genes per region. | |
28 reg.ng <- sapply(uniq.reg, function(r) { | |
29 ri <- which(reg.list==r)[1] | |
30 ng.list[ri] | |
31 }) | |
32 | |
33 # Adjustment ratio. | |
34 origin.fs <- 12 # default font size. | |
35 fs.adj.ratio <- font.size / origin.fs | |
36 # Margin size (in lines) adjusted by ratio. | |
37 m.bot <- fs.adj.ratio * 2 | |
38 m.lef <- fs.adj.ratio * 1.5 | |
39 m.top <- fs.adj.ratio * 2 | |
40 m.rig <- fs.adj.ratio * 1.5 | |
41 key.in <- fs.adj.ratio * 1.0 # colorkey in inches. | |
42 m.lef.diff <- (fs.adj.ratio - 1) * 1.5 | |
43 m.rig.diff <- (fs.adj.ratio - 1) * 1.5 | |
44 # Setup image size. | |
45 hm.width <- (unit.width + m.lef.diff + m.rig.diff) * max(reg.np) | |
46 ipl <- .2 # inches per line. Obtained from par->'mai', 'mar'. | |
47 # Convert #gene to image height. | |
48 reg.hei <- sapply(reg.ng, function(r) { | |
49 c(key.in, # colorkey + margin. | |
50 r * unit.width / pts / reduce.ratio + | |
51 m.bot * ipl + m.top * ipl) # heatmap + margin. | |
52 }) | |
53 reg.hei <- c(reg.hei) | |
54 hm.height <- sum(reg.hei) | |
55 | |
56 # Setup layout of the heatmaps. | |
57 lay.mat <- matrix(0, ncol=max(reg.np), nrow=length(reg.np) * 2) | |
58 fig.n <- 1 # figure plotting number. | |
59 for(i in 1:length(reg.np)) { | |
60 row.upper <- i * 2 - 1 | |
61 row.lower <- i * 2 | |
62 for(j in 1:reg.np[i]) { | |
63 lay.mat[row.upper, j] <- fig.n; | |
64 fig.n <- fig.n + 1 | |
65 lay.mat[row.lower, j] <- fig.n; | |
66 fig.n <- fig.n + 1 | |
67 } | |
68 } | |
69 | |
70 list(reg.hei=reg.hei, hm.width=hm.width, hm.height=hm.height, | |
71 lay.mat=lay.mat, heatmap.mar=c(m.bot, m.lef, m.top, m.rig) * ipl) | |
72 } | |
73 | |
74 SetPtsSpline <- function(pint, lgint) { | |
75 # Set data points for spline function. | |
76 # Args: | |
77 # pint: tag for point interval. | |
78 # Return: list of data points, middle data points, flanking data points. | |
79 | |
80 pts <- 100 # data points to plot: 0...pts | |
81 if(pint){ # point interval. | |
82 m.pts <- 1 # middle part points. | |
83 f.pts <- pts / 2 # flanking part points. | |
84 } else { | |
85 if(lgint) { | |
86 m.pts <- pts / 5 * 3 + 1 | |
87 f.pts <- pts / 5 + 1 | |
88 } else { | |
89 m.pts <- pts / 5 + 1 | |
90 f.pts <- pts / 5 * 2 + 1 | |
91 } | |
92 } | |
93 list(pts=pts, m.pts=m.pts, f.pts=f.pts) | |
94 } | |
95 | |
96 CreatePlotMat <- function(pts, ctg.tbl) { | |
97 # Create matrix for avg. profiles. | |
98 # Args: | |
99 # pts: data points. | |
100 # ctg.tbl: configuration table. | |
101 # Return: avg. profile matrix initialized to zero. | |
102 | |
103 regcovMat <- matrix(0, nrow=pts + 1, ncol=nrow(ctg.tbl)) | |
104 colnames(regcovMat) <- ctg.tbl$title | |
105 regcovMat | |
106 } | |
107 | |
108 CreateConfiMat <- function(se, pts, ctg.tbl){ | |
109 # Create matrix for standard errors. | |
110 # Args: | |
111 # se: tag for standard error plotting. | |
112 # pts: data points. | |
113 # ctg.tbl: configuration table. | |
114 # Return: standard error matrix initialized to zero or null. | |
115 | |
116 if(se){ | |
117 confiMat <- matrix(0, nrow=pts + 1, ncol=nrow(ctg.tbl)) | |
118 colnames(confiMat) <- ctg.tbl$title | |
119 } else { | |
120 confiMat <- NULL | |
121 } | |
122 confiMat | |
123 } | |
124 | |
125 col2alpha <- function(col2use, alpha){ | |
126 # Convert a vector of solid colors to semi-transparent colors. | |
127 # Args: | |
128 # col2use: vector of colors. | |
129 # alpha: represents degree of opacity - [0,1] | |
130 # Return: vector of transformed colors. | |
131 | |
132 apply(col2rgb(col2use), 2, function(x){ | |
133 rgb(x[1], x[2], x[3], alpha=alpha*255, maxColorValue=255) | |
134 }) | |
135 } | |
136 | |
137 smoothvec <- function(v, radius, method=c('mean', 'median')){ | |
138 # Given a vector of coverage, return smoothed version of coverage. | |
139 # Args: | |
140 # v: vector of coverage | |
141 # radius: fraction of org. vector size. | |
142 # method: smooth method | |
143 # Return: vector of smoothed coverage. | |
144 | |
145 stopifnot(is.vector(v)) | |
146 stopifnot(length(v) > 0) | |
147 stopifnot(radius > 0 && radius < 1) | |
148 | |
149 halfwin <- ceiling(length(v) * radius) | |
150 s <- rep(NA, length(v)) | |
151 | |
152 for(i in 1:length(v)){ | |
153 winpos <- (i - halfwin) : (i + halfwin) | |
154 winpos <- winpos[winpos > 0 & winpos <= length(v)] | |
155 if(method == 'mean'){ | |
156 s[i] <- mean(v[winpos]) | |
157 }else if(method == 'median'){ | |
158 s[i] <- median(v[winpos]) | |
159 } | |
160 } | |
161 s | |
162 } | |
163 | |
164 smoothplot <- function(m, radius, method=c('mean', 'median')){ | |
165 # Smooth the entire avg. profile matrix using smoothvec. | |
166 # Args: | |
167 # m: avg. profile matrix | |
168 # radius: fraction of org. vector size. | |
169 # method: smooth method. | |
170 # Return: smoothed matrix. | |
171 | |
172 stopifnot(is.matrix(m) || is.vector(m)) | |
173 | |
174 if(is.matrix(m)) { | |
175 for(i in 1:ncol(m)) { | |
176 m[, i] <- smoothvec(m[, i], radius, method) | |
177 } | |
178 } else { | |
179 m <- smoothvec(m, radius, method) | |
180 } | |
181 m | |
182 } | |
183 | |
184 genXticks <- function(reg2plot, pint, lgint, pts, flanksize, flankfactor, | |
185 Labs) { | |
186 # Generate X-ticks for plotting. | |
187 # Args: | |
188 # reg2plot: string representation of region. | |
189 # pint: point interval. | |
190 # lgint: tag for large interval. | |
191 # pts: data points. | |
192 # flanksize: flanking region size in bps. | |
193 # flankfactor: flanking region factor. | |
194 # Labs: character vector of labels of the genomic region. | |
195 # Return: list of x-tick position and label. | |
196 | |
197 if(pint){ # point interval. | |
198 mid.lab <- Labs[1] | |
199 tick.pos <- c(0, pts / 4, pts / 2, pts / 4 * 3, pts) | |
200 tick.lab <- as.character(c(-flanksize, -flanksize/2, mid.lab, | |
201 flanksize/2, flanksize)) | |
202 }else{ | |
203 left.lab <- Labs[1] | |
204 right.lab <- Labs[2] | |
205 tick.pos <- c(0, pts / 5, pts / 5 * 2, pts / 5 * 3, pts / 5 * 4, pts) | |
206 if(lgint){ # large interval: fla int int int fla | |
207 if(flankfactor > 0){ # show percentage at x-tick. | |
208 tick.lab <- c(sprintf("%d%%", -flankfactor*100), | |
209 left.lab, '33%', '66%', right.lab, | |
210 sprintf("%d%%", flankfactor*100)) | |
211 } else{ # show bps at x-tick. | |
212 tick.lab <- c(as.character(-flanksize), | |
213 left.lab, '33%', '66%', right.lab, | |
214 as.character(flanksize)) | |
215 } | |
216 } else { # small interval: fla fla int fla fla. | |
217 if(flankfactor > 0){ | |
218 tick.lab <- c(sprintf("%d%%", -flankfactor*100), | |
219 sprintf("%d%%", -flankfactor*50), | |
220 left.lab, right.lab, | |
221 sprintf("%d%%", flankfactor*50), | |
222 sprintf("%d%%", flankfactor*100)) | |
223 } else { | |
224 tick.lab <- c(as.character(-flanksize), | |
225 as.character(-flanksize/2), | |
226 left.lab, right.lab, | |
227 as.character(flanksize/2), | |
228 as.character(flanksize)) | |
229 } | |
230 } | |
231 } | |
232 list(pos=tick.pos, lab=tick.lab) | |
233 } | |
234 | |
235 plotmat <- function(regcovMat, title2plot, plot.colors, bam.pair, xticks, | |
236 pts, m.pts, f.pts, pint, shade.alp=0, confiMat=NULL, mw=1, | |
237 misc.options=list(yscale='auto', legend=T, box=T, vline=T, | |
238 xylab=T, line.wd=3)) { | |
239 # Plot avg. profiles and standard errors around them. | |
240 # Args: | |
241 # regcovMat: matrix for avg. profiles. | |
242 # title2plot: profile names, will be shown in figure legend. | |
243 # plot.colors: vector of color specifications for all curves. | |
244 # bam.pair: boolean for bam-pair data. | |
245 # xticks: X-axis ticks. | |
246 # pts: data points | |
247 # m.pts: middle part data points | |
248 # f.pts: flanking part data points | |
249 # pint: tag for point interval | |
250 # shade.alp: shading area alpha | |
251 # confiMat: matrix for standard errors. | |
252 # mw: moving window size for smoothing function. | |
253 # misc.options: list of misc. options - y-axis scale, legend, box around plot, | |
254 # verticle lines, X- and Y-axis labels, line width. | |
255 | |
256 # Smooth avg. profiles if specified. | |
257 if(mw > 1){ | |
258 regcovMat <- as.matrix(runmean(regcovMat, k=mw, alg='C', | |
259 endrule='mean')) | |
260 } | |
261 | |
262 # Choose colors. | |
263 if(any(is.na(plot.colors))) { | |
264 ncurve <- ncol(regcovMat) | |
265 if(ncurve <= 8) { | |
266 suppressMessages(require(RColorBrewer, warn.conflicts=F)) | |
267 col2use <- brewer.pal(ifelse(ncurve >= 3, ncurve, 3), 'Dark2') | |
268 col2use <- col2use[1:ncurve] | |
269 } else { | |
270 col2use <- rainbow(ncurve) | |
271 } | |
272 } else { | |
273 col2use <- plot.colors | |
274 } | |
275 col2use <- col2alpha(col2use, 0.8) | |
276 | |
277 # Plot profiles. | |
278 ytext <- ifelse(bam.pair, "log2(Fold change vs. control)", | |
279 "Read count Per Million mapped reads") | |
280 xrange <- 0:pts | |
281 y.lim <- NULL | |
282 if(length(misc.options$yscale) == 2) { | |
283 y.lim <- misc.options$yscale | |
284 } | |
285 matplot(xrange, regcovMat, | |
286 xaxt='n', type="l", col=col2use, ylim=y.lim, | |
287 lty="solid", lwd=misc.options$line.wd, frame.plot=F, ann=F) | |
288 if(misc.options$xylab) { | |
289 title(xlab="Genomic Region (5' -> 3')", ylab=ytext) | |
290 } | |
291 axis(1, at=xticks$pos, labels=xticks$lab, lwd=3, lwd.ticks=3) | |
292 if(misc.options$box) { | |
293 # box around plot. | |
294 box() | |
295 } | |
296 | |
297 # Add shade area. | |
298 if(shade.alp > 0){ | |
299 for(i in 1:ncol(regcovMat)){ | |
300 v.x <- c(xrange[1], xrange, xrange[length(xrange)]) | |
301 v.y <- regcovMat[, i] | |
302 v.y <- c(0, v.y, 0) | |
303 col.rgb <- col2rgb(col2use[i]) | |
304 p.col <- rgb(col.rgb[1, 1], col.rgb[2, 1], col.rgb[3, 1], | |
305 alpha=shade.alp * 255, maxColorValue=255) | |
306 polygon(v.x, v.y, density=-1, border=NA, col=p.col) | |
307 } | |
308 } | |
309 | |
310 # Add standard errors. | |
311 if(!is.null(confiMat)){ | |
312 v.x <- c(xrange, rev(xrange)) | |
313 for(i in 1:ncol(confiMat)){ | |
314 v.y <- c(regcovMat[, i] + confiMat[, i], | |
315 rev(regcovMat[, i] - confiMat[, i])) | |
316 col.rgb <- col2rgb(col2use[i]) | |
317 p.col <- rgb(col.rgb[1, 1], col.rgb[2, 1], col.rgb[3, 1], | |
318 alpha=0.2 * 255, maxColorValue=255) | |
319 polygon(v.x, v.y, density=-1, border=NA, col=p.col) | |
320 } | |
321 } | |
322 | |
323 if(misc.options$vline) { | |
324 # Add gray lines indicating feature boundaries. | |
325 if(pint) { | |
326 abline(v=f.pts, col="gray", lwd=2) | |
327 } else { | |
328 abline(v=f.pts - 1, col="gray", lwd=2) | |
329 abline(v=f.pts + m.pts - 2, col="gray", lwd=2) | |
330 } | |
331 } | |
332 | |
333 if(misc.options$legend) { | |
334 # Legend. | |
335 legend("topright", title2plot, text.col=col2use) | |
336 } | |
337 } | |
338 | |
339 spline_mat <- function(mat, n=100){ | |
340 # Calculate splined coverage for a matrix. | |
341 # Args: | |
342 # mat: each column represents a profile to be interpolated. | |
343 # n: number of data points to be interpolated. | |
344 | |
345 foreach(r=iter(mat, by='row'), | |
346 .combine='rbind', .multicombine=T) %dopar% { | |
347 spline(1:length(r), r, n)$y | |
348 } | |
349 } | |
350 | |
351 RankNormalizeMatrix <- function(mat, low.cutoff) { | |
352 # Rank-based normalization for a data matrix. | |
353 # Args: | |
354 # mat: data matrix. | |
355 # low.cutoff: low value cutoff. | |
356 # Return: rank normalized matrix. | |
357 | |
358 stopifnot(is.matrix(mat)) | |
359 | |
360 concat.dat <- c(mat) | |
361 low.mask <- concat.dat < low.cutoff | |
362 concat.r <- rank(concat.dat) | |
363 concat.r[low.mask] <- 0 | |
364 | |
365 matrix(concat.r, nrow=nrow(mat)) | |
366 } | |
367 | |
368 OrderGenesHeatmap <- function(enrichList, lowCutoffs, | |
369 method=c('total', 'max', 'prod', 'diff', 'hc', | |
370 'none', 'km'), | |
371 go.paras=list(knc=5, max.iter=20, nrs=30)) { | |
372 # Order genes with a list of heatmap data. | |
373 # Args: | |
374 # enrichList: heatmap data in a list. | |
375 # lowCutoffs: low count cutoff for normalized count data. | |
376 # method: algorithm used to order genes. | |
377 # go.paras: gene ordering parameters. | |
378 # Returns: a vector of REVERSED gene orders. | |
379 # NOTE: due to the design of image function, the order needs to be reversed | |
380 # so that the genes will be shown correctly. | |
381 | |
382 rankList <- mapply(RankNormalizeMatrix, | |
383 mat=enrichList, low.cutoff=lowCutoffs, SIMPLIFY=F) | |
384 np <- length(enrichList) | |
385 | |
386 if(method == 'hc') { | |
387 rankCombined <- do.call('cbind', rankList) | |
388 # Clustering and order genes. | |
389 hc <- hclust(dist(rankCombined, method='euclidean'), | |
390 method='complete') | |
391 memb <- cutree(hc, k = go.paras$knc) | |
392 list(rev(hc$order), memb) # reversed! | |
393 } else if(method == 'km') { | |
394 rankCombined <- do.call('cbind', rankList) | |
395 km <- kmeans(rankCombined, centers=go.paras$knc, | |
396 iter.max=go.paras$max.iter, nstart=go.paras$nrs) | |
397 list(rev(order(km$cluster)), km$cluster) # reversed! | |
398 } else if(method == 'total' || method == 'diff' && np == 1) { | |
399 list(order(rowSums(rankList[[1]])), NULL) | |
400 } else if(method == 'max') { # peak enrichment value of the 1st profile. | |
401 list(order(apply(rankList[[1]], 1, max)), NULL) | |
402 } else if(method == 'prod') { # product of all profiles. | |
403 rs.mat <- sapply(rankList, rowSums) | |
404 g.prod <- apply(rs.mat, 1, prod) | |
405 list(order(g.prod), NULL) | |
406 } else if(method == 'diff' && np > 1) { # difference between 2 profiles. | |
407 list(order(rowSums(rankList[[1]]) - rowSums(rankList[[2]])), NULL) | |
408 } else if(method == 'none') { # according to the order of input gene list. | |
409 # Because the image function draws from bottom to top, the rows are | |
410 # reversed to give a more natural look. | |
411 list(rev(1:nrow(enrichList[[1]])),NULL) | |
412 } else { | |
413 # pass. | |
414 } | |
415 } | |
416 | |
417 | |
418 plotheat <- function(reg.list, uniq.reg, enrichList, v.low.cutoff, go.algo, | |
419 go.paras, title2plot, bam.pair, xticks, flood.q=.02, | |
420 do.plot=T, hm.color="default", color.distr=.6, | |
421 color.scale='local') { | |
422 # Plot heatmaps with genes ordered according to some algorithm. | |
423 # Args: | |
424 # reg.list: factor vector of regions as in configuration. | |
425 # uniq.reg: character vector of unique regions. | |
426 # enrichList: list of heatmap data. | |
427 # v.low.cutoff: low count cutoff for normalized count data. | |
428 # go.algo: gene order algorithm. | |
429 # go.paras: gene ordering parameters. | |
430 # title2plot: title for each heatmap. Same as the legends in avgprof. | |
431 # bam.pair: boolean tag for bam-pair. | |
432 # xticks: info for X-axis ticks. | |
433 # flood.q: flooding percentage. | |
434 # do.plot: boolean tag for plotting heatmaps. | |
435 # hm.color: string for heatmap colors. | |
436 # color.distr: positive number for color distribution. | |
437 # color.scale: string for the method to adjust color scale. | |
438 # Returns: ordered gene names for each unique region as a list. | |
439 | |
440 # Setup basic parameters. | |
441 ncolor <- 256 | |
442 if(bam.pair) { | |
443 if(hm.color != "default") { | |
444 tri.colors <- unlist(strsplit(hm.color, ':')) | |
445 neg.color <- tri.colors[1] | |
446 if(length(tri.colors) == 2) { | |
447 neu.color <- 'black' | |
448 pos.color <- tri.colors[2] | |
449 } else { | |
450 neu.color <- tri.colors[2] | |
451 pos.color <- tri.colors[3] | |
452 } | |
453 enrich.palette <- colorRampPalette(c(neg.color, neu.color, | |
454 pos.color), | |
455 bias=color.distr, | |
456 interpolate='spline') | |
457 } else { | |
458 enrich.palette <- colorRampPalette(c('blue', 'black', 'yellow'), | |
459 bias=color.distr, | |
460 interpolate='spline') | |
461 } | |
462 } else { | |
463 if(hm.color != "default") { | |
464 enrich.palette <- colorRampPalette(c('snow', hm.color)) | |
465 } else { | |
466 enrich.palette <- colorRampPalette(c('snow', 'red2')) | |
467 } | |
468 } | |
469 | |
470 hm_cols <- ncol(enrichList[[1]]) | |
471 | |
472 # Adjust X-axis tick position. In a heatmap, X-axis is [0, 1]. | |
473 # Assume xticks$pos is from 0 to N(>0). | |
474 xticks$pos <- xticks$pos / tail(xticks$pos, n=1) # scale to the same size. | |
475 | |
476 # Define a function to calculate color breaks. | |
477 ColorBreaks <- function(max.e, min.e, bam.pair, ncolor) { | |
478 # Args: | |
479 # max.e: maximum enrichment value to be mapped to color. | |
480 # min.e: minimum enrichment value to be mapped to color. | |
481 # bam.pair: boolean tag for bam-pair. | |
482 # ncolor: number of colors to use. | |
483 # Returns: vector of color breaks. | |
484 | |
485 # If bam-pair is used, create breaks for positives and negatives | |
486 # separately. If log2 ratios are all positive or negative, use only | |
487 # half of the color space. | |
488 if(bam.pair) { | |
489 max.e <- ifelse(max.e > 0, max.e, 1) | |
490 min.e <- ifelse(min.e < 0, min.e, -1) | |
491 c(seq(min.e, 0, length.out=ncolor / 2 + 1), | |
492 seq(0, max.e, length.out=ncolor / 2 + 1)[-1]) | |
493 } else { | |
494 seq(min.e, max.e, length.out=ncolor + 1) | |
495 } | |
496 } | |
497 | |
498 if(grepl(",", color.scale)) { | |
499 scale.pair <- unlist(strsplit(color.scale, ",")) | |
500 scale.min <- as.numeric(scale.pair[1]) | |
501 scale.max <- as.numeric(scale.pair[2]) | |
502 if(scale.min >= scale.max) { | |
503 warning("Color scale min value is >= max value.\n") | |
504 } | |
505 flood.pts <- c(scale.min, scale.max) | |
506 brk.use <- ColorBreaks(scale.max, scale.min, bam.pair, ncolor) | |
507 } | |
508 | |
509 # If color scale is global, calculate breaks and quantile here. | |
510 if(color.scale == 'global') { | |
511 flood.pts <- quantile(c(enrichList, recursive=T), c(flood.q, 1-flood.q)) | |
512 brk.use <- ColorBreaks(flood.pts[2], flood.pts[1], bam.pair, ncolor) | |
513 } | |
514 | |
515 # Go through each unique region. | |
516 # Do NOT use "dopar" in the "foreach" loops here because this will disturb | |
517 # the image order. | |
518 go.list <- vector('list', length(uniq.reg)) | |
519 go.cluster <- vector('list', length(uniq.reg)) | |
520 | |
521 names(go.list) <- uniq.reg | |
522 names(go.cluster) <- uniq.reg | |
523 | |
524 for(ur in uniq.reg) { | |
525 # ur <- uniq.reg[i] | |
526 plist <- which(reg.list==ur) # get indices in the config file. | |
527 | |
528 # Combine all profiles into one. | |
529 # enrichCombined <- do.call('cbind', enrichList[plist]) | |
530 enrichSelected <- enrichList[plist] | |
531 | |
532 # If color scale is region, calculate breaks and quantile here. | |
533 if(color.scale == 'region') { | |
534 flood.pts <- quantile(c(enrichSelected, recursive=T), | |
535 c(flood.q, 1-flood.q)) | |
536 brk.use <- ColorBreaks(flood.pts[2], flood.pts[1], bam.pair, ncolor) | |
537 } | |
538 | |
539 # Order genes. | |
540 if(is.matrix(enrichSelected[[1]]) && nrow(enrichSelected[[1]]) > 1) { | |
541 if(bam.pair) { | |
542 lowCutoffs <- 0 | |
543 } else { | |
544 lowCutoffs <- v.low.cutoff[plist] | |
545 } | |
546 g.order.list <- OrderGenesHeatmap(enrichSelected, lowCutoffs, | |
547 go.algo, go.paras) | |
548 g.order <- g.order.list[[1]] | |
549 g.cluster <- g.order.list[[2]] | |
550 if(is.null(g.cluster)) { | |
551 go.cluster[[ur]] <- NA | |
552 } else{ | |
553 go.cluster[[ur]] <- rev(g.cluster[g.order]) | |
554 } | |
555 go.list[[ur]] <- rev(rownames(enrichSelected[[1]][g.order, ])) | |
556 } else { | |
557 go.cluster[[ur]] <- NULL | |
558 go.list[[ur]] <- NULL | |
559 } | |
560 | |
561 if(!do.plot) { | |
562 next | |
563 } | |
564 | |
565 # Go through each sample and do plot. | |
566 for(pj in plist) { | |
567 if(!is.null(g.order)) { | |
568 enrichList[[pj]] <- enrichList[[pj]][g.order, ] | |
569 } | |
570 | |
571 # If color scale is local, calculate breaks and quantiles here. | |
572 if(color.scale == 'local') { | |
573 flood.pts <- quantile(c(enrichList[[pj]], recursive=T), | |
574 c(flood.q, 1-flood.q)) | |
575 brk.use <- ColorBreaks(flood.pts[2], flood.pts[1], bam.pair, | |
576 ncolor) | |
577 } | |
578 | |
579 # Flooding extreme values. | |
580 enrichList[[pj]][ enrichList[[pj]] < flood.pts[1] ] <- flood.pts[1] | |
581 enrichList[[pj]][ enrichList[[pj]] > flood.pts[2] ] <- flood.pts[2] | |
582 | |
583 # Draw colorkey. | |
584 image(z=matrix(brk.use, ncol=1), col=enrich.palette(ncolor), | |
585 breaks=brk.use, axes=F, useRaster=T, main='Colorkey') | |
586 axis(1, at=seq(0, 1, length.out=5), | |
587 labels=format(brk.use[seq(1, ncolor + 1, length.out=5)], | |
588 digits=1), | |
589 lwd=1, lwd.ticks=1) | |
590 | |
591 # Draw heatmap. | |
592 image(z=t(enrichList[[pj]]), col=enrich.palette(ncolor), | |
593 breaks=brk.use, axes=F, useRaster=T, main=title2plot[pj]) | |
594 | |
595 axis(1, at=xticks$pos, labels=xticks$lab, lwd=1, lwd.ticks=1) | |
596 } | |
597 } | |
598 list(go.list,go.cluster) | |
599 } | |
600 | |
601 trim <- function(x, p){ | |
602 # Trim a numeric vector on both ends. | |
603 # Args: | |
604 # x: numeric vector. | |
605 # p: percentage of data to trim. | |
606 # Return: trimmed vector. | |
607 | |
608 low <- quantile(x, p) | |
609 hig <- quantile(x, 1 - p) | |
610 x[x > low & x < hig] | |
611 } | |
612 | |
613 CalcSem <- function(x, rb=.05){ | |
614 # Calculate standard error of mean for a numeric vector. | |
615 # Args: | |
616 # x: numeric vector | |
617 # rb: fraction of data to trim before calculating sem. | |
618 # Return: a scalar of the standard error of mean | |
619 | |
620 if(rb > 0){ | |
621 x <- trim(x, rb) | |
622 } | |
623 sem <- sd(x) / sqrt(length(x)) | |
624 ifelse(is.na(sem), 0, sem) | |
625 # NOTE: this should be improved to handle exception that "sd" calculation | |
626 # emits errors. | |
627 } | |
628 | |
629 | |
630 | |
631 | |
632 ## Leave for future reference. | |
633 # | |
634 # Set the antialiasing. | |
635 # type <- NULL | |
636 # if (capabilities()["aqua"]) { | |
637 # type <- "quartz" | |
638 # } else if (capabilities()["cairo"]) { | |
639 # type <- "cairo" | |
640 # } else if (capabilities()["X11"]) { | |
641 # type <- "Xlib" | |
642 # } | |
643 # Set the output type based on capabilities. | |
644 # if (is.null(type)){ | |
645 # png(plot.name, width, height, pointsize=pointsize) | |
646 | |
647 # } else { | |
648 # png(plot.name, width, height, pointsize=pointsize, type=type) | |
649 # } |