def pressx(ifile, varkey, options, before='', after=''): import matplotlib.pyplot as plt from matplotlib.colors import Normalize, LogNorm outpath = getattr(options, 'outpath', '.') vert = cu.getpresbnds(ifile) var = ifile.variables[varkey] dims = [(k, l) for l, k in zip(var[:].shape, var.dimensions) if l > 1] if len(dims) > 2: raise ValueError( 'Press-x can have 2 non-unity dimensions; got %d - %s' % (len(dims), str(dims))) if options.logscale: norm = LogNorm() else: norm = Normalize() exec(before) ax = plt.gca() print(varkey, end='') vals = var[:].squeeze() x = np.arange(vals.shape[1]) patches = ax.pcolor(x, vert, vals, norm=norm) # ax.set_xlabel(X.units.strip()) # ax.set_ylabel(Y.units.strip()) plt.colorbar(patches) ax.set_ylim(vert.max(), vert.min()) ax.set_xlim(x.min(), x.max()) fmt = 'png' figpath = os.path.join(outpath + '_PRESX_' + varkey + '.' + fmt) exec(after) plt.savefig(figpath) print('Saved fig', figpath) return figpath
def presslon(ifile, varkey, options, before='', after=''): import matplotlib.pyplot as plt from matplotlib.colors import Normalize, LogNorm outpath = getattr(options, 'outpath', '.') vert = cu.getpresbnds(ifile) lon, lonunit = cu.getlonbnds(ifile) lon = np.append(lon.squeeze()[..., [0, 3]].mean(1), lon.squeeze()[-1, [1, 2]].mean(0)) var = ifile.variables[varkey] dims = [(k, l) for l, k in zip(var[:].shape, var.dimensions) if l > 1] if len(dims) > 2: raise ValueError( 'Press-lon plots can have 2 non-unity dimensions; got %d - %s' % (len(dims), str(dims))) if options.logscale: norm = LogNorm() else: norm = Normalize() exec(before) ax = plt.gca() print(varkey, end='') patches = ax.pcolor(lon, vert, var[:].squeeze(), norm=norm) # ax.set_xlabel(X.units.strip()) # ax.set_ylabel(Y.units.strip()) cbar = plt.colorbar(patches) vunit = getattr(var, 'units', 'unknown').strip() cbar.set_label(varkey + ' (' + vunit + ')') cbar.ax.text(.5, 1, '%.2g' % var[:].max(), horizontalalignment='center', verticalalignment='bottom') cbar.ax.text(.5, 0, '%.2g' % var[:].min(), horizontalalignment='center', verticalalignment='top') ax.set_ylim(vert.max(), vert.min()) ax.set_xlim(lon.min(), lon.max()) fmt = 'png' figpath = os.path.join(outpath + '_PRESLON_' + varkey + '.' + fmt) exec(after) plt.savefig(figpath) print('Saved fig', figpath) return figpath
def plot(ifiles, args): import matplotlib.pylab as pl import matplotlib.pyplot as plt from pylab import figure, NullFormatter, close, rcParams from PseudoNetCDF.coordutil import getsigmamid, getpresmid, getpresbnds, getsigmabnds rcParams['text.usetex'] = False from matplotlib.colors import LinearSegmentedColormap, BoundaryNorm, LogNorm, Normalize map = not args.nomap scale = args.scale minmax = eval(args.minmax) minmaxq = eval(args.minmaxq) sigma = args.sigma maskzeros = args.maskzeros try: f, = ifiles except: raise ValueError( 'curtain plot expects one file when done. Try stack time --stack=time to concatenate' ) if sigma: vertcrd = getsigmabnds(f) else: vertcrd = getpresbnds(f, pref=101325., ptop=getattr(f, 'VGTOP', 10000)) if vertcrd.max() > 2000: vertcrd /= 100. reversevert = not (np.diff(vertcrd) > 0).all() for var_name in args.variables: temp = defaultdict(lambda: 1) try: eval(var_name, None, temp) var = eval(var_name, None, f.variables)[:] except: temp[var_name] var = f.variables[var_name][:] if args.itertime: vars = [('time%02d' % vi, v) for vi, v in enumerate(var)] else: if var.shape[0] != 1: parser.print_help() sys.stderr.write( '\n*****\n\nFile must have only one time or use the itertime options; to reduce file to one time, see the --slice and --reduce operators\n\n' ) exit() vars = [('', var[0])] for lstr, var in vars: bmap = None if maskzeros: var = np.ma.masked_values(var, 0) vmin, vmax = np.percentile( np.ma.compressed(var).ravel(), list(minmaxq)) if minmax[0] is not None: vmin = minmax[0] if minmax[1] is not None: vmax = minmax[1] if not args.normalize is None: norm = eval(args.normalize) if norm.scaled(): vmin = norm.vmin vmax = norm.vmax else: if scale == 'log': bins = np.logspace(np.log10(vmin), np.log10(vmax), 11) elif scale == 'linear': bins = np.linspace(vmin, vmax, 11) elif scale == 'deciles': bins = np.percentile( np.ma.compressed( np.ma.masked_greater( np.ma.masked_less(var, vmin).view( np.ma.MaskedArray), vmax)).ravel(), [0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100]) bins[0] = vmin bins[-1] = vmax norm = BoundaryNorm(bins, ncolors=256) if map: fig = pl.figure(figsize=(8, 8)) fig.subplots_adjust(hspace=.3, wspace=.3) axmap = fig.add_subplot(3, 3, 5) try: cmaqmap = getmap(f, resolution=args.resolution) cmaqmap.drawcoastlines(ax=axmap) cmaqmap.drawcountries(ax=axmap) if not args.states: cmaqmap.drawstates(ax=axmap) if args.counties: cmaqmap.drawcounties(ax=axmap) cmaqmap.drawparallels(np.arange(-90, 100, 10), labels=[True, True, False, False], ax=axmap) cmaqmap.drawmeridians(np.arange(-180, 190, 20), labels=[False, False, True, True], ax=axmap) except Exception as e: warn('An error occurred and no map will be shown:\n%s' % str(e)) axn = fig.add_subplot(3, 3, 2, sharex=axmap) axw = fig.add_subplot(3, 3, 4, sharey=axmap) axe = fig.add_subplot(3, 3, 6, sharey=axmap) axs = fig.add_subplot(3, 3, 8, sharex=axmap) cax = fig.add_axes([.8, .7, .05, .25]) for ax in [axmap, axe]: ax.yaxis.set_major_formatter(NullFormatter()) for ax in [axmap, axn]: ax.xaxis.set_major_formatter(NullFormatter()) for ax in [axn, axs]: if sigma: ax.set_ylabel('sigma') else: ax.set_ylabel('pressure') for ax in [axe, axw]: if sigma: ax.set_xlabel('sigma') else: ax.set_xlabel('pressure') xyfactor = 1 else: fig = pl.figure(figsize=(16, 4)) fig.subplots_adjust(bottom=0.15) axw = fig.add_subplot(1, 4, 1) axn = fig.add_subplot(1, 4, 2) axe = fig.add_subplot(1, 4, 3) axs = fig.add_subplot(1, 4, 4) cax = fig.add_axes([.91, .1, .025, .8]) if sigma: axw.set_ylabel('sigma') else: axw.set_ylabel('pressure') xyfactor = 1e-3 # m -> km x = f.NCOLS + 1 y = f.NROWS + 1 start_south = 0 end_south = start_south + x start_east = end_south end_east = start_east + y start_north = end_east end_north = start_north + x start_west = end_north end_west = start_west + y X, Y = np.meshgrid(np.arange(x + 1) * f.XCELL * xyfactor, vertcrd) patchess = axs.pcolor(X, Y, var[:, start_south:end_south], cmap=bmap, vmin=vmin, vmax=vmax, norm=norm) if not map: if reversevert: axs.set_ylim(*axs.get_ylim()[::-1]) axs.set_title('South') axs.set_xlabel('E to W km') axs.set_xlim(*axs.get_xlim()[::-1]) else: if not reversevert: axs.set_ylim(*axs.get_ylim()[::-1]) X, Y = np.meshgrid(np.arange(-1, x) * f.XCELL * xyfactor, vertcrd) patchesn = axn.pcolor(X, Y, var[:, start_north:end_north], cmap=bmap, vmin=vmin, vmax=vmax, norm=norm) if reversevert: axn.set_ylim(*axn.get_ylim()[::-1]) if not map: axn.set_title('North') axn.set_xlabel('W to E km') if map: X, Y = np.meshgrid(vertcrd, np.arange(y + 1) * f.YCELL) patchese = axe.pcolor(X, Y, var[:, start_east:end_east].swapaxes(0, 1), cmap=bmap, vmin=vmin, vmax=vmax, norm=norm) if reversevert: axe.set_xlim(*axe.get_xlim()[::-1]) else: X, Y = np.meshgrid( np.arange(y + 1) * f.YCELL * xyfactor, vertcrd) patchese = axe.pcolor(X, Y, var[:, start_east:end_east], cmap=bmap, vmin=vmin, vmax=vmax, norm=norm) if reversevert: axe.set_ylim(*axe.get_ylim()[::-1]) axe.set_title('East') axe.set_xlabel('N to S km') axe.set_xlim(*axe.get_xlim()[::-1]) if map: X, Y = np.meshgrid(vertcrd, np.arange(-1, y) * f.YCELL) patchesw = axw.pcolor(X, Y, var[:, start_west:end_west].swapaxes(0, 1), cmap=bmap, vmin=vmin, vmax=vmax, norm=norm) if not reversevert: axw.set_xlim(*axw.get_xlim()[::-1]) else: X, Y = np.meshgrid( np.arange(-1, y) * f.YCELL * xyfactor, vertcrd) patchesw = axw.pcolor(X, Y, var[:, start_west:end_west], cmap=bmap, vmin=vmin, vmax=vmax, norm=norm) if reversevert: axw.set_ylim(*axw.get_ylim()[::-1]) axw.set_title('West') axw.set_xlabel('S to N km') if map: for ax in [axe, axw]: ax.axis('tight', axis='x') pl.setp(ax.xaxis.get_majorticklabels(), rotation=90) for ax in [axs, axn]: ax.axis('tight', axis='y') else: for ax in [axe, axn, axw, axs] + ([axmap] if map else []): ax.axis('tight') if 'TFLAG' in f.variables.keys(): SDATE = f.variables['TFLAG'][:][0, 0, 0] EDATE = f.variables['TFLAG'][:][-1, 0, 0] STIME = f.variables['TFLAG'][:][0, 0, 1] ETIME = f.variables['TFLAG'][:][-1, 0, 1] if SDATE == 0: SDATE = 1900001 EDATE = 1900001 sdate = datetime.strptime('%07d %06d' % (SDATE, STIME), '%Y%j %H%M%S') edate = datetime.strptime('%07d %06d' % (EDATE, ETIME), '%Y%j %H%M%S') elif 'tau0' in f.variables.keys(): sdate = datetime(1985, 1, 1, 0) + timedelta(hours=f.variables['tau0'][0]) edate = datetime(1985, 1, 1, 0) + timedelta(hours=f.variables['tau1'][-1]) else: sdate = datetime(1900, 1, 1, 0) edate = datetime(1900, 1, 1, 0) try: title = '%s %s to %s' % (var_name, sdate.strftime('%Y-%m-%d'), edate.strftime('%Y-%m-%d')) except: title = var_name fig.suptitle(title.replace('O3', 'Ozone at Regional Boundaries')) if var.min() < vmin and var.max() > vmax: extend = 'both' elif var.min() < vmin: extend = 'min' elif var.max() > vmax: extend = 'max' else: extend = 'neither' fig.colorbar(patchesw, cax=cax, extend=extend) cax.set_xlabel('ppm') figpath = args.outpath + var_name + lstr + '.' + args.figformat fig.savefig(figpath) if args.verbose > 0: print('Saved fig', figpath) pl.close(fig)
def plot(ifiles, args): import pylab as pl from pylab import figure, NullFormatter, close, rcParams from PseudoNetCDF.coordutil import getsigmamid, getpresmid, getpresbnds, getsigmabnds rcParams["text.usetex"] = False from matplotlib.colors import LinearSegmentedColormap, BoundaryNorm, LogNorm map = not args.nomap scale = args.scale minmax = eval(args.minmax) minmaxq = eval(args.minmaxq) sigma = args.sigma maskzeros = args.maskzeros try: f, = ifiles except: raise ValueError("curtain plot expects one file when done. Try stack time --stack=time to concatenate") if sigma: vertcrd = getsigmabnds(f) else: vertcrd = getpresbnds(f, pref=101325.0, ptop=getattr(f, "VGTOP", 10000)) if vertcrd.max() > 2000: vertcrd /= 100.0 reversevert = not (np.diff(vertcrd) > 0).all() for var_name in args.variables: temp = defaultdict(lambda: 1) try: eval(var_name, None, temp) var = eval(var_name, None, f.variables)[:] except: temp[var_name] var = f.variables[var_name][:] if args.itertime: vars = [("time%02d" % vi, v) for vi, v in enumerate(var)] else: if var.shape[0] != 1: parser.print_help() sys.stderr.write( "\n*****\n\nFile must have only one time or use the itertime options; to reduce file to one time, see the --slice and --reduce operators\n\n" ) exit() vars = [("", var[0])] for lstr, var in vars: bmap = None if maskzeros: var = np.ma.masked_values(var, 0) vmin, vmax = np.percentile(np.ma.compressed(var).ravel(), list(minmaxq)) if minmax[0] is not None: vmin = minmax[0] if minmax[1] is not None: vmax = minmax[1] if not args.normalize is None: norm = eval(args.normalize) if norm.scaled(): vmin = norm.vmin vmax = norm.vmax else: if scale == "log": bins = np.logspace(np.log10(vmin), np.log10(vmax), 11) elif scale == "linear": bins = np.linspace(vmin, vmax, 11) elif scale == "deciles": bins = np.percentile( np.ma.compressed(np.ma.masked_greater(np.ma.masked_less(var, vmin), vmax)).ravel(), [0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100], ) bins[0] = vmin bins[-1] = vmax norm = BoundaryNorm(bins, ncolors=256) if map: fig = pl.figure(figsize=(8, 8)) fig.subplots_adjust(hspace=0.3, wspace=0.3) axmap = fig.add_subplot(3, 3, 5) try: cmaqmap = getmap(f) cmaqmap.drawcoastlines(ax=axmap) cmaqmap.drawcountries(ax=axmap) if args.states: cmaqmap.drawstates(ax=axmap) if args.counties: cmaqmap.drawcounties(ax=axmap) cmaqmap.drawparallels(np.arange(-90, 100, 10), labels=[True, True, False, False], ax=axmap) cmaqmap.drawmeridians(np.arange(-180, 190, 20), labels=[False, False, True, True], ax=axmap) except Exception as e: warn("An error occurred and no map will be shown:\n%s" % str(e)) axn = fig.add_subplot(3, 3, 2, sharex=axmap) axw = fig.add_subplot(3, 3, 4, sharey=axmap) axe = fig.add_subplot(3, 3, 6, sharey=axmap) axs = fig.add_subplot(3, 3, 8, sharex=axmap) cax = fig.add_axes([0.8, 0.7, 0.05, 0.25]) for ax in [axmap, axe]: ax.yaxis.set_major_formatter(NullFormatter()) for ax in [axmap, axn]: ax.xaxis.set_major_formatter(NullFormatter()) for ax in [axn, axs]: if sigma: ax.set_ylabel("sigma") else: ax.set_ylabel("pressure") for ax in [axe, axw]: if sigma: ax.set_xlabel("sigma") else: ax.set_xlabel("pressure") xyfactor = 1 else: fig = pl.figure(figsize=(16, 4)) fig.subplots_adjust(bottom=0.15) axw = fig.add_subplot(1, 4, 1) axn = fig.add_subplot(1, 4, 2) axe = fig.add_subplot(1, 4, 3) axs = fig.add_subplot(1, 4, 4) cax = fig.add_axes([0.91, 0.1, 0.025, 0.8]) if sigma: axw.set_ylabel("sigma") else: axw.set_ylabel("pressure") xyfactor = 1e-3 # m -> km x = f.NCOLS + 1 y = f.NROWS + 1 start_south = 0 end_south = start_south + x start_east = end_south end_east = start_east + y start_north = end_east end_north = start_north + x start_west = end_north end_west = start_west + y X, Y = np.meshgrid(np.arange(x + 1) * f.XCELL * xyfactor, vertcrd) patchess = axs.pcolor(X, Y, var[:, start_south:end_south], cmap=bmap, vmin=vmin, vmax=vmax, norm=norm) if not map: if reversevert: axs.set_ylim(*axs.get_ylim()[::-1]) axs.set_title("South") axs.set_xlabel("E to W km") axs.set_xlim(*axs.get_xlim()[::-1]) X, Y = np.meshgrid(np.arange(-1, x) * f.XCELL * xyfactor, vertcrd) patchesn = axn.pcolor(X, Y, var[:, start_north:end_north], cmap=bmap, vmin=vmin, vmax=vmax, norm=norm) if reversevert: axn.set_ylim(*axn.get_ylim()[::-1]) if not map: axn.set_title("North") axn.set_xlabel("W to E km") if map: X, Y = np.meshgrid(vertcrd, np.arange(y + 1) * f.YCELL) patchese = axe.pcolor( X, Y, var[:, start_east:end_east].swapaxes(0, 1), cmap=bmap, vmin=vmin, vmax=vmax, norm=norm ) if reversevert: axe.set_xlim(*axe.get_xlim()[::-1]) else: X, Y = np.meshgrid(np.arange(y + 1) * f.YCELL * xyfactor, vertcrd) patchese = axe.pcolor(X, Y, var[:, start_east:end_east], cmap=bmap, vmin=vmin, vmax=vmax, norm=norm) if reversevert: axe.set_ylim(*axe.get_ylim()[::-1]) axe.set_title("East") axe.set_xlabel("N to S km") axe.set_xlim(*axe.get_xlim()[::-1]) if map: X, Y = np.meshgrid(vertcrd, np.arange(-1, y) * f.YCELL) patchesw = axw.pcolor( X, Y, var[:, start_west:end_west].swapaxes(0, 1), cmap=bmap, vmin=vmin, vmax=vmax, norm=norm ) else: X, Y = np.meshgrid(np.arange(-1, y) * f.YCELL * xyfactor, vertcrd) patchesw = axw.pcolor(X, Y, var[:, start_west:end_west], cmap=bmap, vmin=vmin, vmax=vmax, norm=norm) if reversevert: axw.set_ylim(*axw.get_ylim()[::-1]) axw.set_title("West") axw.set_xlabel("S to N km") if map: for ax in [axe, axw]: ax.axis("tight", axis="x") pl.setp(ax.xaxis.get_majorticklabels(), rotation=90) for ax in [axs, axn]: ax.axis("tight", axis="y") else: for ax in [axe, axn, axw, axs] + ([axmap] if map else []): ax.axis("tight") if "TFLAG" in f.variables.keys(): SDATE = f.variables["TFLAG"][:][0, 0, 0] EDATE = f.variables["TFLAG"][:][-1, 0, 0] STIME = f.variables["TFLAG"][:][0, 0, 1] ETIME = f.variables["TFLAG"][:][-1, 0, 1] if SDATE == 0: SDATE = 1900001 EDATE = 1900001 sdate = datetime.strptime("%07d %06d" % (SDATE, STIME), "%Y%j %H%M%S") edate = datetime.strptime("%07d %06d" % (EDATE, ETIME), "%Y%j %H%M%S") elif "tau0" in f.variables.keys(): sdate = datetime(1985, 1, 1, 0) + timedelta(hours=f.variables["tau0"][0]) edate = datetime(1985, 1, 1, 0) + timedelta(hours=f.variables["tau1"][-1]) else: sdate = datetime(1900, 1, 1, 0) edate = datetime(1900, 1, 1, 0) try: title = "%s %s to %s" % (var_name, sdate.strftime("%Y-%m-%d"), edate.strftime("%Y-%m-%d")) except: title = var_name fig.suptitle(title.replace("O3", "Ozone at Regional Boundaries")) if var.min() < vmin and var.max() > vmax: extend = "both" elif var.min() < vmin: extend = "min" elif var.max() > vmax: extend = "max" else: extend = "neither" fig.colorbar(patchesw, cax=cax, extend=extend) cax.set_xlabel("ppm") fig.savefig("%s_%s%s.%s" % (args.outpath, var_name, lstr, args.figformat)) pl.close(fig)