Mercurial > repos > yufei-luo > s_mart
comparison SMART/Java/Python/misc/RPlotter.py @ 6:769e306b7933
Change the repository level.
author | yufei-luo |
---|---|
date | Fri, 18 Jan 2013 04:54:14 -0500 |
parents | |
children | 94ab73e8a190 |
comparison
equal
deleted
inserted
replaced
5:ea3082881bf8 | 6:769e306b7933 |
---|---|
1 # | |
2 # Copyright INRA-URGI 2009-2010 | |
3 # | |
4 # This software is governed by the CeCILL license under French law and | |
5 # abiding by the rules of distribution of free software. You can use, | |
6 # modify and/ or redistribute the software under the terms of the CeCILL | |
7 # license as circulated by CEA, CNRS and INRIA at the following URL | |
8 # "http://www.cecill.info". | |
9 # | |
10 # As a counterpart to the access to the source code and rights to copy, | |
11 # modify and redistribute granted by the license, users are provided only | |
12 # with a limited warranty and the software's author, the holder of the | |
13 # economic rights, and the successive licensors have only limited | |
14 # liability. | |
15 # | |
16 # In this respect, the user's attention is drawn to the risks associated | |
17 # with loading, using, modifying and/or developing or reproducing the | |
18 # software by the user in light of its specific status of free software, | |
19 # that may mean that it is complicated to manipulate, and that also | |
20 # therefore means that it is reserved for developers and experienced | |
21 # professionals having in-depth computer knowledge. Users are therefore | |
22 # encouraged to load and test the software's suitability as regards their | |
23 # requirements in conditions enabling the security of their systems and/or | |
24 # data to be ensured and, more generally, to use and operate it in the | |
25 # same conditions as regards security. | |
26 # | |
27 # The fact that you are presently reading this means that you have had | |
28 # knowledge of the CeCILL license and that you accept its terms. | |
29 # | |
30 | |
31 import os | |
32 import subprocess | |
33 import random | |
34 import math | |
35 | |
36 minPositiveValue = 10e-6 | |
37 | |
38 """ | |
39 Plot simple curves in R | |
40 """ | |
41 | |
42 class RPlotter(object): | |
43 """ | |
44 Plot some curves | |
45 @ivar nbColors: number of different colors | |
46 @type nbColors: int | |
47 @ivar fileName: name of the file | |
48 @type fileName: string | |
49 @ivar lines: lines to be plotted | |
50 @type lines: array of dict | |
51 @ivar names: name of the lines | |
52 @type names: array of strings | |
53 @ivar colors: color of the lines | |
54 @type colors: array of strings | |
55 @ivar types: type of the lines (plain or dashed) | |
56 @type types: array of strings | |
57 @ivar format: format of the picture | |
58 @type format: string | |
59 @ivar lineWidth: width of the line in a xy-plot | |
60 @type lineWidth: int | |
61 @ivar xMin: minimum value taken on the x-axis | |
62 @type xMin: int | |
63 @ivar xMax: maximum value taken on the x-axis | |
64 @type xMax: int | |
65 @ivar yMin: minimum value taken on the y-axis | |
66 @type yMin: int | |
67 @ivar yMax: maximum value taken on the y-axis | |
68 @type yMax: int | |
69 @ivar minimumX: minimum value allowed on the x-axis | |
70 @type minimumX: int | |
71 @ivar maximumX: maximum value allowed on the x-axis | |
72 @type maximumX: int | |
73 @ivar minimumY: minimum value allowed on the y-axis | |
74 @type minimumY: int | |
75 @ivar maximumY: maximum value allowed on the y-axis | |
76 @type maximumY: int | |
77 @ivar leftMargin: add some margin in the left part of the plot | |
78 @type leftMargin: float | |
79 @ivar rightMargin: add some margin in the right part of the plot | |
80 @type rightMargin: float | |
81 @ivar downMargin: add some margin at the top of the plot | |
82 @type downMargin: float | |
83 @ivar upMargin: add some margin at the bottom of the plot | |
84 @type upMargin: float | |
85 @ivar logX: use log scale on the x-axis | |
86 @type logX: boolean | |
87 @ivar logY: use log scale on the y-axis | |
88 @type logY: boolean | |
89 @ivar logZ: use log scale on the z-axis (the color) | |
90 @type logZ: boolean | |
91 @ival fill: if a value is not given, fill it with given value | |
92 @type fill: int | |
93 @ival bucket: cluster the data into buckets of given size | |
94 @type bucket: int | |
95 @ival seed: a random number | |
96 @type seed: int | |
97 @ival regression: plot a linear regression | |
98 @type regression: boolean | |
99 @ival legend: set the legend | |
100 @type legend: boolean | |
101 @ival legendBySide: set the legend outside of the plot | |
102 @type legendBySde: boolean | |
103 @ival xLabel: label for the x-axis | |
104 @type xLabel: string | |
105 @ival yLabel: label for the y-axis | |
106 @type yLabel: string | |
107 @ival title: title of the plot | |
108 @type title: string | |
109 @ival barplot: use a barplot representation instead | |
110 @type barplot: boolean | |
111 @ival points: use a point cloud instead | |
112 @type points: boolean | |
113 @ival heatPoints: use a colored point cloud instead | |
114 @type heatPoints: boolean | |
115 @ival axesLabels: change the names of the axes | |
116 @type axesLabels: vector of 2 int to string dict | |
117 @ival rotateAxesLabels: rotate the axes labels | |
118 @type rotateAxesLabels: dict of 2 boolean | |
119 @ival verbosity: verbosity of the class | |
120 @type verbosity: int | |
121 @ival keep: keep temporary files | |
122 @type keep: boolean | |
123 """ | |
124 | |
125 def __init__(self, fileName, verbosity = 0, keep = False): | |
126 """ | |
127 Constructor | |
128 @param fileName: name of the file to produce | |
129 @type fileName: string | |
130 @param verbosity: verbosity | |
131 @type verbosity: int | |
132 @param keep: keep temporary files | |
133 @type keep: boolean | |
134 """ | |
135 self.nbColors = 9 | |
136 self.fileName = fileName | |
137 self.verbosity = verbosity | |
138 self.keep = keep | |
139 self.format = "png" | |
140 self.fill = None | |
141 self.bucket = None | |
142 self.lines = [] | |
143 self.names = [] | |
144 self.colors = [] | |
145 self.types = [] | |
146 self.lineWidth = 1 | |
147 self.xMin = None | |
148 self.xMax = None | |
149 self.yMin = None | |
150 self.yMax = None | |
151 self.seed = random.randint(0, 10000) | |
152 self.minimumX = None | |
153 self.maximumX = None | |
154 self.minimumY = None | |
155 self.maximumY = None | |
156 self.leftMargin = 0 | |
157 self.rightMargin = 0 | |
158 self.topMargin = 0 | |
159 self.bottomMargin = 0 | |
160 self.logX = False | |
161 self.logY = False | |
162 self.logZ = False | |
163 self.regression = False | |
164 self.width = 1000 | |
165 self.height = 500 | |
166 self.legend = False | |
167 self.legendBySide = False | |
168 self.xLabel = "" | |
169 self.yLabel = "" | |
170 self.title = None | |
171 self.points = False | |
172 self.heatPoints = False | |
173 self.barplot = False | |
174 self.axesLabels = {1: None, 2: None} | |
175 self.rotateAxesLabels = {1: False, 2: False} | |
176 self.linesToAddBox = "" | |
177 | |
178 def __del__(self): | |
179 """ | |
180 Destructor | |
181 Remove tmp files | |
182 """ | |
183 if not self.keep: | |
184 scriptFileName = "tmpScript-%d.R" % (self.seed) | |
185 if os.path.exists(scriptFileName): | |
186 os.remove(scriptFileName) | |
187 outputFileName = "%sout" % (scriptFileName) | |
188 if os.path.exists(outputFileName): | |
189 os.remove(outputFileName) | |
190 nbLines = len(self.lines) + (1 if self.heatPoints else 0) | |
191 for i in range(nbLines): | |
192 if os.path.exists("tmpData-%d-%d.dat" % (self.seed, i)): | |
193 os.remove("tmpData-%d-%d.dat" % (self.seed, i)) | |
194 | |
195 | |
196 def setMinimumX(self, xMin): | |
197 """ | |
198 Set the minimum value on the x-axis | |
199 @param xMin:minimum value on the x-axis | |
200 @type xMin: int | |
201 """ | |
202 self.minimumX = xMin | |
203 | |
204 | |
205 def setMaximumX(self, xMax): | |
206 """ | |
207 Set the maximum value on the x-axis | |
208 @param xMax: maximum value on the x-axis | |
209 @type xMax: int | |
210 """ | |
211 self.maximumX = xMax | |
212 | |
213 | |
214 def setMinimumY(self, yMin): | |
215 """ | |
216 Set the minimum value on the y-axis | |
217 @param yMin: minimum value on the y-axis | |
218 @type yMin: int | |
219 """ | |
220 self.minimumY = yMin | |
221 | |
222 | |
223 def setMaximumY(self, yMax): | |
224 """ | |
225 Set the maximum value on the y-axis | |
226 @param yMax: maximum value on the y-axis | |
227 @type xmax: int | |
228 """ | |
229 self.maximumY = yMax | |
230 | |
231 | |
232 def setFill(self, fill): | |
233 """ | |
234 Fill empty data with given value | |
235 @param fill: the value to fill with | |
236 @type fill: int | |
237 """ | |
238 self.fill = fill | |
239 | |
240 | |
241 def setBuckets(self, bucket): | |
242 """ | |
243 Cluster the data into buckets of given size | |
244 @param bucket: the size of the buckets | |
245 @type bucket: int | |
246 """ | |
247 self.bucket = bucket | |
248 | |
249 | |
250 def setRegression(self, regression): | |
251 """ | |
252 Plot a linear regression line | |
253 @param regression: whether to plot the regression | |
254 @type regression: bool | |
255 """ | |
256 self.regression = regression | |
257 | |
258 | |
259 def setFormat(self, format): | |
260 """ | |
261 Set the format of the picture | |
262 @param format: the format | |
263 @type format: string | |
264 """ | |
265 if format not in ("png", "pdf", "jpeg", "bmp", "tiff"): | |
266 raise Exception("Format '%s' is not supported by RPlotter" % (format)) | |
267 self.format = format | |
268 | |
269 | |
270 def setWidth(self, width): | |
271 """ | |
272 Set the dimensions of the image produced | |
273 @param width: width of the image | |
274 @type width: int | |
275 """ | |
276 self.width = width | |
277 | |
278 | |
279 def setHeight(self, height): | |
280 """ | |
281 Set the dimensions of the image produced | |
282 @param height: heigth of the image | |
283 @type height: int | |
284 """ | |
285 self.height = height | |
286 | |
287 | |
288 def setImageSize(self, width, height): | |
289 """ | |
290 Set the dimensions of the image produced | |
291 @param width: width of the image | |
292 @type width: int | |
293 @param height: heigth of the image | |
294 @type height: int | |
295 """ | |
296 self.setWidth(width) | |
297 self.setHeight(height) | |
298 | |
299 | |
300 def setLegend(self, legend, bySide = False): | |
301 """ | |
302 Print a legend or not | |
303 @param legend: print a legend | |
304 @type legend: boolean | |
305 @param bySide: put the legend outside of the plot | |
306 @type bySide: boolean | |
307 """ | |
308 self.legend = legend | |
309 self.legendBySide = bySide | |
310 | |
311 | |
312 def setXLabel(self, label): | |
313 """ | |
314 Print a label for the x-axis | |
315 @param label: the label | |
316 @type label: string | |
317 """ | |
318 self.xLabel = label | |
319 if self.xLabel != None: | |
320 self.xLabel = self.xLabel.replace("_", " ") | |
321 | |
322 | |
323 def setYLabel(self, label): | |
324 """ | |
325 Print a label for the y-axis | |
326 @param label: the label | |
327 @type label: string | |
328 """ | |
329 self.yLabel = label | |
330 if self.yLabel != None: | |
331 self.yLabel = self.yLabel.replace("_", " ") | |
332 | |
333 | |
334 def addLeftMargin(self, margin): | |
335 """ | |
336 Increase the size of the space on the left part of the graph | |
337 @param margin: the space added | |
338 @type margin: float | |
339 """ | |
340 self.leftMargin = margin | |
341 | |
342 | |
343 def addRightMargin(self, margin): | |
344 """ | |
345 Increase the size of the space on the right part of the graph | |
346 @param margin: the space added | |
347 @type margin: float | |
348 """ | |
349 self.rightMargin = margin | |
350 | |
351 | |
352 def addTopMargin(self, margin): | |
353 """ | |
354 Increase the size of the space at the top of the graph | |
355 TopMargin is a percentage if 0 < TopMargin < 1. | |
356 TopMargin is a value if TopMargin >= 1. | |
357 @param margin: the space added | |
358 @type margin: float | |
359 """ | |
360 self.topMargin = margin | |
361 | |
362 | |
363 def addBottomMargin(self, margin): | |
364 """ | |
365 Increase the size of the space at the bottom of the graph | |
366 @param margin: the space added | |
367 @type margin: float | |
368 """ | |
369 self.bottomMargin = margin | |
370 | |
371 | |
372 def getNewYMaxWithTopMargin(self): | |
373 """ | |
374 Return new xMin coordinate with left margin | |
375 @param xMin: coordinate | |
376 @type xMin: float | |
377 """ | |
378 yMax = self.yMax | |
379 if 0 < self.topMargin and self.topMargin < 1: | |
380 topMargin = self.topMargin * self.yMax | |
381 yMax = self.yMax + topMargin | |
382 elif self.topMargin >= 1: | |
383 yMax = self.yMax + self.topMargin | |
384 return yMax | |
385 | |
386 | |
387 def setTitle(self, title): | |
388 """ | |
389 Print a title for graph | |
390 @param title: a title | |
391 @type title: string | |
392 """ | |
393 self.title = title | |
394 if self.title != None: | |
395 self.title = self.title.replace("_", " ") | |
396 | |
397 | |
398 def setAxisLabel(self, i, labels): | |
399 """ | |
400 Change x- or y-labels | |
401 @param i: x for x-label, y for y-label | |
402 @type i: string | |
403 @param labels: new labels | |
404 @type labels: int to string dict | |
405 """ | |
406 i = i.lower() | |
407 if i not in ("x", "y"): | |
408 raise Exception("Label name '" + i + "' should by 'x' or 'y' while changing axis labels.") | |
409 self.axesLabels[{"x": 1, "y": 2}[i]] = labels | |
410 | |
411 | |
412 def rotateAxisLabel(self, i, b = True): | |
413 """ | |
414 Rotate x- or y-labels | |
415 @param i: x for x-label, y for y-label | |
416 @type i: string | |
417 @param b: whether the labels should be rotated | |
418 @type b: boolean | |
419 """ | |
420 i = i.lower() | |
421 if i not in ("x", "y"): | |
422 raise Exception("Label name '" + i + "' should by 'x' or 'y' while rotating axis labels.") | |
423 self.rotateAxesLabels[{"x": 1, "y": 2}[i]] = b | |
424 | |
425 def setLineWidth(self, width): | |
426 """ | |
427 Set the line width in a xy-plot | |
428 @param width: the new line width | |
429 @type width: int | |
430 """ | |
431 self.lineWidth = width | |
432 | |
433 def setLog(self, log): | |
434 """ | |
435 Use log-scale for axes | |
436 @param log: use log scale | |
437 @type log: boolean | |
438 """ | |
439 self.logX = ("x" in log) | |
440 self.logY = ("y" in log) | |
441 self.logZ = ("z" in log) | |
442 | |
443 | |
444 def setBarplot(self, barplot): | |
445 """ | |
446 Use barplot representation instead | |
447 @param barplot: barplot representation | |
448 @type barplot: boolean | |
449 """ | |
450 self.barplot = barplot | |
451 | |
452 | |
453 def setPoints(self, points): | |
454 """ | |
455 Use points cloud representation instead | |
456 @param points: points cloud representation | |
457 @type points: boolean | |
458 """ | |
459 self.points = points | |
460 | |
461 | |
462 def setHeatPoints(self, heatPoints): | |
463 """ | |
464 Use points cloud representation with color representing another variable instead | |
465 @param points: colored points cloud representation | |
466 @type points: boolean | |
467 """ | |
468 self.heatPoints = heatPoints | |
469 | |
470 | |
471 def addBox(self, lXCoordList, minY, maxY): | |
472 for lXCoord in lXCoordList: | |
473 self.linesToAddBox += "rect(%s,%s,%s,%s,density=50, col='grey',border='transparent')\n" % (lXCoord[0], minY, lXCoord[1], maxY) | |
474 | |
475 def addLine(self, line, name = "", color = None): | |
476 """ | |
477 Add a line | |
478 @param line: a line to plot | |
479 @type line: dict | |
480 """ | |
481 # prepare data | |
482 plot = [] | |
483 if self.points or self.heatPoints: | |
484 values = line.values() | |
485 elif self.fill == None: | |
486 values = sorted(line.keys()) | |
487 else: | |
488 values = range(min(line.keys()), max(line.keys()) + 1) | |
489 | |
490 for element in values: | |
491 if self.points or self.heatPoints: | |
492 x = element[0] | |
493 y = element[1] | |
494 else: | |
495 x = element | |
496 if x not in line: | |
497 y = self.fill | |
498 else: | |
499 y = line[x] | |
500 | |
501 if self.minimumX != None and x < self.minimumX: | |
502 continue | |
503 if self.maximumX != None and x > self.maximumX: | |
504 continue | |
505 | |
506 if x == None: | |
507 raise Exception("Problem! x is None. Aborting...") | |
508 if y == None: | |
509 raise Exception("Problem! y is None. Aborting...") | |
510 if x == 0 and self.logX: | |
511 x = minPositiveValue | |
512 if y == 0 and self.logY: | |
513 y = minPositiveValue | |
514 if self.xMin == None: | |
515 if not self.logX or x != 0: | |
516 self.xMin = x | |
517 else: | |
518 if not self.logX or x != 0: | |
519 self.xMin = min(self.xMin, x) | |
520 if self.xMax == None: | |
521 self.xMax = x | |
522 else: | |
523 self.xMax = max(self.xMax, x) | |
524 if self.yMin == None: | |
525 if not self.logY or y != 0: | |
526 self.yMin = y | |
527 else: | |
528 if not self.logY or y != 0: | |
529 if y != "NA": | |
530 self.yMin = min(self.yMin, y) | |
531 if self.yMax == None: | |
532 self.yMax = y | |
533 else: | |
534 if y != "NA": | |
535 self.yMax = max(self.yMax, y) | |
536 | |
537 plot.append((x, y)) | |
538 | |
539 # cluster the data into buckets | |
540 if self.bucket != None: | |
541 buckets = dict([((int(value) / int(self.bucket)) * self.bucket, 0) for value in xrange(min(line.keys()), max(line.keys())+1)]) | |
542 for distance, nb in line.iteritems(): | |
543 buckets[(int(distance) / int(self.bucket)) * self.bucket] += nb | |
544 self.yMax = max(buckets.values()) | |
545 plot = [] | |
546 for x, y in buckets.iteritems(): | |
547 plot.append((x, y)) | |
548 | |
549 # write file | |
550 dataFileName = "tmpData-%d-%d.dat" % (self.seed, len(self.lines)) | |
551 dataHandle = open(dataFileName, "w") | |
552 if not self.heatPoints: | |
553 plot.sort() | |
554 for (x, y) in plot: | |
555 if y != "NA": | |
556 dataHandle.write("%f\t%f\n" % (x, y)) | |
557 else: | |
558 dataHandle.write("%f\t%s\n" % (x, y)) | |
559 dataHandle.close() | |
560 | |
561 self.lines.append(line) | |
562 self.names.append(name) | |
563 | |
564 if color == None: | |
565 colorNumber = len(self.colors) % (self.nbColors - 1) + 1 | |
566 type = "solid" | |
567 if len(self.colors) >= self.nbColors: | |
568 type = "dashed" | |
569 color = "colorPanel[%d]" % (colorNumber) | |
570 else: | |
571 color = "\"%s\"" % (color) | |
572 type = "solid" | |
573 self.colors.append(color) | |
574 self.types.append(type) | |
575 | |
576 | |
577 def addHeatLine(self, line, name = "", color = None): | |
578 """ | |
579 Add the heat line | |
580 @param line: the line which gives the color of the points | |
581 @type line: dict | |
582 """ | |
583 if not self.heatPoints: | |
584 raise Exception("Error! Trying to add a heat point whereas not mentioned to earlier! Aborting.") | |
585 | |
586 dataFileName = "tmpData-%d-%d.dat" % (self.seed, len(self.lines)) | |
587 dataHandle = open(dataFileName, "w") | |
588 | |
589 minimumHeat = min(line.values()) | |
590 maximumHeat = max(line.values()) | |
591 minLogValue = 0.00001 | |
592 log = self.logZ | |
593 | |
594 if log: | |
595 if minimumHeat == 0: | |
596 for element in line: | |
597 line[element] += minLogValue | |
598 minimumHeat += minLogValue | |
599 maximumHeat += minLogValue | |
600 minimumHeat = math.log10(minimumHeat) | |
601 maximumHeat = math.log10(maximumHeat) | |
602 | |
603 coeff = 255.0 / (maximumHeat - minimumHeat) | |
604 | |
605 for element in line: | |
606 value = line[element] | |
607 if log: | |
608 value = math.log10(max(minLogValue, value)) | |
609 dataHandle.write("\"#%02X%02X00\"\n" % (int((value - minimumHeat) * coeff), 255 - int((value - minimumHeat) * coeff))) | |
610 | |
611 dataHandle.close() | |
612 self.names.append(name) | |
613 if color == None: | |
614 colorNumber = len(self.colors) % (self.nbColors - 1) + 1 | |
615 type = "solid" | |
616 if len(self.colors) >= self.nbColors: | |
617 type = "dashed" | |
618 color = "colorPanel[%d]" % (colorNumber) | |
619 else: | |
620 color = "\"%s\"" % (color) | |
621 type = "solid" | |
622 self.colors.append(color) | |
623 self.types.append(type) | |
624 | |
625 | |
626 def getScript(self): | |
627 """ | |
628 Write (unfinished) R script | |
629 """ | |
630 script = "" | |
631 | |
632 xMin = self.xMin - self.leftMargin | |
633 if self.minimumX != None: | |
634 xMin = max(xMin, self.minimumX) | |
635 xMax = self.xMax + self.rightMargin | |
636 if self.maximumX != None: | |
637 xMax = min(xMax, self.maximumX) | |
638 yMin = self.yMin - self.bottomMargin | |
639 if self.minimumY != None: | |
640 yMin = self.minimumY | |
641 yMax = self.getNewYMaxWithTopMargin() | |
642 if self.maximumY != None: | |
643 yMax = self.maximumY | |
644 | |
645 log = "" | |
646 if self.logX: | |
647 log += "x" | |
648 if self.logY: | |
649 log += "y" | |
650 if log != "": | |
651 log = ", log=\"%s\"" % (log) | |
652 | |
653 title = "" | |
654 if self.title != None: | |
655 title = ", main = \"%s\"" % (self.title) | |
656 | |
657 if self.legend and self.legendBySide: | |
658 script += "layout(matrix(c(1,2), 1, 2), widths=c(5,1))\n" | |
659 | |
660 if self.rotateAxesLabels[2]: | |
661 script += "par(mar=c(5,12,4,2))\n" | |
662 else: | |
663 script += "par(mar=c(5,5,4,2))\n" | |
664 | |
665 addAxes = True | |
666 | |
667 if self.barplot: | |
668 script += "data = scan(\"tmpData-%d-0.dat\", list(x = -666, y = -666))\n" % (self.seed) | |
669 if len(self.lines) == 1: | |
670 script += "barplot(data$y, name = data$x, xlab=\"%s\", ylab=\"%s\", ylim = c(%f, %f), cex.axis = 2, cex.names = 2, cex.lab = 2%s%s)\n" % (self.xLabel, self.yLabel, yMin, yMax, title, log) | |
671 addAxes = False | |
672 else: | |
673 script += "data1 = scan(\"tmpData-%d-1.dat\", list(x = -666, y = -666))\n" % (self.seed) | |
674 script += "barplot(rbind(data$y, data1$y), name = data$x, xlab=\"%s\", ylab=\"%s\", cex.axis = 2, cex.names = 2, cex.lab = 2%s, beside = TRUE, space=c(-1,0), axes = FALSE%s)\n" % (self.xLabel, self.yLabel, title, log) | |
675 elif self.points: | |
676 script += "data = scan(\"tmpData-%d-0.dat\", list(x = -666, y = -666))\n" % (self.seed) | |
677 script += "plot(data$x, data$y, xlab=\"%s\", ylab=\"%s\", cex.axis = 2, cex.lab = 2, axes = FALSE%s%s)\n" % (self.xLabel, self.yLabel, title, log) | |
678 if self.regression: | |
679 x = "log10(data$x)" if self.logX else "data$x" | |
680 y = "log10(data$y)" if self.logY else "data$y" | |
681 script += "abline(lm(%s ~ %s))\n" % (y, x) | |
682 elif self.heatPoints: | |
683 if len(self.lines) != 1: | |
684 raise Exception("Error! Bad number of input data! Aborting...") | |
685 script += "data = scan(\"tmpData-%d-0.dat\", list(x = -666, y = -666))\n" % (self.seed) | |
686 script += "heatData = scan(\"tmpData-%d-1.dat\", list(x = \"\"))\n" % (self.seed) | |
687 script += "plot(data$x, data$y, col=heatData$x, xlab=\"%s\", ylab=\"%s\", cex.axis = 2, cex.lab = 2, axes = FALSE%s%s)\n" % (self.xLabel, self.yLabel, title, log) | |
688 if self.regression: | |
689 x = "log10(data$x)" if self.logX else "data$x" | |
690 y = "log10(data$y)" if self.logY else "data$y" | |
691 script += "abline(lm(%s ~ %s))\n" % (y, x) | |
692 else: | |
693 script += "plot(x = NA, y = NA, panel.first = grid(lwd = 1.0), xlab=\"%s\", ylab=\"%s\", xlim = c(%f, %f), ylim = c(%f, %f), cex.axis = 2, cex.lab = 2, axes = FALSE%s%s)\n" % (self.xLabel, self.yLabel, xMin, xMax, yMin, yMax, title, log) | |
694 for i in range(0, len(self.lines)): | |
695 script += "data = scan(\"tmpData-%d-%d.dat\", list(x = -666.666, y = -666.666))\n" % (self.seed, i) | |
696 script += "lines(x = data$x, y = data$y, col = %s, lty = \"%s\", lwd = %d)\n" % (self.colors[i], self.types[i], self.lineWidth) | |
697 | |
698 script += self.linesToAddBox | |
699 | |
700 if addAxes: | |
701 for i in self.axesLabels: | |
702 rotation = ", las = 2" if self.rotateAxesLabels[i] else "" | |
703 if self.axesLabels[i] == None: | |
704 script += "axis(%d, cex.axis = 2, cex.lab = 2%s)\n" % (i, rotation) | |
705 else: | |
706 oldKeys = ", ".join(["%d" % (key) for key in sorted(self.axesLabels[i].keys())]) | |
707 newKeys = ", ".join(["\"%s\"" % (self.axesLabels[i][key]) for key in sorted(self.axesLabels[i].keys())]) | |
708 script += "axis(%d, at=c(%s), lab=c(%s), cex.axis = 2, cex.lab = 2%s)\n" % (i, oldKeys, newKeys, rotation) | |
709 script += "box()\n" | |
710 | |
711 if self.legend: | |
712 if self.legendBySide: | |
713 script += "plot.new()\n" | |
714 script += "par(mar=c(0,0,0,0))\n" | |
715 script += "plot.window(c(0,1), c(0,1))\n" | |
716 script += "legends = c(%s)\n" % ", ".join(["\"%s\"" % name for name in self.names]) | |
717 script += "colors = c(%s)\n" % ", ".join(["%s" % color for color in self.colors]) | |
718 script += "lineTypes = c(%s)\n" % ", ".join(["\"%s\"" % type for type in self.types]) | |
719 if self.legendBySide: | |
720 script += "legend(0, 1, legend = legends, xjust = 0, yjust = 1, col = colors, lty = lineTypes, lwd = %d, cex = 1.5, ncol = 1, bg = \"white\")\n" % (self.lineWidth) | |
721 else: | |
722 script += "legend(\"topright\", legend = legends, xjust = 0, yjust = 1, col = colors, lty = lineTypes, lwd = %d, cex = 1.5, ncol = 1, bg = \"white\")\n" % (self.lineWidth) | |
723 | |
724 return script | |
725 | |
726 | |
727 | |
728 def plot(self): | |
729 """ | |
730 Plot the lines | |
731 """ | |
732 scriptFileName = "tmpScript-%d.R" % (self.seed) | |
733 scriptHandle = open(scriptFileName, "w") | |
734 scriptHandle.write("library(RColorBrewer)\n") | |
735 scriptHandle.write("colorPanel = brewer.pal(n=%d, name=\"Set1\")\n" % (self.nbColors)) | |
736 scriptHandle.write("%s(%s = \"%s\", width = %d, height = %d, bg = \"white\")\n" % (self.format, "filename" if self.format != "pdf" else "file", self.fileName, self.width, self.height)) | |
737 scriptHandle.write(self.getScript()) | |
738 scriptHandle.write("dev.off()\n") | |
739 scriptHandle.close() | |
740 rCommand = "R" | |
741 if "SMARTRPATH" in os.environ: | |
742 rCommand = os.environ["SMARTRPATH"] | |
743 command = "\"%s\" CMD BATCH %s" % (rCommand, scriptFileName) | |
744 status = subprocess.call(command, shell=True) | |
745 | |
746 if status != 0: | |
747 self.keep = True | |
748 raise Exception("Problem with the execution of script file %s, status is: %s" % (scriptFileName, status)) | |
749 | |
750 | |
751 def getCorrelationData(self): | |
752 if not self.regression: | |
753 return "" | |
754 scriptFileName = "tmpScript-%d.R" % (self.seed) | |
755 rScript = open(scriptFileName, "w") | |
756 rScript.write("data = scan(\"tmpData-%d-0.dat\", list(x = -0.000000, y = -0.000000))\n" % (self.seed)) | |
757 x = "log10(data$x)" if self.logX else "data$x" | |
758 y = "log10(data$y)" if self.logY else "data$y" | |
759 rScript.write("summary(lm(%s ~ %s))\n" % (y, x)) | |
760 rScript.close() | |
761 rCommand = "R" | |
762 if "SMARTRPATH" in os.environ: | |
763 rCommand = os.environ["SMARTRPATH"] | |
764 command = "\"%s\" CMD BATCH %s" % (rCommand, scriptFileName) | |
765 status = subprocess.call(command, shell=True) | |
766 if status != 0: | |
767 self.keep = True | |
768 raise Exception("Problem with the execution of script file %s computing the correlation, status is: %s" % (scriptFileName, status)) | |
769 outputRFile = open("%sout" % (scriptFileName)) | |
770 output = "" | |
771 start = False | |
772 end = False | |
773 for line in outputRFile: | |
774 if start and "> " in line: | |
775 end = True | |
776 if start and not end: | |
777 output += line | |
778 if "summary" in line: | |
779 start = True | |
780 return output | |
781 | |
782 | |
783 def getSpearmanRho(self): | |
784 """ | |
785 Get the Spearman rho correlation using R | |
786 """ | |
787 return None | |
788 if not self.points and not self.barplot and not self.heatPoints: | |
789 raise Exception("Cannot compute Spearman rho correlation whereas not in 'points' or 'bar' mode.") | |
790 | |
791 scriptFileName = "tmpScript-%d.R" % (self.seed) | |
792 rScript = open(scriptFileName, "w") | |
793 rScript.write("library(Hmisc)\n") | |
794 rScript.write("data = scan(\"tmpData-%d-0.dat\", list(x = -0.000000, y = -0.000000))\n" % (self.seed)) | |
795 rScript.write("spearman(data$x, data$y)\n") | |
796 rScript.close() | |
797 | |
798 rCommand = "R" | |
799 if "SMARTRPATH" in os.environ: | |
800 rCommand = os.environ["SMARTRPATH"] | |
801 command = "\"%s\" CMD BATCH %s" % (rCommand, scriptFileName) | |
802 status = subprocess.call(command, shell=True) | |
803 | |
804 if status != 0: | |
805 self.keep = True | |
806 raise Exception("Problem with the execution of script file %s, status is: %s" % (scriptFileName, status)) | |
807 | |
808 outputRFile = open("%sout" % (scriptFileName)) | |
809 nextLine = False | |
810 for line in outputRFile: | |
811 line = line.strip() | |
812 if nextLine: | |
813 if line == "NA": | |
814 return None | |
815 return float(line) | |
816 nextLine = False | |
817 if line == "rho": | |
818 nextLine = True | |
819 | |
820 return None |