3 from copy
import deepcopy
6 import matplotlib.pyplot
as plt
7 from mpl_toolkits.axes_grid1
import make_axes_locatable
8 import matplotlib.axes
as maxes
11 import basic_plot_functions
14 import var_utils
as vu
20 │ ├── obsout_3denvar_bump_sondes_0000.nc4
21 │ ├── obsout_3denvar_bump_sondes_0001.nc4
24 │ ├── plot_diag_omaomb.py
25 │ ├── basic_plot_functions.py
31 'air_temperature': [
'(K)',
'T' ] \
32 ,
'virtual_temperature': [
'(K)',
'Tv' ] \
33 ,
'eastward_wind': [
'(m/s)',
'U' ] \
34 ,
'northward_wind': [
'(m/s)',
'V' ] \
35 ,
'specific_humidity': [
'(kg/kg)',
'Q' ] \
36 ,
'refractivity': [
'(%)',
'Ref' ] \
37 ,
'bending_angle': [
'(%)',
'Bnd' ] \
38 ,
'brightness_temperature': [
'(K)',
'BT' ] \
39 ,
'surface_pressure': [
'(Pa)',
'Ps' ] \
50 plot_allinOneDistri =
True
51 plot_eachLevelDistri =
True
76 all_groups.append(profile_group)
77 all_groups.append(sfc_group)
78 all_groups.append(radiance_group)
82 diagprefix =
'obsout_'
97 NOUTER=str(os.getenv(
'NOUTER',2))
98 qcbg_var =
'EffectiveQC0'
99 qcan_var =
'EffectiveQC'+NOUTER
102 errstart_var =
'EffectiveError0'
103 errend_var =
'EffectiveError'+NOUTER
105 for files
in os.listdir(diagdir):
107 if fnmatch.fnmatch(files, diagprefix+
'*'+diagsuffix):
108 obsoutfiles.append(diagdir+files)
115 for j, file_name
in enumerate(obsoutfiles):
117 exob_group_name =
'_'.join(file_name.split(
"_")[1:][:-1])
118 for i, exob_group
in enumerate(exob_groups):
119 if exob_group_name
in exob_group:
121 update_group = exob_group
122 update_group.append(file_name)
123 exob_groups[i][:] = update_group
125 elif i == len(exob_groups)-1:
127 new_group = [exob_group_name]
128 new_group.append(file_name)
129 exob_groups.append(new_group)
131 exob_groups = exob_groups[1:][:]
134 for exob_group
in exob_groups:
135 expt_obs = exob_group[0]
139 expt_parts = expt_obs.split(
"_")
140 nstr = len(expt_parts)
142 for i
in range(0,nstr):
143 obstype_ =
'_'.join(expt_parts[i:nstr])
144 for group
in all_groups:
145 if ''.join(obstype_)
in group:
148 if obstype ==
'none':
149 print(
'obstype not selected, skipping data: '+expt_obs)
153 nc = h5.File(exob_group[1],
'r')
156 if type(nc[node])
is h5._hl.group.Group:
158 varlist += [node+
'/'+var]
160 bglist = [var
for var
in varlist
if (var[:][:5] == depbg_var)]
162 if ''.join(obstype)
in radiance_group:
164 for bgname
in bglist:
165 var =
''.join(bgname.split(
"/")[1:])
166 chlist = nc[
'nchans']
167 ObsSpaceInfo = conf.DiagSpaceConfig.get(obstype,conf.nullDiagSpaceInfo)
168 channels = ObsSpaceInfo.get(
'channels',[vu.miss_i])
172 for ivar, depbg
in enumerate(bglist):
173 varname =
''.join(depbg.split(
"/")[1:])
174 obs=obs_var+
'/'+
''.join(depbg.split(
"/")[1:])
175 depan=depan_var+
'/'+
''.join(depbg.split(
"/")[1:])
176 qcb = qcbg_var+
'/'+
''.join(depbg.split(
"/")[1:])
177 qca = qcan_var+
'/'+
''.join(depbg.split(
"/")[1:])
178 obserror = err_obs+
'/'+
''.join(depbg.split(
"/")[1:])
179 errstart = errstart_var+
'/'+
''.join(depbg.split(
"/")[1:])
180 errend = errend_var+
'/'+
''.join(depbg.split(
"/")[1:])
181 print(
"obs=",obs,
"depbg=",depbg,
"depan=",depan)
183 obsnc = np.asarray([])
184 bkgnc = np.asarray([])
185 ananc = np.asarray([])
186 ombnc = np.asarray([])
187 omanc = np.asarray([])
188 qcbnc = np.asarray([])
189 qcanc = np.asarray([])
190 prenc = np.asarray([])
191 latnc = np.asarray([])
192 lonnc = np.asarray([])
193 recordNum_baknc = np.asarray([])
194 recordNum_ananc = np.asarray([])
195 stationId_baknc = np.asarray([])
196 stationId_ananc = np.asarray([])
197 obserrornc = np.asarray([])
198 errstartnc = np.asarray([])
199 errendnc = np.asarray([])
202 for file_name
in exob_group[1:]:
203 nc = h5.File(file_name,
'r')
204 if ''.join(obstype)[:6] ==
'gnssro':
205 prenc = np.append(prenc, nc[
'MetaData/altitude'])
206 station_id = nc[
'MetaData/occulting_sat_id']
207 recordNum = nc[
'MetaData/record_number']
208 recordNum_baknc = np.append( recordNum_baknc, recordNum)
209 recordNum_ananc = np.append( recordNum_ananc, recordNum)
210 elif ''.join(obstype)
not in radiance_group:
211 tmp = nc[
'MetaData/air_pressure']
212 if np.max(tmp) > 10000.0:
213 tmp = np.divide(tmp,100.0)
214 prenc = np.append( prenc, tmp )
215 station_id = nc[
'MetaData/station_id']
216 station_id = [
''.join(i[0:5])
for i
in nc[
'MetaData/station_id'][:]]
217 stationId_baknc = np.append( stationId_baknc, station_id )
218 stationId_ananc = np.append( stationId_ananc, station_id )
219 obsnc = np.append( obsnc, nc[obs] )
220 ombnc = np.append( ombnc, np.negative( nc[depbg] ) )
221 omanc = np.append( omanc, np.negative( nc[depan] ) )
222 qcbnc = np.append( qcbnc, nc[qcb] )
223 qcanc = np.append( qcanc, nc[qca] )
224 obserrornc = np.append(obserrornc, nc[obserror])
225 errstartnc = np.append(errstartnc, nc[errstart])
226 errendnc = np.append(errendnc, nc[errend])
227 latnc = np.append( latnc, nc[
'MetaData/latitude'] )
228 lonnc = np.append( lonnc, nc[
'MetaData/longitude'] )
229 bkgnc = obsnc - ombnc
230 ananc = obsnc - omanc
234 obsnc[qcbnc != 0] = np.NaN
235 ombnc[np.less(ombnc,-1.0e+15)] = np.NaN
236 ombnc[qcbnc != 0] = np.NaN
237 omanc[np.less(omanc,-1.0e+15)] = np.NaN
238 omanc[qcanc != 0] = np.NaN
239 bkgnc[np.less(bkgnc,-1.0e+15)] = np.NaN
240 bkgnc[qcbnc != 0] = np.NaN
241 ananc[np.less(ananc,-1.0e+15)] = np.NaN
242 ananc[qcanc != 0] = np.NaN
243 obserrornc[qcbnc != 0] = np.NaN
244 errstartnc[qcbnc != 0] = np.NaN
245 errendnc[qcanc != 0] = np.NaN
246 if ''.join(obstype)
not in radiance_group:
247 stationId_baknc[qcbnc != 0] = np.NaN
248 stationId_ananc[qcanc != 0] = np.NaN
249 if ''.join(obstype)[:6] ==
'gnssro':
250 recordNum_baknc[qcbnc != 0] = np.NaN
251 recordNum_ananc[qcanc != 0] = np.NaN
252 if np.isnan(ombnc).all() ==
True:
253 print(
'all values are NaN in', varname, obstype)
256 if ''.join(obstype)[:6] ==
'gnssro':
257 ombnc = (ombnc/obsnc)*100
258 omanc = (omanc/obsnc)*100
260 if ''.join(obstype)
not in radiance_group:
261 if (plot_allinOneDistri):
262 if ''.join(obstype)[:6] ==
'gnssro':
263 n_stationId_bak = len(np.unique(stationId_baknc[~np.isnan(stationId_baknc)]))
264 n_stationId_ana = len(np.unique(stationId_ananc[~np.isnan(stationId_ananc)]))
265 n_record_bak = len(np.unique(recordNum_baknc[~np.isnan(recordNum_baknc)]))
266 n_record_ana = len(np.unique(recordNum_ananc[~np.isnan(recordNum_ananc)]))
268 if 'nan' in stationId_baknc:
269 n_stationId_bak = len(set(stationId_baknc)) -1
271 n_stationId_bak = len(set(stationId_baknc))
272 if 'nan' in stationId_ananc:
273 n_stationId_ana = len(set(stationId_ananc)) -1
275 n_stationId_ana = len(set(stationId_ananc))
278 if ''.join(obstype)[:6] ==
'gnssro':
285 if ''.join(obstype)
in profile_group:
297 if ''.join(obstype)[:6] ==
'gnssro':
298 bins = list(np.arange(50000.0, -1000, -2000.))
299 binsfory= list(np.arange(49500.0,-500.0,-2000.))
301 bins = [1050.,950.,850.,750.,650.,550.,450.,350.,250.,150.,50.,0.]
302 binsfory= [1000.,900.,800.,700.,600.,500.,400.,300.,200.,100.,0]
303 bins = np.asarray(bins)
305 ombnum = len(ombnc)-np.isnan(ombnc).sum()
306 ombnums = np.append(ombnums,ombnum)
308 omanum = len(omanc)-np.isnan(omanc).sum()
309 omanums = np.append(omanums,omanum)
311 for j
in range(0, len(bins)-1):
313 obsncbin = deepcopy(obsnc)
314 ombncbin = deepcopy(ombnc)
315 omancbin = deepcopy(omanc)
316 latncbin = deepcopy(latnc)
317 lonncbin = deepcopy(lonnc)
318 obserrorbin = deepcopy(obserrornc)
319 errstartbin = deepcopy(errstartnc)
320 errendbin = deepcopy(errendnc)
321 stationbin_bak = deepcopy(stationId_baknc)
322 stationbin_ana = deepcopy(stationId_ananc)
323 recordbin_bak = deepcopy(recordNum_baknc)
324 recordbin_ana = deepcopy(recordNum_ananc)
326 obsncbin[np.logical_or(prenc <bins[j+1], prenc >=bins[j])] = np.NaN
327 ombncbin[np.logical_or(prenc <bins[j+1], prenc >=bins[j])] = np.NaN
328 omancbin[np.logical_or(prenc <bins[j+1], prenc >=bins[j])] = np.NaN
329 latncbin[np.logical_or(prenc <bins[j+1], prenc >=bins[j])] = np.NaN
330 lonncbin[np.logical_or(prenc <bins[j+1], prenc >=bins[j])] = np.NaN
331 stationbin_bak[np.logical_or(prenc <bins[j+1], prenc >=bins[j])] = np.NaN
332 stationbin_ana[np.logical_or(prenc <bins[j+1], prenc >=bins[j])] = np.NaN
333 obserrorbin[np.logical_or(prenc <bins[j+1], prenc >=bins[j])] = np.NaN
334 errstartbin[np.logical_or(prenc <bins[j+1], prenc >=bins[j])] = np.NaN
335 errendbin[np.logical_or(prenc <bins[j+1], prenc >=bins[j])] = np.NaN
336 RMSEomb = np.sqrt(np.nanmean(ombncbin**2))
337 RMSEoma = np.sqrt(np.nanmean(omancbin**2))
338 Meanobserror = np.nanmean(obserrorbin)
339 Meanerrstart = np.nanmean(errstartbin)
341 obsnum = len(obsncbin)-np.isnan(obsncbin).sum()
342 obsnums = np.append(obsnums,obsnum)
344 ombnum = len(ombncbin)-np.isnan(ombncbin).sum()
345 ombnums = np.append(ombnums,ombnum)
347 omanum = len(omancbin)-np.isnan(omancbin).sum()
348 omanums = np.append(omanums,omanum)
350 obserrornum = len(obserrorbin)-np.isnan(obserrorbin).sum()
351 obserrornums = np.append(obserrornums,obserrornum)
353 errstartnum = len(errstartbin)-np.isnan(errstartbin).sum()
354 errstartnums = np.append(errstartnums,errstartnum)
356 RMSEombs = np.append(RMSEombs,RMSEomb)
357 RMSEomas = np.append(RMSEomas,RMSEoma)
358 Meanobserrors = np.append(Meanobserrors,Meanobserror)
359 Meanerrstarts = np.append(Meanerrstarts,Meanerrstart)
362 if (plot_eachLevelDistri):
363 if ''.join(obstype)[:6] ==
'gnssro':
364 recordbin_bak[np.logical_or(prenc <bins[j+1], prenc >=bins[j])] = np.NaN
365 recordbin_ana[np.logical_or(prenc <bins[j+1], prenc >=bins[j])] = np.NaN
366 n_record_bak = len(np.unique(recordbin_bak[~np.isnan(recordbin_bak)]))
367 n_record_ana = len(np.unique(recordbin_ana[~np.isnan(recordbin_ana)]))
368 n_stationId_bak = len(np.unique(stationbin_bak[~np.isnan(stationbin_bak)]))
369 n_stationId_ana = len(np.unique(stationbin_ana[~np.isnan(stationbin_ana)]))
370 print(
'check every level n_record_bak, n_record_ana=',n_record_bak, n_record_ana)
372 if 'nan' in stationbin_bak:
373 n_stationId_bak = len(set(stationbin_bak)) -1
375 n_stationId_bak = len(set(stationbin_bak))
376 if 'nan' in stationbin_ana:
377 n_stationId_ana = len(set(stationbin_ana)) -1
379 n_stationId_ana = len(set(stationbin_ana))
380 if ''.join(obstype)[:6] ==
'gnssro':
387 plotrmsepro(RMSEombs,RMSEomas,binsfory,ombnums,omanums,expt_obs,varname,print_fmt)
388 ploterrpro(Meanobserrors,Meanerrstarts,binsfory,obserrornums,errstartnums,expt_obs,varname,print_fmt,
"Mean")
390 elif ''.join(obstype)
in radiance_group:
391 obsnc = obsnc.reshape(len(latnc),len(chlist))
392 bkgnc = bkgnc.reshape(len(latnc),len(chlist))
393 ananc = ananc.reshape(len(latnc),len(chlist))
394 ombnc = ombnc.reshape(len(latnc),len(chlist))
395 omanc = omanc.reshape(len(latnc),len(chlist))
399 nvars = len(channels)
400 for channel
in channels:
401 ifig = channels.index(channel) + 1
402 varval = vardict.get(varname,[
'',varname])
403 units = vu.varDictObs[var][0]
404 shortname =
'_'+str(channel)
405 shortname = varval[1] + shortname
406 ivar = channels.index(channel)
410 nx_subplt, ny_subplt, figs, subplt_cnt = \
415 maxsubplts, subplt_cnt, \
416 obsnc[:,channel-1], ombnc[:,channel-1], omanc[:,channel-1], \
417 nx_subplt, ny_subplt, \
418 nfigtypes, figs, expt_obs,print_fmt)
421 varval = vardict.get(varname,[
'',varname])
422 units = vu.varDictObs[var][0]
424 if ''.join(obstype)
in radiance_group:
428 for channel
in channels:
429 shortname =
'_'+str(channel)
430 shortname = varval[1] + shortname
432 obstype,shortname,units,expt_obs,0,
"obs", \
433 None,
None,dotsize,color)
435 obstype,shortname,units,expt_obs,0,
"bkg", \
436 None,
None,dotsize,color)
438 obstype,shortname,units,expt_obs,0,
"ana", \
439 None,
None,dotsize,color)
444 obstype,shortname,units,expt_obs,0,
"omb", \
445 dmin,dmax,dotsize,color)
447 obstype,shortname,units,expt_obs,0,
"oma", \
448 dmin,dmax,dotsize,color)
450 def plotrmsepro(var1,var2,binsfory,ombnums,omanums,EXP_NAME,VAR_NAME,fmt):
451 fig, ax1 = plt.subplots()
453 plt.gca().invert_yaxis()
455 ax1.plot(var1,binsfory,
'g-*',markersize=5)
456 ax1.plot(var2,binsfory,
'r-*',markersize=5)
458 print(np.nanmax(var1))
459 if VAR_NAME
in 'specific_humidity':
460 ax1.set_xlim([0,np.nanmax(var1)])
462 ax1.set_xlim([0,math.ceil(np.nanmax(var1))])
465 ax2.spines[
'right'].set_position((
'axes', 1.0))
466 ax2.set_yticks(binsfory)
467 ax2.set_ylabel(
'Observation Number(EffectiveQCbg=0)',fontsize=15)
470 ax3.set_yticks(binsfory)
471 ax3.spines[
'right'].set_position((
'axes', 1.2))
472 ax3.set_ylabel(
'Observation Number(EffectiveQCan=0)',fontsize=15)
474 if ''.join(EXP_NAME.split(
"_")[-1:])[:6] ==
'gnssro':
475 ax1.set_ylim([0,49500])
476 ax1.set_ylabel(
'Altitude (m)',fontsize=15)
477 ax1.set_xlabel(VAR_NAME+
' RMSE of OMB/O & OMA/O '+ vardict[VAR_NAME][0],fontsize=15)
478 ax1.legend((
'(OMB/O)*100%',
'(OMA/O)*100%'), loc=
'upper right',fontsize=15)
479 ax2.set_yticklabels(ombnums.astype(np.int))
480 ax3.set_yticklabels(omanums.astype(np.int))
482 ax1.set_ylim([1000,0])
483 major_ticks = np.arange(0, 1000, 100)
484 ax1.set_yticks(major_ticks)
485 ax1.set_ylabel(
'Pressure (hPa)',fontsize=15)
486 ax1.set_xlabel(VAR_NAME+
' RMSE '+ vardict[VAR_NAME][0],fontsize=15)
487 ax1.legend((
'OMB',
'OMA'), loc=
'lower left',fontsize=15)
488 ax2.set_yticklabels(reversed(ombnums.astype(np.int)))
489 ax3.set_yticklabels(reversed(omanums.astype(np.int)))
490 fname =
'RMSE_%s_%s.'%(EXP_NAME,VAR_NAME)+fmt
491 print(
'Saving figure to '+fname)
492 plt.savefig(fname,dpi=200,bbox_inches=
'tight')
495 def ploterrpro(var1,var2,binsfory,ombnums,omanums,EXP_NAME,VAR_NAME,fmt,metrics):
496 fig, ax1 = plt.subplots()
498 plt.gca().invert_yaxis()
500 ax1.plot(var1,binsfory,
'g-*',markersize=5)
501 ax1.plot(var2,binsfory,
'r-*',markersize=5)
502 print(np.nanmax(var1))
503 if VAR_NAME
in 'specific_humidity':
504 ax1.set_xlim([0,np.nanmax(var1)])
506 ax1.set_xlim([0,math.ceil(np.nanmax(var2))])
509 ax2.spines[
'right'].set_position((
'axes', 1.0))
510 ax2.set_yticks(binsfory)
512 ax2.set_ylabel(
'Obs Num for obserror (EffectiveQCbg=0)',fontsize=8)
515 ax3.set_yticks(binsfory)
516 ax3.spines[
'right'].set_position((
'axes', 1.2))
517 ax3.set_ylabel(
'Obs Num for EffectiveError0(EffectiveQCbg=0)',fontsize=8)
519 if ''.join(EXP_NAME.split(
"_")[-1:])[:6] ==
'gnssro':
520 ax1.set_ylim([0,49500])
521 ax1.set_ylabel(
'Altitude (m)',fontsize=15)
524 ax2.set_yticklabels(ombnums.astype(np.int))
525 ax3.set_yticklabels(omanums.astype(np.int))
527 ax1.set_ylim([1000,0])
528 major_ticks = np.arange(0, 1000, 100)
529 ax1.set_yticks(major_ticks)
530 ax1.set_ylabel(
'Pressure (hPa)',fontsize=15)
533 ax2.set_yticklabels(reversed(ombnums.astype(np.int)))
534 ax3.set_yticklabels(reversed(omanums.astype(np.int)))
535 ax1.set_xlabel(VAR_NAME+
' '+ metrics +
' '+ vardict[VAR_NAME][0],fontsize=15)
536 ax1.legend((
'obserr',
'EffectiveError0'), loc=
'lower left',fontsize=15)
538 fname = metrics+
'_%s_%s.'%(EXP_NAME,VAR_NAME)+fmt
540 print(
'Saving figure to '+fname)
541 plt.savefig(fname,dpi=200,bbox_inches=
'tight')
559 nnfigs = (int(len(subpltlist) / maxsubplts) + 1)
560 nsubplts = len(subpltlist)
561 if nsubplts > maxsubplts : nsubplts = maxsubplts
566 nx = np.ceil(np.sqrt(nsubplts))
567 ny = np.ceil(np.true_divide(nsubplts,nx))
571 for ifig
in range(0,nnfigs*nfigtypes):
574 fig.set_size_inches(nx_subplt[0]*inch_size,ny_subplt[0]*inch_size)
576 subplt_cnt = np.zeros(nnfigs*nfigtypes)
578 return nx_subplt, ny_subplt, figs, subplt_cnt
581 maxsubplts, subplt_cnt, \
583 nx_subplt, ny_subplt, \
584 nfigtypes, figs, EXP_NAME, fmt):
609 nnfigs = len(figs) / nfigtypes
610 jfig = int((ifig-1)/maxsubplts)
611 kfig = np.mod(ifig-1,maxsubplts)+1
612 subplt_cnt[jfig] += 1
613 if jfig == nnfigs-1 :
614 numsubplts = np.mod(nvars,maxsubplts)
616 numsubplts = maxsubplts
619 for iifig
in range(nfigtypes):
627 print(
'WARNING: scatter_verification has no definitions for nfigtypes == ',nfigtypes)
633 ax = figs[int(offset+jfig)].add_subplot(ny_subplt[0],nx_subplt[0],kfig)
637 fname =
'XB_XA_%s'%(EXP_NAME)
639 obs, [obs-omb , obs-oma], \
640 [
'x_b' ,
'x_a'],
True, xlab, ylab, \
641 varname, varunits, ax)
644 fname =
'OMB_OMA_%s'%(EXP_NAME)
647 [],
False, xlab, ylab, \
648 varname, varunits, ax)
653 ax.text(0.5, 0.5,
'[NO DATA]',
654 {
'color':
'k',
'fontsize': 12},
655 ha=
'center', va=
'center', transform=ax.transAxes)
657 if nnfigs > 1: fname=fname+
'_%d-of-%d'%(jfig,nnfigs)
660 if (ivar == nvars-1
or subplt_cnt[jfig] == numsubplts):
662 print(
'Saving figure to '+fname)
663 figs[int(offset+jfig)].subplots_adjust(wspace=0.35,hspace=0.35)
664 figs[int(offset+jfig)].savefig(fname,dpi=200,bbox_inches=
'tight')
694 ax.text(0.03, 0.97 - len(LEG) * 0.125, VAR_NAME,
695 {
'color':
'k',
'fontsize': fsize_leg},
696 ha=
'left', va=
'top', transform=ax.transAxes)
699 print(
'WARNING in scatter_one2ones: len(XVAL)==0; skipping this dataset')
701 NVALS = np.asarray([])
702 for i,YVAL
in enumerate(YVALS):
703 if len(XVAL) != len(YVAL):
704 print(
'ERROR: Incorrect usage of scatter_one2ones, YVALS must be list of arrays.')
706 not_nan = np.isfinite(XVAL) & np.isfinite(YVAL)
707 NVALS = np.append(NVALS,np.sum(not_nan))
709 if np.all(NVALS == 0):
710 print(
'WARNING in scatter_one2ones: all(XVAL/YVAL) are non-finite; skipping this dataset')
714 [0.0000, 0.4470, 0.7410], \
715 [0.8500, 0.3250, 0.0980], \
716 [0.9290, 0.6940, 0.1250], \
717 [0.4940, 0.1840, 0.5560], \
718 [0.4660, 0.6740, 0.1880], \
719 [0.3010, 0.7450, 0.9330], \
720 [0.6350, 0.0780, 0.1840], \
722 markers = [
'*',
'+',
'o',
'.']
723 msizes = [0.5,0.5,0.5, 3 ]
725 for i,YVAL
in enumerate(YVALS):
726 col = colors[np.mod(i,len(colors))]
727 mind = np.mod(i,len(markers))
728 ax.plot( XVAL, YVAL, markers[mind], color = col, \
729 markersize = msizes[mind], alpha=0.5 )
733 if UNITS !=
'': label = label+
' '+UNITS
734 ax.set_xlabel(label,fontsize=6)
737 if UNITS !=
'': label = label+
' '+UNITS
738 ax.set_ylabel(label,fontsize=6)
740 ax.legend(LEG, loc=
'upper left',fontsize=5)
742 ymin, ymax = ax.get_ylim()
743 xmin, xmax = ax.get_xlim()
753 predictor = np.arange(xymin, xymax, (xymax - xymin) / 10.0)
757 for j,YVAL
in enumerate(reversed(YVALS)):
758 i = len(YVALS) - j - 1
759 if NVALS[j]==0:
continue
761 not_nan = np.isfinite(XVAL) & np.isfinite(YVAL)
764 p = np.polyfit(XVAL[not_nan],YVAL[not_nan],1)
765 predicted = p[0] * predictor + p[1]
766 col0 = colors[np.mod(i,len(colors))]
770 col = (1. - dimmer) * np.asarray(col0)
771 ax.plot( predictor, predicted,
'-', color = col, lw=1.2 )
774 stat =
'N = %d\nslope: %0.2f '%(NVALS[j],p[0])
776 RMSE = np.sqrt( np.sum( np.square(YVAL[not_nan] - XVAL[not_nan]) ) / NVALS[j] )
777 BIAS = np.sum( YVAL[not_nan] - XVAL[not_nan] ) / NVALS[j]
778 stat = stat+
'\nRMSE: %0.2f \nBIAS: %0.2f'%(RMSE,BIAS)
779 ax.text(tx, ty, stat+nline, \
780 {
'color': col,
'fontsize': fsize_lab},
781 ha=
'right', va=
'bottom', backgroundcolor=[1,1,1,0.2], \
782 clip_on=
True, transform=ax.transAxes)
783 nline = nline +
''.join(
'\n' * stat.count(
'\n')) +
'\n'
785 ax.plot([xymin,xymax],[xymin,xymax],
'k--',lw=0.5)
786 ticks = ax.get_yticks()
787 ticks = ticks[np.logical_and(ticks >= xymin, ticks<=xymax)]
790 for tick
in ax.xaxis.get_major_ticks():
791 tick.label.set_fontsize(5)
792 tick.label.set_rotation(
'vertical')
793 for tick
in ax.yaxis.get_major_ticks():
794 tick.label.set_fontsize(5)
796 ax.set_xlim(xymin,xymax)
797 ax.set_ylim(xymin,xymax)
804 if __name__ ==
'__main__':
main()
def plotDistri(lats, lons, values, ObsType, VarName, var_unit, out_name, nstation, levbin, dmin=None, dmax=None, dotsize=6, color="rainbow")
def scatter_verification(ifig, varname, varunits, ivar, nvars, maxsubplts, subplt_cnt, obs, omb, oma, nx_subplt, ny_subplt, nfigtypes, figs, EXP_NAME, fmt)
def scatter_one2ones(XVAL, YVALS, LEG, show_stats, XLAB, YLAB, VAR_NAME, UNITS, ax)
def plotrmsepro(var1, var2, binsfory, ombnums, omanums, EXP_NAME, VAR_NAME, fmt)
def init_subplts(subpltlist, nfigtypes, maxsubplts)
def ploterrpro(var1, var2, binsfory, ombnums, omanums, EXP_NAME, VAR_NAME, fmt, metrics)