source: TOOLS/PlotRuncard/plot_runcard.py @ 2040

Last change on this file since 2040 was 1986, checked in by brocksce, 9 years ago

Add last version of the script

File size: 9.1 KB
Line 
1#!/bin/env python
2
3#======================================================
4# Author: Patrick.Brockmann@cea.fr
5#
6# Date: 13/11/2012
7#
8#======================================================
9
10#======================================================
11import csv
12import matplotlib.pyplot as plt
13import datetime as dt
14import sys, string, os, re
15import urllib2
16import random
17
18#======================================================
19usage = """######################################################
20Usage:  plot_runcard.py [-h]
21        [--period]
22        [--yscalelog]
23        [--linewidth width]
24        [--linecolor colorcode]
25        [--showtitle]
26        [--pattern  'pattern, options ; ...']
27        list
28
29
30Argument:
31        Argument list is text file with one run.card file accessible by HTTP (http://...) or locally (file:///...) per line.
32        For each line, you can add specific options (linecolor, linewidth, title, showtitle) separated by ',' (whatever order).
33        For example :
34http://dods.extra.cea.fr/work/p86caub/IPSLCM5A/PROD/rcp85GHG/v3.rcp85GHG1/MONITORING/run.card   , linecolor="AFBBAA", title="My text", showtitle=1
35
36Notes:
37        Default color are randomly choosen
38        Default title is built from filename
39
40Examples:
41       ./plot_runcard.py --linecolor "BBBBBB" --pattern 'p86caub, linecolor="00FF00", showtitle=1 ; p25mart, linecolor="FF0000", showtitle=1, linewidth=4'  list_url_work2
42       ./plot_runcard.py --linecolor "BBBBBB" --pattern 'p86.*, linecolor="00FF00", showtitle=1 ; p25.*, linecolor="FF0000", showtitle=1'  list_url_work2
43
44"""
45
46options = """######################################################
47Options:
48        -h, -?, --help, -help
49                Print this manual
50        --period
51                Use CumulPeriod rather than PeriodDateBegin
52        --yscalelog
53                Set a log axis for vertical axis (only with --period option)
54        --linecolor FFFFFF
55                color code in hexa
56        --linewidth width
57                width = float value in points
58        --showtitle
59                title will be displayed
60                By default, titles are displayed only when mouse is passed over simulations
61        --pattern  'pattern, options ; ...'
62                ex: 'p86caub, linecolor="00FF00", showtitle=1 ; p86mart, linecolor="FF0000"'
63                Use single quote to delimit the option and ; between patterns.
64                Options are considered following the order : options from command, options from pattern option, options from list file.
65"""
66
67#======================================================
68periodoption=0 
69yscalelogoption=0
70linecoloroption=0
71linewidthoption=0
72showtitleoption=0
73patternoption=0
74while len(sys.argv[1:]) != 0 :
75        if sys.argv[1] in ('-h','--help') :
76                del(sys.argv[1])
77                print usage + options
78                sys.exit(1)
79        elif sys.argv[1] == '--period' :
80                periodoption=1
81                del(sys.argv[1])
82        elif sys.argv[1] == '--yscalelog' :
83                yscalelogoption=1
84                del(sys.argv[1])
85        elif sys.argv[1] == '--linecolor' :
86                linecoloroptionvalue=sys.argv[2]
87                linecoloroption=1
88                del(sys.argv[1])
89                del(sys.argv[1])
90        elif sys.argv[1] == '--linewidth' :
91                linewidthoptionvalue=string.atof(sys.argv[2])
92                linewidthoption=1
93                del(sys.argv[1])
94                del(sys.argv[1])
95        elif sys.argv[1] == '--showtitle' :
96                showtitleoptionvalue=True
97                showtitleoption=1
98                del(sys.argv[1])
99        elif sys.argv[1] == '--pattern' :
100                pattern=sys.argv[2].split(';')
101                patternoption=1
102                del(sys.argv[1])
103                del(sys.argv[1])
104        elif re.match('-',sys.argv[1]) :
105                print 'Error: option inconnu'
106                print usage + options
107                sys.exit(1)
108                break
109        else:
110                break
111
112if len(sys.argv[1:]) != 1 :
113        print usage + options
114        sys.exit(1)
115
116#======================================================
117fig = plt.figure()
118ax = fig.add_subplot(111)
119
120#======================================================
121nbfile=len(sys.argv[1:])/2
122
123#======================================================
124finput=file(sys.argv[1])
125
126simus_with_annotation=[]
127nbsimus=0
128nbfiles=0
129
130for line in finput :
131        print '#==========================================='
132        nbfiles=nbfiles+1
133
134        line=line.split(',')
135
136        #---------------------------
137        # options from command
138        fileruncard=line[0].strip() 
139
140        if not linecoloroption :
141                linecolor="%06X" % random.randint(0, 16777215)  # a random color for default
142        else :
143                linecolor=linecoloroptionvalue
144
145        if not linewidthoption :
146                linewidth=2.0
147        else :
148                linewidth=linewidthoptionvalue 
149
150        if fileruncard[0:4] == 'http' :
151                # remote file: http://
152                        # http://dods.idris.fr/login
153                if fileruncard[0:20] == 'http://dods.idris.fr' :
154                        title='.'.join(fileruncard.split('/')[3:-2])
155                else :
156                        # http://dods.extra.cea.fr/xxxx/login
157                        title='.'.join(fileruncard.split('/')[4:-2])
158        else : 
159                # local file: file://
160                title=os.path.basename(re.sub(r'_run.card',"",fileruncard))
161
162        if not showtitleoption :
163                showtitle=0
164        else :
165                showtitle=showtitleoptionvalue
166
167        #---------------------------
168        # options from pattern option
169        if patternoption :
170                for pat in pattern :
171                        pat=pat.split(',')
172                        patternword=pat[0].strip()
173                        if re.search(patternword,fileruncard) :
174                                patternoptions=pat[1:]
175                                for i in range(0,len(patternoptions)) :
176                                        exec patternoptions[i].strip()          # set options if defined
177
178        #---------------------------
179        # options from list file
180        for i in range(1,len(line)) :
181                #print i, line[i].strip()
182                exec line[i].strip()            # set options if defined
183
184        #---------------------------
185        print 'file = ', fileruncard
186        print 'linecolor = ', linecolor
187        print 'linewidth = ', linewidth
188        print 'title = ', title
189        print 'showtitle = ', showtitle
190
191        x,y1,y2 = [],[],[]
192        lineref=['# CumulPeriod | PeriodDateBegin |   PeriodDateEnd |        RunDateBegin |          RunDateEnd |     RealCpuTime |     UserCpuTime |      SysCpuTime | ExeDate']
193
194        try:
195                f=urllib2.urlopen(fileruncard)
196                csv_reader = csv.reader(f)
197                headerline = csv_reader.next()
198                while headerline != lineref :           # read until find lineref
199                        headerline = csv_reader.next()
200                # read an extra line
201                headerline = csv_reader.next()
202
203                nblines=0               
204                for line in csv_reader:
205                        a=line[0][1:]           # to remove first character=#
206                        part=a.split('|')
207
208                        PeriodDateBegin=dt.datetime.strptime(part[1].strip(),'%Y%m%d')
209                        CumulPeriod=int(part[0].strip())
210                        RunDateBegin=dt.datetime.strptime(part[3].strip(),'%Y-%m-%dT%H:%M:%S')
211                        RunDateEnd=dt.datetime.strptime(part[4].strip(),'%Y-%m-%dT%H:%M:%S')
212                        x.append(RunDateBegin)
213                        x.append(RunDateEnd)
214                        y1.append(PeriodDateBegin)
215                        y1.append(PeriodDateBegin)
216                        y2.append(CumulPeriod)
217                        y2.append(CumulPeriod)
218                        nblines=nblines+1
219
220                print '--> Read %d lines'%nblines
221                if nblines < 10 :
222                        print '----> File skipped (not enough lines < 10)'
223                        continue       
224
225                if not periodoption :
226                        y=y1
227                else :
228                        y=y2
229
230                simu,=ax.plot(x,y,'-', linewidth=linewidth, color='#'+linecolor)
231                lastx=x[-2] ; lasty=y[-2]               # before last (last is None)
232                simuname=fileruncard[:-9]               # remove _run.card
233                annotation=ax.annotate(title, xy=(lastx, lasty), xytext=(-20,20), 
234                    textcoords='offset points', ha='center', va='bottom',
235                    bbox=dict(boxstyle='round,pad=0.4', fc='yellow', alpha=0.3),
236                    arrowprops=dict(arrowstyle='->', connectionstyle='arc3', 
237                                    color='black'))
238
239                annotation.set_visible(showtitle)
240
241                if not showtitle :              # title will displayed when mouse over
242                        simus_with_annotation.append([simu,annotation])
243
244                nbsimus=nbsimus+1
245
246        except IOError :
247                print "======> IOError when reading run.card"
248                continue       
249
250        except :
251                print "======> Error when reading run.card"
252                continue       
253
254finput.close()
255
256#======================================================
257if nbsimus == 0 :
258        print '#==========================================='
259        print "======> No simulation to plot"
260        sys.exit(1)
261
262#======================================================
263# http://stackoverflow.com/questions/11537374/matplotlib-basemap-popup-box/11556140#11556140
264
265def on_move(event):
266    visibility_changed = False
267    for simu, annotation in simus_with_annotation:
268        should_be_visible = (simu.contains(event)[0] == True)
269
270        if should_be_visible != annotation.get_visible():
271            visibility_changed = True
272            x, y = event.xdata, event.ydata
273            annotation.xy = x, y
274            annotation.set_visible(should_be_visible)
275
276    if visibility_changed:       
277        plt.draw()
278
279#======================================================
280if not periodoption :
281        #from matplotlib.ticker import MaxNLocator
282        #ax.yaxis.set_major_locator(MaxNLocator(5))
283        from matplotlib.dates import YearLocator
284        ax.yaxis.set_major_locator(YearLocator(50))
285        #from matplotlib.dates import AutoDateLocator
286        #locator = AutoDateLocator(maxticks=5)
287        #ax.yaxis.set_major_locator(locator)
288        #ax.yaxis_date()
289
290else :                          # period option (not date)
291        if yscalelogoption :
292                ax.set_yscale('log')
293
294fig.autofmt_xdate()
295plt.grid(True)
296
297on_move_id = fig.canvas.mpl_connect('motion_notify_event', on_move)
298
299print '#==========================================='
300print 'Number of run.card indicated : %d' % nbfiles
301print 'Number of run.card processed : %d' % nbsimus
302print '#==========================================='
303
304plt.show()
305
306
Note: See TracBrowser for help on using the repository browser.