| 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 | |
|---|