1 | #!/usr/bin/env python |
---|
2 | |
---|
3 | ### T.Navarro |
---|
4 | |
---|
5 | ## |
---|
6 | # This routine reads sparse data, i.e. not binned in a lat/lon/vert/time grid and does plots |
---|
7 | # |
---|
8 | # There is nothing gnuplot could not be able to do for now, except command line and ease and all python plots possibilities, |
---|
9 | # but the goal is to provide a framework to compare with data from simulations on a constant grid. |
---|
10 | ### |
---|
11 | |
---|
12 | ########################################################################################### |
---|
13 | ########################################################################################### |
---|
14 | ### What is below relate to running the file as a command line executable (very convenient) |
---|
15 | if __name__ == "__main__": |
---|
16 | import sys |
---|
17 | from optparse import OptionParser ### to be replaced by argparse |
---|
18 | from os import system,path |
---|
19 | from scipy.io.idl import readsav |
---|
20 | import numpy as np |
---|
21 | from myplot import separatenames, definesubplot, errormess, defcolorb, fmtvar, polarinterv, simplinterv, define_proj, readdata, makeplotres |
---|
22 | from mymath import min, max, writeascii |
---|
23 | import matplotlib as mpl |
---|
24 | from matplotlib.pyplot import subplot, figure, plot, scatter, colorbar, show, title, close, legend, xlabel, ylabel, axis, hist |
---|
25 | from matplotlib.cm import get_cmap |
---|
26 | from mpl_toolkits.mplot3d import Axes3D |
---|
27 | parser = OptionParser() |
---|
28 | |
---|
29 | ############################# |
---|
30 | ### Options |
---|
31 | parser.add_option('-f', '--file', action='store',dest='file', type="string", default=None, help='[NEEDED] filename, comma separated') |
---|
32 | parser.add_option('--ftype', action='store',dest='ftype', default=None, help=' Force data file type [\'sav\',\'txt\']') |
---|
33 | parser.add_option('-X', '--xvar', action='store',dest='xvar', type="string", default=None, help='[NEEDED] x variable: a name, a number, etc ...') |
---|
34 | parser.add_option('-Y', '--yvar', action='store',dest='yvar', type="string", default=None, help='y variable') |
---|
35 | parser.add_option('-Z', '--zvar', action='store',dest='zvar', type="string", default=None, help='z variable') |
---|
36 | parser.add_option('-C', '--cvar', action='store',dest='cvar', type="string", default=None, help='c variable for color') |
---|
37 | parser.add_option('--xmin', action='store',dest='xmin', type="float", default=None, help='min values for x var, comma separated') |
---|
38 | parser.add_option('--xmax', action='store',dest='xmax', type="float", default=None, help='max values for x var, comma separated') |
---|
39 | parser.add_option('--ymin', action='store',dest='ymin', type="float", default=None, help='min values for y var, comma separated') |
---|
40 | parser.add_option('--ymax', action='store',dest='ymax', type="float", default=None, help='max values for y var, comma separated') |
---|
41 | parser.add_option('--zmin', action='store',dest='zmin', type="float", default=None, help='min values for z var, comma separated') |
---|
42 | parser.add_option('--zmax', action='store',dest='zmax', type="float", default=None, help='max values for z var, comma separated') |
---|
43 | parser.add_option('--cmin', action='store',dest='cmin', type="string", default=None, help='min values for c var, comma separated') |
---|
44 | parser.add_option('--cmax', action='store',dest='cmax', type="string", default=None, help='max values for c var, comma separated') |
---|
45 | parser.add_option('-w','--with', action='append',dest='cond', type="string", default=None, help='conditions..') |
---|
46 | parser.add_option('--merge', action='store_true', dest='merge', default=False, help='merge datafiles in a single plot [False]') |
---|
47 | parser.add_option('-c','--color', action='store',dest='clb', type="string", default="def", help='change colormap (also: nobar,onebar)') |
---|
48 | parser.add_option('--trans', action='store',dest='trans', type="float", default=1., help='shaded plot transparency, 0 to 1 (=opaque) [1]') |
---|
49 | parser.add_option('-p', '--proj', action='store',dest='proj', type="string", default=None, help='projection') |
---|
50 | parser.add_option('--blat', action='store',dest='blat', type="int", default=None, help='reference lat (or bounding lat for stere) [computed]') |
---|
51 | parser.add_option('--blon', action='store',dest='blon', type="int", default=None, help='reference lon [computed]') |
---|
52 | parser.add_option('-b', '--back', action='store',dest='back', type="string", default=None, help='background image [None]') |
---|
53 | parser.add_option('-m', '--min', action='store',dest='vmin', type="float", default=None, help='bounding minimum value [min]') |
---|
54 | parser.add_option('-M', '--max', action='store',dest='vmax', type="float", default=None, help='bounding maximum value [max]') |
---|
55 | parser.add_option('--div', action='store',dest='ndiv', type="int", default=10, help='number of divisions in histogram [10]') |
---|
56 | parser.add_option('-S', '--save', action='store',dest='save', type="string", default="gui", help='save mode (gui,png,eps,svg,pdf,txt,html,avi) [gui]') |
---|
57 | |
---|
58 | |
---|
59 | ############################# |
---|
60 | ### Get options and variables |
---|
61 | (opt,args) = parser.parse_args() |
---|
62 | |
---|
63 | ############################# |
---|
64 | ### Load and check data |
---|
65 | |
---|
66 | ############################# |
---|
67 | ### Load and check data |
---|
68 | |
---|
69 | if opt.file is None: |
---|
70 | print "You must specify at least a file to process with -f." |
---|
71 | exit() |
---|
72 | if opt.xvar is None: |
---|
73 | print "You must specify at least a 1st field with -X." |
---|
74 | exit() |
---|
75 | if opt.proj is not None and opt.yvar is None: |
---|
76 | print "Why did you ask a projection with only one variable?" |
---|
77 | exit() |
---|
78 | |
---|
79 | filename=separatenames(opt.file) |
---|
80 | |
---|
81 | #print 'conditions', opt.cond |
---|
82 | |
---|
83 | print opt.vmax |
---|
84 | print opt.vmin |
---|
85 | |
---|
86 | if opt.cond is None: nslices = 1 |
---|
87 | else: nslices = len(opt.cond) |
---|
88 | numplot = nslices |
---|
89 | if opt.merge is False: numplot = numplot*len(filename) |
---|
90 | |
---|
91 | print ' ' |
---|
92 | if opt.merge is False: |
---|
93 | print nslices, 'condition(s) and', len(filename), 'file(s) without merging ---->', numplot, 'plot(s)' |
---|
94 | else: |
---|
95 | print nslices, 'condition(s) and', len(filename), 'file(s) with merging ---->', numplot, 'plot(s)' |
---|
96 | print ' ' |
---|
97 | |
---|
98 | all_type = [[]]*len(filename) |
---|
99 | all_x = [[]]*len(filename) |
---|
100 | all_y = [[]]*len(filename) |
---|
101 | all_z = [[]]*len(filename) |
---|
102 | all_c = [[]]*len(filename) |
---|
103 | all_data = [[]]*len(filename) |
---|
104 | #index = [[]]*len(filename) |
---|
105 | |
---|
106 | |
---|
107 | ############################## |
---|
108 | ################## READ DATA |
---|
109 | |
---|
110 | for k in range(len(filename)): |
---|
111 | |
---|
112 | ##### Find file type |
---|
113 | if opt.ftype is None: |
---|
114 | if filename[k].find('.sav') is not -1: |
---|
115 | all_type[k] ='sav' |
---|
116 | print '.sav file detected for', filename[k],'!!' |
---|
117 | elif filename[k].find('.txt') is not -1: |
---|
118 | all_type[k] ='txt' |
---|
119 | #print '.txt file detected for', filename[k],'!!' |
---|
120 | else: |
---|
121 | all_type[k] ='txt' |
---|
122 | print 'no file type detected for', filename[k],'!!, default type is', all_type[k] |
---|
123 | |
---|
124 | if all_type[k] != all_type[0]: |
---|
125 | print 'Two different types were used: ', all_type[k], all_type[0] |
---|
126 | errormess('Not suported') |
---|
127 | else: |
---|
128 | all_type[k] = opt.ftype |
---|
129 | |
---|
130 | ##### Read file |
---|
131 | if all_type[k] == 'sav': |
---|
132 | print 'reading .sav file', filename[k], '...' |
---|
133 | data = {} |
---|
134 | data = readsav(filename[k], idict=data, python_dict=False) #, verbose=True) |
---|
135 | all_data[k] = data |
---|
136 | elif all_type[k] == 'txt': |
---|
137 | print 'reading .text file', filename[k], '...' |
---|
138 | all_data[k] = np.loadtxt(filename[k]) |
---|
139 | |
---|
140 | all_x[k] = readdata(all_data,all_type[k],k,opt.xvar) |
---|
141 | if opt.yvar is not None: all_y[k] = readdata(all_data,all_type[k],k,opt.yvar) |
---|
142 | else: all_y[k] = None |
---|
143 | if opt.zvar is not None: all_z[k] = readdata(all_data,all_type[k],k,opt.zvar) |
---|
144 | else: all_z[k] = None |
---|
145 | if opt.cvar is not None: all_c[k] = readdata(all_data,all_type[k],k,opt.cvar) |
---|
146 | else: all_c[k] = None |
---|
147 | |
---|
148 | if opt.merge is True and k >=1 : |
---|
149 | all_x[0] = np.concatenate((all_x[0],all_x[k])) |
---|
150 | if opt.yvar is not None: all_y[0] = np.concatenate((all_y[0],all_y[k])) |
---|
151 | if opt.zvar is not None: all_z[0] = np.concatenate((all_z[0],all_z[k])) |
---|
152 | if opt.cvar is not None: all_c[0] = np.concatenate((all_c[0],all_c[k])) |
---|
153 | |
---|
154 | |
---|
155 | |
---|
156 | ############################## |
---|
157 | ################## PLOT DATA |
---|
158 | |
---|
159 | ## Open a figure and set subplots |
---|
160 | fig = figure() |
---|
161 | subv,subh = definesubplot(numplot,fig) |
---|
162 | palette = get_cmap(name=opt.clb) |
---|
163 | |
---|
164 | |
---|
165 | for nplot in range(numplot): |
---|
166 | |
---|
167 | print ' ' |
---|
168 | |
---|
169 | ###### Find which data and which file for plot nplot |
---|
170 | if opt.merge is False: |
---|
171 | index_s = ((nplot)//len(filename))%nslices |
---|
172 | index_f = ((nplot-1)//nslices)%len(filename) |
---|
173 | else: |
---|
174 | index_s = ((nplot)//1)%nslices |
---|
175 | index_f = ((nplot-1)//nslices)%1 |
---|
176 | #print 'nplot,numplot,index_f,index_s', nplot,numplot,index_f,index_s |
---|
177 | |
---|
178 | |
---|
179 | ###### Select point under conditions defined in -w option |
---|
180 | index = np.isfinite(all_x[index_f]) |
---|
181 | if opt.cond is not None: |
---|
182 | zecond = separatenames(opt.cond[index_s]) |
---|
183 | #print 'hello', opt.cond[index_s], zecond |
---|
184 | for i in range(len(zecond)): |
---|
185 | zecondi = zecond[i] |
---|
186 | if zecondi.find('>') != -1: |
---|
187 | variable = zecondi[0:zecondi.find('>')] |
---|
188 | value = float(zecondi[zecondi.find('>')+1:len(zecondi)]) |
---|
189 | if opt.merge is True: # ultra moche de reconcatener a chaque fois, mais bon on s'en fout c'est du python |
---|
190 | zedata = [] |
---|
191 | for k in range(len(filename)): |
---|
192 | zedata = np.concatenate((zedata,readdata(all_data,all_type[k],k,variable))) |
---|
193 | else : zedata = readdata(all_data,all_type[k],index_f,variable) |
---|
194 | #print index.shape,zedata.shape, value |
---|
195 | index = index*(zedata>value) |
---|
196 | print 'All points such as', variable, '>', value, 'have been selected' |
---|
197 | elif zecondi.find('<') != -1: |
---|
198 | variable = zecondi[0:zecondi.find('<')] |
---|
199 | value = float(zecondi[zecondi.find('<')+1:len(zecondi)]) |
---|
200 | if opt.merge is True: |
---|
201 | zedata = [] |
---|
202 | for k in range(len(filename)): |
---|
203 | zedata = np.concatenate((zedata,readdata(all_data,all_type[k],k,variable))) |
---|
204 | else : zedata = readdata(all_data,all_type[k],index_f,variable) |
---|
205 | #print index.shape,zedata.shape, value |
---|
206 | index = index*(zedata<value) |
---|
207 | print 'All points such as', variable, '<', value, 'have been selected' |
---|
208 | else: |
---|
209 | print '' |
---|
210 | print 'I do not understand that condition :', zecondi |
---|
211 | errormess('') |
---|
212 | |
---|
213 | |
---|
214 | if np.sum(index) == 0: |
---|
215 | print '*********** WARNING ***********' |
---|
216 | print '*********** NO DATA ***********' |
---|
217 | errormess('') |
---|
218 | else: |
---|
219 | print np.sum(index),'points have been selected among', len(all_x[index_f]), \ |
---|
220 | 'that is to say %2.2f' %(float(100*np.sum(index))/float(len(all_x[index_f]))), '%.' |
---|
221 | |
---|
222 | |
---|
223 | #print 'numplot', numplot |
---|
224 | changesubplot = (numplot > 1) #and (len(what_I_plot.shape) != 1) |
---|
225 | if changesubplot: subplot(subv,subh,nplot+1) |
---|
226 | #print 'subv,subh,nplot', subv,subh,nplot |
---|
227 | |
---|
228 | ###### Projection |
---|
229 | if opt.proj is not None: # Nota : NEVER TRY TO DO A MESHGRID ON SPARSE DATA. WAY TOO MUCH POINTS. |
---|
230 | wlon = [min(all_x[index_f][index]),max(all_x[index_f][index])] |
---|
231 | wlat = [min(all_y[index_f][index]),max(all_y[index_f][index])] |
---|
232 | m = define_proj(opt.proj,wlon,wlat,back=opt.back,blat=opt.blat,blon=opt.blon) |
---|
233 | x, y = m(all_x[index_f][index],all_y[index_f][index]) |
---|
234 | else: |
---|
235 | x = all_x[index_f][index] |
---|
236 | if opt.yvar is not None: y = all_y[index_f][index] |
---|
237 | |
---|
238 | ###### Plot: 1D histogram |
---|
239 | if opt.yvar is None: |
---|
240 | hist(x,bins=opt.ndiv,histtype='step',linewidth=2) |
---|
241 | if opt.save == 'txt': |
---|
242 | print 'saving file profile'+str(nplot+1)+'.txt' |
---|
243 | writeascii(np.transpose(x),'profile'+str(nplot+1)+'.txt') |
---|
244 | ###### Plot: 2D cloud |
---|
245 | elif opt.zvar is None and opt.cvar is None : |
---|
246 | plot(x,y,'.b') |
---|
247 | if opt.save == 'txt': |
---|
248 | print 'saving file profile'+str(nplot+1)+'.txt' |
---|
249 | writeascii(np.transpose(np.array([x,y])),'profile'+str(nplot+1)+'.txt') |
---|
250 | ###### Plot: 2D cloud with color |
---|
251 | elif opt.zvar is None and opt.cvar is not None : |
---|
252 | if opt.save == 'txt': |
---|
253 | print 'saving file profile'+str(nplot+1)+'.txt' |
---|
254 | writeascii(np.transpose(np.array([x,y,all_c[index_f][index]])),'profile'+str(nplot+1)+'.txt') |
---|
255 | scatter(x,y,c=all_c[index_f][index],\ |
---|
256 | marker='o', edgecolor='None',cmap = palette, alpha=opt.trans, vmin = opt.vmin,vmax = opt.vmax) |
---|
257 | ###### Plot: 3D cloud |
---|
258 | elif opt.zvar is not None and opt.cvar is None : |
---|
259 | ax = fig.add_subplot(subv,subh,nplot+1, projection='3d') |
---|
260 | ax.plot(x,y,all_z[index_f][index],'.b') |
---|
261 | ###### Plot: 3D cloud with color |
---|
262 | else : |
---|
263 | ax = fig.add_subplot(subv,subh,nplot+1, projection='3d') |
---|
264 | ax.scatter(x,y,all_z[index_f][index],c=all_c[index_f][index],\ |
---|
265 | marker='o', edgecolor='None', cmap = palette, alpha=opt.trans,vmin = opt.vmin,vmax = opt.vmax) |
---|
266 | |
---|
267 | ###### Colorbar: http://www.scipy.org/Cookbook/Matplotlib/Show_colormaps?action=AttachFile&do=get&target=colormaps3.png |
---|
268 | if opt.clb != 'nobar' and all_c[index_f] is not None and all_z[index_f] is None: # pourquoi la colorbar marche pas en 3d? |
---|
269 | colorbar( fraction=0.05,pad=0.03,format='%0.2f',\ |
---|
270 | extend='neither',spacing='proportional' ) |
---|
271 | |
---|
272 | ###### Plot limits (options --xmin, --xmax, etc ..) |
---|
273 | if opt.proj is None: |
---|
274 | xlabel(opt.xvar) |
---|
275 | ylabel(opt.yvar) |
---|
276 | if opt.zvar is None : |
---|
277 | if opt.xmin is not None: mpl.pyplot.xlim(xmin=opt.xmin) |
---|
278 | else: mpl.pyplot.xlim(xmin=min(all_x[index_f][index])) |
---|
279 | if opt.xmax is not None: mpl.pyplot.xlim(xmax=opt.xmax) |
---|
280 | else: mpl.pyplot.xlim(xmax=max(all_x[index_f][index])) |
---|
281 | if opt.yvar is not None: |
---|
282 | if opt.ymin is not None: mpl.pyplot.ylim(ymin=opt.ymin) |
---|
283 | else: mpl.pyplot.ylim(ymin=min(all_y[index_f][index])) |
---|
284 | if opt.ymax is not None: mpl.pyplot.ylim(ymax=opt.ymax) |
---|
285 | else: mpl.pyplot.ylim(ymax=max(all_y[index_f][index])) |
---|
286 | |
---|
287 | |
---|
288 | if opt.cond is not None: |
---|
289 | title(opt.cond[index_s]) |
---|
290 | else: |
---|
291 | title('all point selected') |
---|
292 | |
---|
293 | zeplot = "output" |
---|
294 | if opt.save in ['png','eps','svg','pdf']: makeplotres(zeplot,ext=opt.save)#,res=resolution,pad_inches_value=pad_inches_value,disp=False,ext=save) |
---|
295 | elif opt.save == 'gui': show() |
---|
296 | else: print "INFO: save mode not supported. using gui instead." ; show() |
---|
297 | print '' |
---|
298 | |
---|
299 | command = "" |
---|
300 | for arg in sys.argv: command = command + arg + ' ' |
---|
301 | name = zeplot |
---|
302 | f = open(name+'.sh', 'w') |
---|
303 | f.write(command) |
---|
304 | |
---|
305 | |
---|
306 | |
---|
307 | |
---|
308 | |
---|