6
|
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()
|
18
|
642 yMax += min(1, yMax / 100.0)
|
6
|
643 if self.maximumY != None:
|
|
644 yMax = self.maximumY
|
|
645
|
|
646 log = ""
|
|
647 if self.logX:
|
|
648 log += "x"
|
|
649 if self.logY:
|
|
650 log += "y"
|
|
651 if log != "":
|
|
652 log = ", log=\"%s\"" % (log)
|
|
653
|
|
654 title = ""
|
|
655 if self.title != None:
|
|
656 title = ", main = \"%s\"" % (self.title)
|
|
657
|
|
658 if self.legend and self.legendBySide:
|
|
659 script += "layout(matrix(c(1,2), 1, 2), widths=c(5,1))\n"
|
|
660
|
|
661 if self.rotateAxesLabels[2]:
|
|
662 script += "par(mar=c(5,12,4,2))\n"
|
|
663 else:
|
|
664 script += "par(mar=c(5,5,4,2))\n"
|
|
665
|
|
666 addAxes = True
|
|
667
|
|
668 if self.barplot:
|
|
669 script += "data = scan(\"tmpData-%d-0.dat\", list(x = -666, y = -666))\n" % (self.seed)
|
|
670 if len(self.lines) == 1:
|
|
671 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)
|
|
672 addAxes = False
|
|
673 else:
|
|
674 script += "data1 = scan(\"tmpData-%d-1.dat\", list(x = -666, y = -666))\n" % (self.seed)
|
|
675 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)
|
|
676 elif self.points:
|
|
677 script += "data = scan(\"tmpData-%d-0.dat\", list(x = -666, y = -666))\n" % (self.seed)
|
|
678 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)
|
|
679 if self.regression:
|
|
680 x = "log10(data$x)" if self.logX else "data$x"
|
|
681 y = "log10(data$y)" if self.logY else "data$y"
|
|
682 script += "abline(lm(%s ~ %s))\n" % (y, x)
|
|
683 elif self.heatPoints:
|
|
684 if len(self.lines) != 1:
|
|
685 raise Exception("Error! Bad number of input data! Aborting...")
|
|
686 script += "data = scan(\"tmpData-%d-0.dat\", list(x = -666, y = -666))\n" % (self.seed)
|
|
687 script += "heatData = scan(\"tmpData-%d-1.dat\", list(x = \"\"))\n" % (self.seed)
|
|
688 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)
|
|
689 if self.regression:
|
|
690 x = "log10(data$x)" if self.logX else "data$x"
|
|
691 y = "log10(data$y)" if self.logY else "data$y"
|
|
692 script += "abline(lm(%s ~ %s))\n" % (y, x)
|
|
693 else:
|
|
694 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)
|
|
695 for i in range(0, len(self.lines)):
|
|
696 script += "data = scan(\"tmpData-%d-%d.dat\", list(x = -666.666, y = -666.666))\n" % (self.seed, i)
|
|
697 script += "lines(x = data$x, y = data$y, col = %s, lty = \"%s\", lwd = %d)\n" % (self.colors[i], self.types[i], self.lineWidth)
|
|
698
|
|
699 script += self.linesToAddBox
|
|
700
|
|
701 if addAxes:
|
|
702 for i in self.axesLabels:
|
|
703 rotation = ", las = 2" if self.rotateAxesLabels[i] else ""
|
|
704 if self.axesLabels[i] == None:
|
|
705 script += "axis(%d, cex.axis = 2, cex.lab = 2%s)\n" % (i, rotation)
|
|
706 else:
|
|
707 oldKeys = ", ".join(["%d" % (key) for key in sorted(self.axesLabels[i].keys())])
|
|
708 newKeys = ", ".join(["\"%s\"" % (self.axesLabels[i][key]) for key in sorted(self.axesLabels[i].keys())])
|
|
709 script += "axis(%d, at=c(%s), lab=c(%s), cex.axis = 2, cex.lab = 2%s)\n" % (i, oldKeys, newKeys, rotation)
|
|
710 script += "box()\n"
|
|
711
|
|
712 if self.legend:
|
|
713 if self.legendBySide:
|
|
714 script += "plot.new()\n"
|
|
715 script += "par(mar=c(0,0,0,0))\n"
|
|
716 script += "plot.window(c(0,1), c(0,1))\n"
|
|
717 script += "legends = c(%s)\n" % ", ".join(["\"%s\"" % name for name in self.names])
|
|
718 script += "colors = c(%s)\n" % ", ".join(["%s" % color for color in self.colors])
|
|
719 script += "lineTypes = c(%s)\n" % ", ".join(["\"%s\"" % type for type in self.types])
|
|
720 if self.legendBySide:
|
|
721 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)
|
|
722 else:
|
|
723 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)
|
|
724
|
|
725 return script
|
|
726
|
|
727
|
|
728
|
|
729 def plot(self):
|
|
730 """
|
|
731 Plot the lines
|
|
732 """
|
|
733 scriptFileName = "tmpScript-%d.R" % (self.seed)
|
|
734 scriptHandle = open(scriptFileName, "w")
|
|
735 scriptHandle.write("library(RColorBrewer)\n")
|
|
736 scriptHandle.write("colorPanel = brewer.pal(n=%d, name=\"Set1\")\n" % (self.nbColors))
|
|
737 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))
|
|
738 scriptHandle.write(self.getScript())
|
|
739 scriptHandle.write("dev.off()\n")
|
|
740 scriptHandle.close()
|
|
741 rCommand = "R"
|
|
742 if "SMARTRPATH" in os.environ:
|
|
743 rCommand = os.environ["SMARTRPATH"]
|
|
744 command = "\"%s\" CMD BATCH %s" % (rCommand, scriptFileName)
|
|
745 status = subprocess.call(command, shell=True)
|
|
746
|
|
747 if status != 0:
|
|
748 self.keep = True
|
|
749 raise Exception("Problem with the execution of script file %s, status is: %s" % (scriptFileName, status))
|
|
750
|
|
751
|
|
752 def getCorrelationData(self):
|
|
753 if not self.regression:
|
|
754 return ""
|
|
755 scriptFileName = "tmpScript-%d.R" % (self.seed)
|
|
756 rScript = open(scriptFileName, "w")
|
|
757 rScript.write("data = scan(\"tmpData-%d-0.dat\", list(x = -0.000000, y = -0.000000))\n" % (self.seed))
|
|
758 x = "log10(data$x)" if self.logX else "data$x"
|
|
759 y = "log10(data$y)" if self.logY else "data$y"
|
|
760 rScript.write("summary(lm(%s ~ %s))\n" % (y, x))
|
|
761 rScript.close()
|
|
762 rCommand = "R"
|
|
763 if "SMARTRPATH" in os.environ:
|
|
764 rCommand = os.environ["SMARTRPATH"]
|
|
765 command = "\"%s\" CMD BATCH %s" % (rCommand, scriptFileName)
|
|
766 status = subprocess.call(command, shell=True)
|
|
767 if status != 0:
|
|
768 self.keep = True
|
|
769 raise Exception("Problem with the execution of script file %s computing the correlation, status is: %s" % (scriptFileName, status))
|
|
770 outputRFile = open("%sout" % (scriptFileName))
|
|
771 output = ""
|
|
772 start = False
|
|
773 end = False
|
|
774 for line in outputRFile:
|
|
775 if start and "> " in line:
|
|
776 end = True
|
|
777 if start and not end:
|
|
778 output += line
|
|
779 if "summary" in line:
|
|
780 start = True
|
|
781 return output
|
|
782
|
|
783
|
|
784 def getSpearmanRho(self):
|
|
785 """
|
|
786 Get the Spearman rho correlation using R
|
|
787 """
|
|
788 return None
|
|
789 if not self.points and not self.barplot and not self.heatPoints:
|
|
790 raise Exception("Cannot compute Spearman rho correlation whereas not in 'points' or 'bar' mode.")
|
|
791
|
|
792 scriptFileName = "tmpScript-%d.R" % (self.seed)
|
|
793 rScript = open(scriptFileName, "w")
|
|
794 rScript.write("library(Hmisc)\n")
|
|
795 rScript.write("data = scan(\"tmpData-%d-0.dat\", list(x = -0.000000, y = -0.000000))\n" % (self.seed))
|
|
796 rScript.write("spearman(data$x, data$y)\n")
|
|
797 rScript.close()
|
|
798
|
|
799 rCommand = "R"
|
|
800 if "SMARTRPATH" in os.environ:
|
|
801 rCommand = os.environ["SMARTRPATH"]
|
|
802 command = "\"%s\" CMD BATCH %s" % (rCommand, scriptFileName)
|
|
803 status = subprocess.call(command, shell=True)
|
|
804
|
|
805 if status != 0:
|
|
806 self.keep = True
|
|
807 raise Exception("Problem with the execution of script file %s, status is: %s" % (scriptFileName, status))
|
|
808
|
|
809 outputRFile = open("%sout" % (scriptFileName))
|
|
810 nextLine = False
|
|
811 for line in outputRFile:
|
|
812 line = line.strip()
|
|
813 if nextLine:
|
|
814 if line == "NA":
|
|
815 return None
|
|
816 return float(line)
|
|
817 nextLine = False
|
|
818 if line == "rho":
|
|
819 nextLine = True
|
|
820
|
|
821 return None
|