[1124] | 1 | ##### Python to plot multiple plots at the same time in a panel |
---|
| 2 | # L. Fita, LMD September 2016 |
---|
| 3 | ## e.g. # multi_plot.py -f multi_plot.dat -o multi_plot -d True -s True |
---|
| 4 | import os |
---|
| 5 | import subprocess as sub |
---|
| 6 | import numpy as np |
---|
| 7 | from netCDF4 import Dataset as NetCDFFile |
---|
| 8 | import matplotlib.pyplot as plt |
---|
| 9 | import nc_var_tools as ncvar |
---|
| 10 | import drawing_tools as drw |
---|
| 11 | import generic_tools as gen |
---|
| 12 | import drawing as DrW |
---|
| 13 | import matplotlib as mpl |
---|
| 14 | from optparse import OptionParser |
---|
| 15 | |
---|
| 16 | main='multi_plot.py' |
---|
| 17 | |
---|
| 18 | errormsg='ERROR -- error -- ERROR -- error' |
---|
| 19 | warnmsg='WARNING -- warning -- WARNING -- warning' |
---|
| 20 | |
---|
| 21 | class values_figure(object): |
---|
| 22 | """ Class with the values to plot a figure |
---|
| 23 | self.files= list with the files to use |
---|
| 24 | self.vals= values to use for the plot |
---|
| 25 | self.vars= list with the variables to use |
---|
| 26 | """ |
---|
| 27 | |
---|
| 28 | def __init__(self,files,vals,varns): |
---|
| 29 | self.files = files |
---|
| 30 | self.vals = vals |
---|
| 31 | self.vars = varns |
---|
| 32 | |
---|
| 33 | ####### ###### ##### #### ### ## # |
---|
| 34 | fix_multiplot_conf = ['title','kind','panel'] |
---|
| 35 | |
---|
| 36 | parser = OptionParser() |
---|
| 37 | parser.add_option("-d", "--debug", dest="debug", |
---|
| 38 | help="debug ('true'/'false')", metavar="VALUE") |
---|
| 39 | parser.add_option("-f", "--file_configuration", dest="fileconf", help="configuration file to use", |
---|
| 40 | metavar="FILE") |
---|
| 41 | parser.add_option("-o", "--output_name", dest="oname", |
---|
| 42 | help="name of the output figure (without extension)", metavar="LABEL") |
---|
| 43 | parser.add_option("-s", "--seeFigure", dest="seefig", |
---|
| 44 | help="see resultan figure ('true'/'false')", metavar="VALUE") |
---|
| 45 | |
---|
| 46 | (opts, args) = parser.parse_args() |
---|
| 47 | |
---|
| 48 | ####### ####### |
---|
| 49 | ## MAIN |
---|
| 50 | ####### |
---|
| 51 | |
---|
| 52 | if opts.debug is None: |
---|
| 53 | print warnmsg |
---|
| 54 | print ' ' + main + ": no debug provided!!" |
---|
| 55 | print " give a value for the option '-d/--debug'" |
---|
| 56 | print " debug ('true'/'false')" |
---|
| 57 | print " Assuming 'false'" |
---|
| 58 | dbg=False |
---|
| 59 | else: |
---|
| 60 | dbg=gen.Str_Bool(opts.debug) |
---|
| 61 | |
---|
| 62 | if opts.fileconf is None: |
---|
| 63 | print errormsg |
---|
| 64 | print ' ' + main + ": no configuration file provided!!" |
---|
| 65 | print " give a value for the option '-f/--file_configuration'" |
---|
| 66 | print " configuration file to use" |
---|
| 67 | quit(-1) |
---|
| 68 | |
---|
| 69 | if not os.path.isfile(opts.fileconf): |
---|
| 70 | print errormsg |
---|
| 71 | print ' '+main+": configuration file '" + opts.fileconf + "' does not exist!!" |
---|
| 72 | quit(-1) |
---|
| 73 | |
---|
| 74 | if opts.oname is None: |
---|
| 75 | print warnmsg |
---|
| 76 | print ' ' + main + ": no output figure name provided!!" |
---|
| 77 | print " give a value for the option '-o/--output_name'" |
---|
| 78 | print " name of the output figure (without extension)" |
---|
| 79 | print " Assuming 'multi_plot'" |
---|
| 80 | oname='multi_plot' |
---|
| 81 | else: |
---|
| 82 | oname=opts.oname |
---|
| 83 | |
---|
| 84 | if opts.seefig is None: |
---|
| 85 | print warnmsg |
---|
| 86 | print ' ' + main + ": no seeing figure provided!!" |
---|
| 87 | print " give a value for the option '-s/--seeFigure'" |
---|
| 88 | print " see resultan figure ('true'/'false')" |
---|
| 89 | print " Assuming 'false'" |
---|
| 90 | seefig=False |
---|
| 91 | else: |
---|
| 92 | seefig=gen.Str_Bool(opts.seefig) |
---|
| 93 | |
---|
| 94 | |
---|
| 95 | # Reading configuration file |
---|
| 96 | # File strcture must be as follows |
---|
| 97 | # fig_title: Title of the figure ('!') for spaces (None for no title) |
---|
| 98 | # fig_panel: [Ncol],[Nrow] panel of figures with Ncolumns and Nrows |
---|
| 99 | # fig_kind: kind of the output figure (None, png) |
---|
| 100 | # kind: [graphic_label] (from drawing.py) |
---|
| 101 | # file: [file1],[file2],...,[fileN] (',' list of files if required) |
---|
| 102 | # values: Specific values for this graphic (in same format as in [graphic_label] |
---|
| 103 | # variables: [var1],[var2],....,[varN] (',' list of variables if required) |
---|
| 104 | # Figures will be draw consecutively as they appear in the file |
---|
| 105 | |
---|
| 106 | # Dictionary with the figures to plot and their values kepts in a class |
---|
| 107 | figures = {} |
---|
| 108 | |
---|
| 109 | # List of the names of the figures as they appear in the file |
---|
| 110 | figns = [] |
---|
| 111 | |
---|
| 112 | # List of the names of the variables as they appear in the file |
---|
| 113 | varns = [] |
---|
| 114 | |
---|
| 115 | # Dictionary with the number of times that a given graphic appears in the panel |
---|
| 116 | Nfigs = {} |
---|
| 117 | |
---|
| 118 | oconf = open(opts.fileconf) |
---|
| 119 | kindn = None |
---|
| 120 | kindnow = None |
---|
| 121 | variables = None |
---|
| 122 | for line in oconf: |
---|
| 123 | if line[0:1] != '#' and len(line) > 1 and line.find(':') != -1: |
---|
| 124 | label = line.split(':')[0].replace(' ','') |
---|
| 125 | vals = line.split(':')[1].replace('\n','') |
---|
| 126 | if label == 'fig_title': figures['title'] = vals |
---|
| 127 | elif label == 'fig_panel': |
---|
| 128 | vals0 = vals.replace(' ','').split(',') |
---|
| 129 | figures['panel']=[int(vals0[0]), int(vals0[1])] |
---|
| 130 | elif label == 'fig_kind': |
---|
| 131 | if vals == 'None': figures['kind'] = png |
---|
| 132 | else: figures['kind'] = vals.replace(' ','') |
---|
| 133 | elif label == 'kind': kindn = vals.replace(' ','') + '@0' |
---|
| 134 | elif label == 'file': files = gen.str_list(vals.replace(' ',''),',') |
---|
| 135 | elif label == 'values': |
---|
| 136 | Lvalues = len('values:') |
---|
| 137 | Lline = len(line) |
---|
| 138 | values = line[Lvalues:Lline - Lvalues + 1] |
---|
| 139 | elif label == 'variables': variables = gen.str_list(vals.replace(' ',''),',') |
---|
| 140 | else: |
---|
| 141 | print errormsg |
---|
| 142 | print ' ' + main + ": configuration label '" + label + "' not ready !!" |
---|
| 143 | quit(-1) |
---|
| 144 | |
---|
| 145 | if kindn is not None and kindn != kindnow and variables is not None: |
---|
| 146 | if kindnow is None: |
---|
| 147 | kindnow = kindn.split('@')[0] |
---|
| 148 | else: |
---|
| 149 | kindnow = kindnow.split('@')[0] |
---|
| 150 | |
---|
| 151 | if dbg: |
---|
| 152 | print ' ' + main + ": adding in panel: '" + kindnow + "'... " |
---|
| 153 | print ' files:', files |
---|
| 154 | print ' values:', values |
---|
| 155 | print ' variables:', variables |
---|
| 156 | |
---|
| 157 | varns.append(':'.join(values)) |
---|
| 158 | if Nfigs.has_key(kindnow): |
---|
| 159 | N = Nfigs[kindnow] |
---|
| 160 | Nfigs[kindnow] = N + 1 |
---|
| 161 | else: |
---|
| 162 | Nfigs[kindnow] = 1 |
---|
| 163 | |
---|
| 164 | labf = kindnow + '@' + str(Nfigs[kindnow]) |
---|
| 165 | figns.append(labf) |
---|
| 166 | if dbg: |
---|
| 167 | print " added as '" + labf + "'" |
---|
| 168 | |
---|
| 169 | figures[labf] = values_figure(files,values,variables) |
---|
| 170 | |
---|
| 171 | kindnow = kindn+'@-1' |
---|
| 172 | variables = None |
---|
| 173 | |
---|
| 174 | oconf.close() |
---|
| 175 | |
---|
| 176 | if dbg: |
---|
| 177 | print ' ' + main + " General figure configuration _______" |
---|
| 178 | for ff in fix_multiplot_conf: |
---|
| 179 | print ' ' + ff + ': ', figures[ff] |
---|
| 180 | |
---|
| 181 | for ff in figns: |
---|
| 182 | if not gen.searchInlist(fix_multiplot_conf,ff): |
---|
| 183 | print " '" + ff + "' _______" |
---|
| 184 | gen.printing_class(figures[ff]) |
---|
| 185 | |
---|
| 186 | panelval = figures['panel'] |
---|
| 187 | if np.prod(panelval) != len(figns): |
---|
| 188 | print errormsg |
---|
| 189 | print ' ' + main + ': then number of plots=',len(figns),'not suits the panel=', \ |
---|
| 190 | figures['panel'] |
---|
| 191 | print ' figures to plot:',figns |
---|
| 192 | quit(-1) |
---|
| 193 | |
---|
| 194 | # |
---|
| 195 | ## Plotting |
---|
| 196 | # |
---|
| 197 | plt.rc('text', usetex=True) |
---|
| 198 | |
---|
| 199 | fig, axes = plt.subplots(panelval[0],panelval[1]) |
---|
| 200 | |
---|
| 201 | ifig = 1 |
---|
| 202 | for ff in figns: |
---|
| 203 | isubplot = gen.index_flatten_mat(ifig,list(panelval)) |
---|
| 204 | isubplot = isubplot + 1 |
---|
| 205 | if dbg: |
---|
| 206 | print ' ' + main + " adding in graph '" + ff + "' in ", isubplot, "..." |
---|
| 207 | graphinf = figures[ff] |
---|
| 208 | graphlab = ff.split('@')[0] |
---|
| 209 | plt.subplot(panelval[0],panelval[1],ifig) |
---|
| 210 | |
---|
| 211 | if graphlab == 'draw_2D_shad': |
---|
| 212 | Files = graphinf.files[0] |
---|
| 213 | Vals = graphinf.vals+':False' |
---|
| 214 | Vars = graphinf.vars[0] |
---|
| 215 | |
---|
| 216 | DrW.draw_2D_shad(Files,Vals,Vars) |
---|
| 217 | |
---|
| 218 | elif graphlab == 'direc_draw_2D_shad': |
---|
| 219 | Files = graphinf.files[0] |
---|
| 220 | if not os.path.isfile(Files): |
---|
| 221 | print errormsg |
---|
| 222 | print ' '+main+": netcdf file with data '" + Files + "' does not exist!!" |
---|
| 223 | quit(-1) |
---|
| 224 | |
---|
| 225 | Vals = graphinf.vals.split(':') |
---|
| 226 | |
---|
| 227 | ncf = NetCDFFile(Files,'r') |
---|
| 228 | ovar = ncf.variables[graphinf.vars[0]] |
---|
| 229 | |
---|
| 230 | dictslice = {} |
---|
| 231 | for dmn in Vals[1].split(','): |
---|
| 232 | dn = dmn.split('|')[0] |
---|
| 233 | dv = int(dmn.split('|')[1]) |
---|
| 234 | dictslice[dn] = dv |
---|
| 235 | |
---|
| 236 | slicevar, slicedims = ncvar.SliceVarDict(ovar,dictslice) |
---|
| 237 | |
---|
| 238 | Vars = ovar[tuple(slicevar)] |
---|
| 239 | ncf.close() |
---|
| 240 | |
---|
| 241 | CFname = Vals[0].replace(' ','') |
---|
| 242 | dimxn = Vals[2] |
---|
| 243 | dimyn = Vals[3] |
---|
| 244 | colorbar = Vals[4] |
---|
| 245 | minv = np.float(Vals[5].split(',')[0]) |
---|
| 246 | maxv = np.float(Vals[5].split(',')[1]) |
---|
| 247 | titgraph = Vals[6].replace('|',' ') |
---|
| 248 | |
---|
| 249 | varvu = gen.variables_values(CFname)[5] |
---|
| 250 | dimxu = gen.variables_values(dimxn)[5] |
---|
| 251 | dimyu = gen.variables_values(dimyn)[5] |
---|
| 252 | |
---|
| 253 | # Plot itself |
---|
| 254 | plt.rc('text', usetex=True) |
---|
| 255 | plt.pcolormesh(Vars, cmap=plt.get_cmap(colorbar), vmin=minv, vmax=maxv) |
---|
| 256 | cbar = plt.colorbar() |
---|
| 257 | cbar.set_label(CFname + ' (' + drw.units_lunits(varvu) + ')') |
---|
| 258 | plt.title(titgraph) |
---|
| 259 | plt.xlabel(dimxn + ' (' + drw.units_lunits(dimxu) + ')') |
---|
| 260 | plt.ylabel(dimyn + ' (' + drw.units_lunits(dimyu) + ')') |
---|
| 261 | |
---|
| 262 | else: |
---|
| 263 | print errormsg |
---|
| 264 | print ' ' + main + ": kind of figure '" + graphlab + "' not ready !!" |
---|
| 265 | ifig = ifig+1 |
---|
| 266 | |
---|
| 267 | fig.suptitle(figures['title'].replace('!',' ')) |
---|
| 268 | |
---|
| 269 | figname = opts.oname + '.' + figures['kind'] |
---|
| 270 | sub.call('rm ' + figname + ' >& /dev/null', shell=True) |
---|
| 271 | plt.savefig(figname) |
---|
| 272 | print main + " succesfull drawing of figure '" + figname + "' !!" |
---|
| 273 | if seefig: |
---|
| 274 | if figures['kind'] == 'pdf': |
---|
| 275 | sub.call('evince ' + figname + ' &', shell=True) |
---|
| 276 | else: |
---|
| 277 | sub.call('display ' + figname + ' &', shell=True) |
---|
| 278 | |
---|