def plot_variable(self,va,lv,**kwargs): self.fig = plt.figure() m, x, y = self.basemap_setup(nc,**kwargs) # Scales, colourmaps in here data = self.get(va,**kwargs) if not 'scale' in kwargs: m.contourf(x,y,data) else: m.contourf(x,y,data,N.arange(*kwargs['scale'])) if self.C.plot_titles: title = utils.string_from_time('title',self.t) plt.title(title) if self.C.colorbar: plt.colorbar(orientation='horizontal') # SAVE FIGURE datestr = utils.string_from_time('output',self.t) lv_na = utils.get_level_naming(lv,va) na = (va,lv_na,datestr) self.fname = self.create_fname(*na) # pdb.set_trace() self.save(self.fig,self.output_root,self.fname) plt.close()
def plot_streamlines(self, va, lv, **kwargs): fig = plt.figure() # Scales, colourmaps in here # Get data u_all = self.get('U10', **kwargs)[:] v_all = self.get('V10', **kwargs)[:] u = self.cut_2D_array(u_all) v = self.cut_2D_array(v_all) m, x, y = self.basemap_setup(**kwargs) """ # Density depends on which version # Wanting to match 3 km WRF (which had 2.5 density) # Should work out dx, dy in __init__ method! WRF_density = 2.5 WRF_res = 3.0 if self.version == 3: RUC_res = 13.0 density = WRF_density * RUC_res/WRF_res """ density = 2.5 #x = N.array(range(u.shape[0])) #y = N.array(range(v.shape[1])) #pdb.set_trace() #m.streamplot(x[self.x_dim/2,:],y[:,self.y_dim/2],u,v,density=density,linewidth=0.75,color='k') #m.streamplot(x[y.shape[1]/2,:],y[:,x.shape[0]/2],u,v,density=density,linewidth=0.75,color='k') #plt.streamplot(x[:,0],y[0,:],u,v)#,density=density,linewidth=0.75,color='k') m.streamplot(y[0, :], x[:, 0], u, v, density=density, linewidth=0.75, color='k') #m.quiver(x,y,u,v) if self.C.plot_titles: title = utils.string_from_time('title', self.t) plt.title(title) # SAVE FIGURE datestr = utils.string_from_time('output', self.t) lv_na = utils.get_level_naming(va, lv=lv) na = (va, lv_na, datestr) self.fname = self.create_fname(*na) # pdb.set_trace() self.save(fig, self.output_root, self.fname) plt.close()
def plot_streamlines(self,va,lv,**kwargs): fig = plt.figure() # Scales, colourmaps in here # Get data u_all = self.get('U10',**kwargs)[:] v_all = self.get('V10',**kwargs)[:] u = self.cut_2D_array(u_all) v = self.cut_2D_array(v_all) m, x, y = self.basemap_setup(**kwargs) """ # Density depends on which version # Wanting to match 3 km WRF (which had 2.5 density) # Should work out dx, dy in __init__ method! WRF_density = 2.5 WRF_res = 3.0 if self.version == 3: RUC_res = 13.0 density = WRF_density * RUC_res/WRF_res """ density = 2.5 #x = N.array(range(u.shape[0])) #y = N.array(range(v.shape[1])) #pdb.set_trace() #m.streamplot(x[self.x_dim/2,:],y[:,self.y_dim/2],u,v,density=density,linewidth=0.75,color='k') #m.streamplot(x[y.shape[1]/2,:],y[:,x.shape[0]/2],u,v,density=density,linewidth=0.75,color='k') #plt.streamplot(x[:,0],y[0,:],u,v)#,density=density,linewidth=0.75,color='k') m.streamplot(y[0,:],x[:,0],u,v,density=density,linewidth=0.75,color='k') #m.quiver(x,y,u,v) if self.C.plot_titles: title = utils.string_from_time('title',self.t) plt.title(title) # SAVE FIGURE datestr = utils.string_from_time('output',self.t) lv_na = utils.get_level_naming(va,lv=lv) na = (va,lv_na,datestr) self.fname = self.create_fname(*na) # pdb.set_trace() self.save(fig,self.output_root,self.fname) plt.close()
def frontogenesis(self, time, level, wrf_sd=0, out_sd=0, dom=1, clvs=0, no_title=1): """ Compute and plot (Miller?) frontogenesis as d/dt of theta gradient. Use a centred-in-time derivative; hence, if time index is start or end of wrfout file, skip the plot. """ outpath = self.get_outpath(out_sd) self.W = self.get_wrfout(wrf_sd, dom=dom) tstr = utils.string_from_time('output', time) Front = self.W.compute_frontogenesis(time, level) if isinstance(Front, N.ndarray): F = BirdsEye(self.C, self.W) fname = 'frontogen_{0}.png'.format(tstr) F.plot_data(Front, 'contourf', outpath, fname, time, clvs=clvs, no_title=no_title) else: print("Skipping this time; at start or end of run.")
def get_times(itime, ftime, int_hr): times = utils.generate_times(itime, ftime, 60 * 60 * int_hr) # times = [itime,] time_strs = [] for t in times: time_strs.append(utils.string_from_time("output", t)) return time_strs
def get_times(itime, ftime, int_hr): times = utils.generate_times(itime, ftime, 60 * 60 * int_hr) #times = [itime,] time_strs = [] for t in times: time_strs.append(utils.string_from_time('output', t)) return time_strs
def spaghetti(self, t, lv, va, contour, wrfouts, outpath, da=0, dom=0): """ wrfouts : list of wrfout files Only change dom if there are multiple domains. """ m, x, y = self.basemap_setup() time_idx = self.W.get_time_idx(t) colours = utils.generate_colours(M, len(wrfouts)) # import pdb; pdb.set_trace() if lv == 2000: lv_idx = None else: print("Only support surface right now") raise Exception lat_sl, lon_sl = self.get_limited_domain(da) slices = {'t': time_idx, 'lv': lv_idx, 'la': lat_sl, 'lo': lon_sl} # self.ax.set_color_cycle(colours) ctlist = [] for n, wrfout in enumerate(wrfouts): self.W = WRFOut(wrfout) data = self.W.get(va, slices)[0, ...] # m.contour(x,y,data,levels=[contour,]) ct = m.contour(x, y, data, colors=[ colours[n], ], levels=[ contour, ], label=wrfout.split('/')[-2]) print( ("Plotting contour level {0} for {1} from file \n {2}".format( contour, va, wrfout))) # ctlist.append(ct) # self.ax.legend() # labels = [w.split('/')[-2] for w in wrfouts] # print labels # self.fig.legend(handles=ctlist) # plt.legend(handles=ctlist,labels=labels) #labels,ncol=3, loc=3, # bbox_to_anchor=[0.5,1.5]) datestr = utils.string_from_time('output', t, tupleformat=0) lv_na = utils.get_level_naming(va, lv) naming = ['spaghetti', va, lv_na, datestr] if dom: naming.append(dom) fname = self.create_fname(*naming) self.save(outpath, fname)
def plot_radar(self, outdir, fig=False, ax=False, fname=False, Nlim=False, Elim=False, Slim=False, Wlim=False, cb=True): """ Plot radar data. """ # if not fig: # fig, ax = plt.subplots() # self.generate_basemap(fig,ax,Nlim,Elim,Slim,Wlim) #lons, lats = self.m.makegrid(self.xlen,self.ylen) if isinstance(Nlim, float): data, lats, lons = self.get_subdomain(Nlim, Elim, Slim, Wlim) # x,y = self.m(lons,lats) else: data = self.data lats = self.lats #flip lats upside down? lons = self.lons # x,y = self.m(*N.meshgrid(lons,lats)) # x,y = self.m(*N.meshgrid(lons,lats)) # x,y = self.m(*N.meshgrid(lons,lats[::-1])) # Custom colorbar from . import colourtables as ct radarcmap = ct.reflect_ncdc(self.clvs) # radarcmap = ct.ncdc_modified_ISU(self.clvs) # Convert pixel levels to dBZ dBZ = self.get_dBZ(data) # dBZ[dBZ<0] = 0 # def plot2D(self,data,fname,outdir,plottype='contourf', # save=1,smooth=1,lats=False,lons=False, # clvs=False,cmap=False,title=False,colorbar=True, # locations=False): if not fname: tstr = utils.string_from_time('output', self.utc) fname = 'verif_radar_{0}.png'.format(tstr) F = BirdsEye(fig=fig, ax=ax) if cb: cb = 'horizontal' F.plot2D(dBZ, fname, outdir, lats=lats, lons=lons, cmap=radarcmap, clvs=N.arange(5, 90, 5), cb=cb, cblabel='Composite reflectivity (dBZ)')
def plot(self,va,lv,times,**kwargs): for t in times: fig = plt.figure() data = self.get(va,lv,t) m, x, y = self.basemap_setup() if 'scale' in kwargs: S = kwargs['scale'] f1 = m.contour(x,y,data,S,colors='k') else: f1 = m.contour(x,y,data,colors='k') if self.C.plot_titles: title = utils.string_from_time('title',t) plt.title(title) if 'wind_overlay' in kwargs: jet = kwargs['wind_overlay'] wind = self.get('wind',lv,t) windplot = m.contourf(x,y,wind,jet,alpha=0.6) plt.colorbar(windplot) elif 'W_overlay' in kwargs: Wscale = kwargs['W_overlay'] W = self.get('W',lv,t) windplot = m.contourf(x,y,W,alpha=0.6) plt.colorbar(windplot) # if self.C.colorbar: # plt.colorbar(orientation='horizontal') datestr = utils.string_from_time('output',t) fname = '_'.join(('ECMWF',va,str(lv),datestr)) + '.png' print(("Plotting {0} at {1} for {2}".format( va,lv,datestr))) plt.clabel(f1, inline=1, fmt='%4u', fontsize=12, colors='k') utils.trycreate(self.C.output_root) plt.savefig(os.path.join(self.C.output_root,fname)) plt.clf() plt.close()
def plot_streamlines(self, lv, time, wrf_sd=0, wrf_nc=0, out_sd=0, dom=1): self.W = self.get_wrfout(wrf_sd, wrf_nc, dom=dom) outpath = self.get_outpath(out_sd) self.F = BirdsEye(self.C, self.W) disp_t = utils.string_from_time('title', time) print("Plotting {0} at lv {1} for time {2}.".format( 'streamlines', lv, disp_t)) self.F.plot_streamlines(lv, time, outpath)
def plot(self, va, lv, times, **kwargs): for t in times: fig = plt.figure() data = self.get(va, lv, t) m, x, y = self.basemap_setup() if 'scale' in kwargs: S = kwargs['scale'] f1 = m.contour(x, y, data, S, colors='k') else: f1 = m.contour(x, y, data, colors='k') if self.C.plot_titles: title = utils.string_from_time('title', t) plt.title(title) if 'wind_overlay' in kwargs: jet = kwargs['wind_overlay'] wind = self.get('wind', lv, t) windplot = m.contourf(x, y, wind, jet, alpha=0.6) plt.colorbar(windplot) elif 'W_overlay' in kwargs: Wscale = kwargs['W_overlay'] W = self.get('W', lv, t) windplot = m.contourf(x, y, W, alpha=0.6) plt.colorbar(windplot) # if self.C.colorbar: # plt.colorbar(orientation='horizontal') datestr = utils.string_from_time('output', t) fname = '_'.join(('ECMWF', va, str(lv), datestr)) + '.png' print(("Plotting {0} at {1} for {2}".format(va, lv, datestr))) plt.clabel(f1, inline=1, fmt='%4u', fontsize=12, colors='k') utils.trycreate(self.C.output_root) plt.savefig(os.path.join(self.C.output_root, fname)) plt.clf() plt.close()
def plot_streamlines(self,lv,pt,outpath,da=0): m,x,y = self.basemap_setup() time_idx = self.W.get_time_idx(pt) if lv==2000: lv_idx = None else: print("Only support surface right now") raise Exception lat_sl, lon_sl = self.get_limited_domain(da) slices = {'t': time_idx, 'lv': lv_idx, 'la': lat_sl, 'lo': lon_sl} if lv == 2000: u = self.W.get('U10',slices)[0,:,:] v = self.W.get('V10',slices)[0,:,:] else: u = self.W.get('U',slices)[0,0,:,:] v = self.W.get('V',slices)[0,0,:,:] # pdb.set_trace() #div = N.sum(N.dstack((N.gradient(u)[0],N.gradient(v)[1])),axis=2)*10**4 #vort = (N.gradient(v)[0] - N.gradient(u)[1])*10**4 #pdb.set_trace() lv_na = utils.get_level_naming('wind',lv=2000) m.streamplot(x[self.W.x_dim/2,:],y[:,self.W.y_dim/2],u,v, density=2.5,linewidth=0.75,color='k') #div_Cs = N.arange(-30,31,1) #divp = m.contourf(x,y,vort,alpha=0.6) #divp = m.contour(x,y,vort) #plt.colorbar(divp,orientation='horizontal') if self.C.plot_titles: title = utils.string_from_time('title',pt) m.title(title) datestr = utils.string_from_time('output',pt) na = ('streamlines',lv_na,datestr) fname = self.create_fname(*na) self.save(outpath,fname)
def plot_radar( self, outdir, fig=False, ax=False, fname=False, Nlim=False, Elim=False, Slim=False, Wlim=False, cb=True ): """ Plot radar data. """ # if not fig: # fig, ax = plt.subplots() # self.generate_basemap(fig,ax,Nlim,Elim,Slim,Wlim) # lons, lats = self.m.makegrid(self.xlen,self.ylen) if isinstance(Nlim, float): data, lats, lons = self.get_subdomain(Nlim, Elim, Slim, Wlim) # x,y = self.m(lons,lats) else: data = self.data lats = self.lats # flip lats upside down? lons = self.lons # x,y = self.m(*N.meshgrid(lons,lats)) # x,y = self.m(*N.meshgrid(lons,lats)) # x,y = self.m(*N.meshgrid(lons,lats[::-1])) # Custom colorbar import colourtables as ct radarcmap = ct.reflect_ncdc(self.clvs) # radarcmap = ct.ncdc_modified_ISU(self.clvs) # Convert pixel levels to dBZ dBZ = self.get_dBZ(data) # dBZ[dBZ<0] = 0 # def plot2D(self,data,fname,outdir,plottype='contourf', # save=1,smooth=1,lats=False,lons=False, # clvs=False,cmap=False,title=False,colorbar=True, # locations=False): if not fname: tstr = utils.string_from_time("output", self.utc) fname = "verif_radar_{0}.png".format(tstr) F = BirdsEye(fig=fig, ax=ax) if cb: cb = "horizontal" F.plot2D( dBZ, fname, outdir, lats=lats, lons=lons, cmap=radarcmap, clvs=N.arange(5, 90, 5), cb=cb, cblabel="Composite reflectivity (dBZ)", )
def spaghetti(self,t,lv,va,contour,wrfouts,outpath,da=0,dom=0): """ wrfouts : list of wrfout files Only change dom if there are multiple domains. """ m,x,y = self.basemap_setup() time_idx = self.W.get_time_idx(t) colours = utils.generate_colours(M,len(wrfouts)) # import pdb; pdb.set_trace() if lv==2000: lv_idx = None else: print("Only support surface right now") raise Exception lat_sl, lon_sl = self.get_limited_domain(da) slices = {'t': time_idx, 'lv': lv_idx, 'la': lat_sl, 'lo': lon_sl} # self.ax.set_color_cycle(colours) ctlist = [] for n,wrfout in enumerate(wrfouts): self.W = WRFOut(wrfout) data = self.W.get(va,slices)[0,...] # m.contour(x,y,data,levels=[contour,]) ct = m.contour(x,y,data,colors=[colours[n],],levels=[contour,],label=wrfout.split('/')[-2]) print("Plotting contour level {0} for {1} from file \n {2}".format( contour,va,wrfout)) # ctlist.append(ct) # self.ax.legend() # labels = [w.split('/')[-2] for w in wrfouts] # print labels # self.fig.legend(handles=ctlist) # plt.legend(handles=ctlist,labels=labels) #labels,ncol=3, loc=3, # bbox_to_anchor=[0.5,1.5]) datestr = utils.string_from_time('output',t,tupleformat=0) lv_na = utils.get_level_naming(va,lv) naming = ['spaghetti',va,lv_na,datestr] if dom: naming.append(dom) fname = self.create_fname(*naming) self.save(outpath,fname)
def plot_skewT(self, plot_time, plot_latlon, dom=1, save_output=0, composite=0): wrfouts = self.wrfout_files_in(self.C.wrfout_root) for wrfout in wrfouts: if not composite: W = WRFOut(wrfout) ST = SkewT(self.C, W) ST.plot_skewT(plot_time, plot_latlon, dom, save_output) nice_time = utils.string_from_time('title', plot_time) print("Plotted Skew-T for time {0} at {1}".format( nice_time, plot_latlon)) else: #ST = SkewT(self.C) pass
def std(self, t, lv, va, wrf_sds, out_sd, dom=1, clvs=0): """Compute standard deviation of all members for given variable. Inputs: t : time lv : level va : variable wrf_sds : list of wrf subdirs to loop over Optional out_sd : directory in which to save image clvs : user-set contour levels """ outpath = self.get_outpath(out_sd) ncfiles = self.list_ncfiles(wrf_sds) # Use first wrfout to initialise grid, get indices self.W = self.get_wrfout(wrf_sds[0], dom=dom) tidx = self.W.get_time_idx(t) if lv == 2000: # lvidx = None lvidx = 0 else: print("Only support surface right now") raise Exception std_data = stats.std(ncfiles, va, tidx, lvidx) F = BirdsEye(self.C, self.W) t_name = utils.string_from_time('output', t) fname_t = 'std_{0}_{1}'.format(va, t_name) # pdb.set_trace() plotkwargs = {} plotkwargs['no_title'] = 1 if isinstance(clvs, N.ndarray): plotkwargs['clvs'] = clvs F.plot_data(std_data, 'contourf', outpath, fname_t, t, **plotkwargs) print("Plotting std dev for {0} at time {1}".format(va, t_name))
def upperlevel_W(self, time, level, wrf_sd=0, out_sd=0, dom=1, clvs=0, no_title=1): # import pdb; pdb.set_trace() outpath = self.get_outpath(out_sd) self.W = self.get_wrfout(wrf_sd, dom=dom) data = self.W.isosurface_p('W', time, level) F = BirdsEye(self.C, self.W) tstr = utils.string_from_time('output', time) fname = 'W_{0}_{1}.png'.format(level, tstr) F.plot_data(data, 'contourf', outpath, fname, time, clvs=clvs, no_title=no_title)
def cold_pool_strength(self, time, wrf_sd=0, wrf_nc=0, out_sd=0, swath_width=100, dom=1, twoplot=0, fig=0, axes=0, dz=0): """ Pick A, B points on sim ref overlay This sets the angle between north and line AB Also sets the length in along-line direction For every gridpt along line AB: Locate gust front via shear Starting at front, do 3-grid-pt-average in line-normal direction time : time (tuple or datenum) to plot wrf_sd : string - subdirectory of wrfout file wrf_nc : filename of wrf file requested. If no wrfout file is explicitly specified, the netCDF file in that folder is chosen if unambiguous. out_sd : subdirectory of output .png. swath_width : length in gridpoints in cross-section-normal direction dom : domain number return2 : return two figures. cold pool strength and cref/cross-section. axes : if two-length tuple, this is the first and second axes for cross-section/cref and cold pool strength, respectively dz : plot height of cold pool only. """ # Initialise self.W = self.get_wrfout(wrf_sd, wrf_nc, dom=dom) outpath = self.get_outpath(out_sd) # keyword arguments for plots line_kwargs = {} cps_kwargs = {} # Create two-panel figure if twoplot: P2 = Figure(self.C, self.W, plotn=(1, 2)) line_kwargs['ax'] = P2.ax.flat[0] line_kwargs['fig'] = P2.fig P2.ax.flat[0].set_size_inches(3, 3) cps_kwargs['ax'] = P2.ax.flat[1] cps_kwargs['fig'] = P2.fig P2.ax.flat[1].set_size_inches(6, 6) elif isinstance(axes, tuple) and len(axes) == 2: line_kwargs['ax'] = axes[0] line_kwargs['fig'] = fig cps_kwargs['ax'] = axes[1] cps_kwargs['fig'] = fig return_ax = 1 # Plot sim ref, send basemap axis to clicker function F = BirdsEye(self.C, self.W) self.data = F.plot2D('cref', time, 2000, dom, outpath, save=0, return_data=1) C = Clicker(self.C, self.W, data=self.data, **line_kwargs) # C.fig.tight_layout() # Line from front to back of system C.draw_line() # C.draw_box() lon0, lat0 = C.bmap(C.x0, C.y0, inverse=True) lon1, lat1 = C.bmap(C.x1, C.y1, inverse=True) # Pick location for environmental dpt # C.click_x_y() # Here, it is the end of the cross-section lon_env, lat_env = C.bmap(C.x1, C.y1, inverse=True) y_env, x_env, exactlat, exactlon = utils.getXY(self.W.lats1D, self.W.lons1D, lat_env, lon_env) # Create the cross-section object X = CrossSection(self.C, self.W, lat0, lon0, lat1, lon1) # Ask user the line-normal box width (self.km) #C.set_box_width(X) # Compute the grid (DX x DY) cps = self.W.cold_pool_strength(X, time, swath_width=swath_width, env=(x_env, y_env), dz=dz) # import pdb; pdb.set_trace() # Plot this array CPfig = BirdsEye(self.C, self.W, **cps_kwargs) tstr = utils.string_from_time('output', time) if dz: fprefix = 'ColdPoolDepth_' else: fprefix = 'ColdPoolStrength_' fname = fprefix + tstr pdb.set_trace() # imfig,imax = plt.subplots(1) # imax.imshow(cps) # plt.show(imfig) # CPfig.plot_data(cps,'contourf',outpath,fname,time,V=N.arange(5,105,5)) mplcommand = 'contour' plotkwargs = {} if dz: clvs = N.arange(100, 5100, 100) else: clvs = N.arange(10, 85, 2.5) if mplcommand[:7] == 'contour': plotkwargs['levels'] = clvs plotkwargs['cmap'] = plt.cm.ocean_r cf2 = CPfig.plot_data(cps, mplcommand, outpath, fname, time, **plotkwargs) # CPfig.fig.tight_layout() plt.close(fig) if twoplot: P2.save(outpath, fname + "_twopanel") if return_ax: return C.cf, cf2
def plot_xs(self, vrbl, ttime, outpath, clvs=0, ztop=0): """ Inputs: vrbl : variable to plot, from this list: parawind,perpwind,wind,U,V,W,T,RH, ttime : time in ... format outpath : absolute path to directory to save output """ tidx = self.W.get_time_idx(ttime) xint = self.xx.astype(int) yint = self.yy.astype(int) # Get terrain heights terrain_z, heighthalf = self.get_height(self.tidx, xint, yint, self.W.z_dim, self.hyp_pts) # Set up plot # Length of x-section in km xs_len = (1 / 1000.0) * N.sqrt( (-1.0 * self.hyp_pts * self.W.dy * N.cos(self.angle))**2 + (self.hyp_pts * self.W.dy * N.sin(self.angle))**2) # Generate ticks along cross-section xticks = N.arange(0, xs_len, xs_len / self.hyp_pts) xlabels = [r"%3.0f" % t for t in xticks] grid = N.swapaxes( N.repeat(N.array(xticks).reshape(self.hyp_pts, 1), self.W.z_dim, axis=1), 0, 1) ######### #### ADD SELF BELOW HERE ######### # Plotting if self.W.dx != self.W.dy: print("Square domains only here") else: # TODO: allow easier change of defaults? self.fig.gca().axis([ 0, (hyp_pts * self.W.dx / 1000.0) - 1, self.D.plot_zmin, self.D.plot_zmax + self.D.plot_dz ]) # Logic time # First, check to see if v is in the list of computable or default # variables within WRFOut (self.W) # If not, maybe it can be computed here. # If not, raise Exception. # pdb.set_trace() # TODO: vailable_vars in WRFOut to check this ps = {'t': tidx, 'la': yint, 'lo': xint} if vrbl in self.W.available_vrbls: data = self.W.get(vrbl, ps) elif vrbl is 'parawind': u = self.W.get('U', ps) v = self.W.get('V', ps) data = N.cos(angle) * u - N.sin(angle) * v # clvs = u_wind_levels extends = 'both' CBlabel = r'Wind Speed (ms$^{-1}$)' elif vrbl is 'perpwind': u = self.W.get('U', ps) v = self.W.get('V', ps) # Note the negative here. I think it's alright? TODO data = -N.cos(angle) * v + N.sin(angle) * u clvs = u_wind_levels extends = 'both' CBlabel = r'Wind Speed (ms$^{-1}$)' else: print("Unsupported variable", vrbl) raise Exception # lv = '2000' # Very hacky, setting surface level # S = Scales(vrbl,lv) # multiplier = S.get_multiplier(vrbl,lv) # This is awful.... # if S.cm: # cmap = S.cm # elif isinstance(S.clvs,N.ndarray): # if plottype == 'contourf': # cmap = plt.cm.jet # else: # pass # else: # cmap = plt.cm.jet # if clvs: pass # This is where to get clvs... #clvs = N.arange(-25,30,5) kwargs = {} kwargs['alpha'] = 0.6 #kwargs['extend'] = 'both' if isinstance(clvs, N.ndarray): kwargs['levels'] = clvs cf = self.ax.contourf(grid, heighthalf, data[0, ...], **kwargs) #, # cf = self.ax.contourf(grid[0,:],grid[:,0],data[0,...],alpha=0.6,extend='both')#levels=clvs, # extend='both')#, cmap=cmap) #norm=, # cf = self.ax.contourf(data[0,...]) # pdb.set_trace() self.ax.plot( xticks, terrain_z, color='k', ) self.ax.fill_between(xticks, terrain_z, 0, facecolor='lightgrey') # What is this? TODO labeldelta = 15 self.ax.set_yticks( N.arange(self.D.plot_zmin, self.D.plot_zmax + self.D.plot_dz, self.D.plot_dz)) self.ax.set_xlabel("Distance along cross-section (km)") self.ax.set_ylabel("Height above sea level (m)") datestr = utils.string_from_time('output', ttime) if ztop: self.ax.set_ylim([0, ztop * 1000]) naming = [vrbl, 'xs', datestr] fname = self.create_fname(*naming) self.save(self.fig, outpath, fname) #self.close() CBlabel = str(vrbl) # Save a colorbar # Only if one doesn't exist self.just_one_colorbar(outpath, fname + 'CB', cf, label=CBlabel) self.draw_transect(outpath, fname + 'Tsct')
def plot_average(self, vrbl, avepts, ttime, outpath, clvs=0, ztop=0, f_suffix=False, cmap='jet', contour_vrbl='skip', contour_clvs=False, cflabel=False, cftix=False): self.tidx = self.W.get_time_idx(ttime) AVEDATA = {'cf_vrbl': {}, 'ct_vrbl': {}} for shn in range(-avepts, avepts + 1): if shn == -avepts: self.translate_xs(shn) else: self.translate_xs(1) xint = self.xx.astype(int) yint = self.yy.astype(int) # Get terrain heights terrain_z, heighthalf = self.get_height(self.tidx, xint, yint, self.W.z_dim, self.hyp_pts) # Set up plot # Length of x-section in km xs_len = (1 / 1000.0) * N.sqrt( (-1.0 * self.hyp_pts * self.W.dy * N.cos(self.angle))**2 + (self.hyp_pts * self.W.dy * N.sin(self.angle))**2) # Generate ticks along cross-section xticks = N.arange(0, xs_len, xs_len / self.hyp_pts) xlabels = [r"%3.0f" % t for t in xticks] grid = N.repeat(N.array(xticks).reshape(self.hyp_pts, 1), self.W.z_dim, axis=1) # Plotting if self.W.dx != self.W.dy: print("Square domains only here") else: # TODO: allow easier change of defaults? self.fig.gca().axis([ 0, (self.hyp_pts * self.W.dx / 1000.0) - 1, self.D.plot_zmin, self.D.plot_zmax + self.D.plot_dz ]) for nn, v in enumerate([vrbl, contour_vrbl]): print(v) if v == 'skip': continue elif v in self.W.available_vrbls: # data = self.W.get(vrbl,**ps) data = self.get_wrfout_slice(v, utc=self.tidx, y=yint, x=xint) elif v is 'parawind': # u = self.W.get('U',**ps) # v = self.W.get('V',**ps) u = self.get_wrfout_slice('U', utc=self.tidx, y=yint, x=xint) v = self.get_wrfout_slice('V', utc=self.tidx, y=yint, x=xint) data = N.cos(self.angle) * u + N.sin(self.angle) * v # data = N.cos(self.angle)*u - N.sin(self.angle)*v # import pdb; pdb.set_trace() # clvs = u_wind_levels extends = 'both' CBlabel = r'Wind Speed (ms$^{-1}$)' elif v is 'perpwind': u = self.get_wrfout_slice('U', utc=self.tidx, y=yint, x=xint) v = self.get_wrfout_slice('V', utc=self.tidx, y=yint, x=xint) # u = self.W.get('U',ps) # v = self.W.get('V',ps) # Note the negative here. I think it's alright? TODO data = -N.cos(self.angle) * v + N.sin(self.angle) * u # clvs = u_wind_levels extends = 'both' CBlabel = r'Wind Speed (ms$^{-1}$)' else: print(("Unsupported variable", v)) raise Exception if nn == 0: data = N.swapaxes(data[0, :, :], 1, 0) AVEDATA['cf_vrbl'][shn] = data else: data = N.swapaxes(data[0, :, :], 1, 0) AVEDATA['ct_vrbl'][shn] = data for nn, v in enumerate([vrbl, contour_vrbl]): if nn == 0: kwargs = {} kwargs['alpha'] = 0.6 kwargs['extend'] = 'both' if isinstance(clvs, N.ndarray): kwargs['levels'] = clvs alldata = N.zeros( ((2 * avepts) + 1, grid.shape[0], grid.shape[1])) for n, nn in enumerate(AVEDATA['cf_vrbl'].keys()): alldata[n, :, :] = AVEDATA['cf_vrbl'][nn] avedata = N.mean(alldata, axis=0) cf = self.ax.contourf(grid, heighthalf, avedata, cmap=cmap, **kwargs) #, elif contour_vrbl is not 'skip': alldata = N.zeros( ((2 * avepts) + 1, grid.shape[0], grid.shape[1])) for n, nn in enumerate(AVEDATA['ct_vrbl'].keys()): alldata[n, :, :] = AVEDATA['ct_vrbl'][nn] avedata = N.mean(alldata, axis=0) ct = self.ax.contour(grid, heighthalf, data, colors=[ 'k', ], levels=contour_clvs, linewidths=0.3) self.ax.clabel(ct, inline=1, fontsize=6, fmt='%d') self.ax.fill_between(xticks, terrain_z[:, 0], 0, facecolor='lightgrey') labeldelta = 15 self.ax.set_yticks( N.arange(self.D.plot_zmin, self.D.plot_zmax + self.D.plot_dz, self.D.plot_dz)) self.ax.set_xlabel("Distance along cross-section (km)") self.ax.set_ylabel("Height above sea level (m)") datestr = utils.string_from_time('output', ttime) if ztop: self.ax.set_ylim([0, ztop * 1000]) naming = [vrbl, 'xs_ave', datestr, f_suffix] fname = self.create_fname(*naming) self.save(outpath, fname) #self.close() CBlabel = str(vrbl) # Save a colorbar # Only if one doesn't exist self.just_one_colorbar(outpath, fname + 'CB', cf, label=cflabel, tix=cftix) self.draw_transect(outpath, fname + 'Tsct') plt.close(self.fig)
def composite_profile(self, va, plot_time, plot_latlon, wrfouts, outpath, dom=1, mean=True, std=True, xlim=False, ylim=False, fig=False, ax=False, locname=0, ml=-2): """ Loop over wrfout files. Get profile of variable Plot all members Optional standard deviation Optional mean If ax, save image to that axis ml : member level. negative number that corresponds to the folder in absolute string for naming purposes. """ # Set up figure if isinstance(fig, M.figure.Figure): self.fig = fig self.ax = ax else: self.fig, self.ax = plt.subplots() # Plot settings if xlim: xmin, xmax, xint = xlim if ylim: if ylim[1] > ylim[0]: # top to bottom P_top, P_bot, dp = [y * 100.0 for y in ylim] else: P_bot, P_top, dp = [y * 100.0 for y in ylim] else: P_bot = 100000.0 P_top = 20000.0 dp = 10000.0 # plevs = N.arange(P_bot,P_top,dp) # Get wrfout prototype for information W = WRFOut(wrfouts[0]) lat, lon = plot_latlon datestr = utils.string_from_time('output', plot_time) t_idx = W.get_time_idx(plot_time, ) y, x, exact_lat, exact_lon = utils.getXY(W.lats1D, W.lons1D, lat, lon) slices = {'t': t_idx, 'la': y, 'lo': x} #var_slices = {'t': t_idx, 'lv':0, 'la':y, 'lo':x} # Initialise array # Number of levels and ensembles: nPlevs = W.z_dim data = W.get(va, slices) nvarlevs = data.shape[1] nens = len(wrfouts) # 2D: (profile,member) profile_arr = N.zeros((nvarlevs, nens)) composite_P = N.zeros((nPlevs, nens)) # Set up legend labels = [] colourlist = utils.generate_colours(M, nens) # M.rcParams['axes.color_cycle'] = colourlist # Collect profiles for n, wrfout in enumerate(wrfouts): W = WRFOut(wrfout) # Get pressure levels composite_P[:, n] = W.get('pressure', slices)[0, :, 0, 0] #elev = self.W.get('HGT',H_slices) #pdb.set_trace() # Grab variable profile_arr[:, n] = W.get(va, slices)[0, :, 0, 0] # Plot variable on graph self.ax.plot(profile_arr[:, n], composite_P[:, n], color=colourlist[n]) member = wrfout.split('/')[ml] labels.append(member) # if locname=='KOAX': pdb.set_trace() # Compute mean, std etc if mean: profile_mean = N.mean(profile_arr, axis=1) profile_mean_P = N.mean(composite_P, axis=1) self.ax.plot(profile_mean, profile_mean_P, color='black') if std: # Assume mean P across ensemble is correct level # to plot standard deviation profile_std = N.std(profile_arr, axis=1) std_upper = profile_mean + profile_std std_lower = profile_mean - profile_std self.ax.plot(std_upper, profile_mean_P, 'k--') self.ax.plot(std_lower, profile_mean_P, 'k--') if not locname: fname = '_'.join(('profile_comp', va, datestr, '{0:03d}'.format(x), '{0:03d}'.format(y))) + '.png' else: fname = '_'.join(('profile_comp', va, datestr, locname)) + '.png' # Set semi-log graph self.ax.set_yscale('log') # Plot limits, ticks yticks = N.arange(P_bot, P_top + dp * 100.0, -100 * 100.0) # yticks = N.arange(P_bot,P_top+dp,-dp*100) # self.ax.set_yticks(yticks) ylabels = ["%4u" % (p / 100.0) for p in yticks] self.ax.set_yticks(yticks) self.ax.set_yticklabels(ylabels) # import pdb; pdb.set_trace() # self.ax.yaxis.tick_right() #plt.axis([-20,50,105000.0,20000.0]) #plt.xlabel(r'Temperature ($^{\circ}$C) at 1000 hPa') #plt.xticks(xticks,['' if tick%10!=0 else str(tick) for tick in xticks]) self.ax.set_ylabel('Pressure (hPa)') #yticks = N.arange(self.P_bot,P_t-1,-10**4) #plt.yticks(yticks,yticks/100) if xlim: self.ax.set_xlim([xmin, xmax]) xticks = N.arange(xmin, xmax + xint, xint) self.ax.set_xticks(xticks) # Flip y axis # Limits are already set self.ax.set_ylim([P_bot, P_top]) # plt.tight_layout(self.fig) #plt.autoscale(enable=1,axis='x') #ax = plt.gca() #ax.relim() #ax.autoscale_view() #plt.draw() self.ax.legend(labels, loc=2, fontsize=6) self.save(outpath, fname) plt.close(self.fig)
def plot_data(self,data,mplcommand,p2p,fname,pt,no_title=1,save=1,**kwargs): """ Generic method that plots any matrix of data on a map Inputs: data : lat/lon matrix of data vrbl : variable type for contouring convention m : basemap instance mplcommand : contour or contourf etc p2p : path to plots fname : filename for plot V : scale for contours no_title : switch to turn off title save : whether to save to file """ # INITIALISE # self.fig = plt.figure() # self.fig = self.figsize(8,8,self.fig) # Create a default figure size if not set by user # self.fig.set_size_inches(5,5) self.bmap,self.x,self.y = self.basemap_setup()#ax=self.ax) self.mplcommand = mplcommand self.data = data self.la_n = self.data.shape[-2] self.lo_n = self.data.shape[-1] # if plottype == 'contourf': # f1 = self.bmap.contourf(*plotargs,**plotkwargs) # elif plottype == 'contour': # plotkwargs['colors'] = 'k' # f1 = self.bmap.contour(*plotargs,**plotkwargs) # scaling_func = M.ticker.FuncFormatter(lambda x, pos:'{0:d}'.format(int(x*multiplier))) # plt.clabel(f1, inline=1, fmt=scaling_func, fontsize=9, colors='k') plotargs, plotkwargs = self.get_contouring(**kwargs) # pdb.set_trace() if self.mplcommand == 'contour': f1 = self.bmap.contour(*plotargs,**plotkwargs) elif self.mplcommand == 'contourf': f1 = self.bmap.contourf(*plotargs,**plotkwargs) elif self.mplcommand == 'pcolor': f1 = self.bmap.pcolor(*plotargs,**plotkwargs) elif self.mplcommand == 'pcolormesh': f1 = self.bmap.pcolormesh(*plotargs,**plotkwargs) elif self.mplcommand == 'scatter': f1 = self.bmap.scatter(*plotargs,**plotkwargs) else: print("Specify plot type.") raise Exception # LABELS, TITLES etc """ Change these to hasattr! """ #if self.C.plot_titles: if not no_title: title = utils.string_from_time('title',pt,tupleformat=0) plt.title(title) plot_colorbar = 1 if plot_colorbar: self.fig.colorbar(f1,orientation='horizontal') # plt.show(self.fig) # div0 = make_axes_locatable(self.ax) # cax0 = div0.append_axes("bottom", size="20%", pad=0.05) # cb0 = self.fig.colorbar(f1, cax=cax0) # SAVE FIGURE datestr = utils.string_from_time('output',pt,tupleformat=0) # self.fname = self.create_fname(fpath) # No da variable here if save: self.save(p2p,fname) plt.close(self.fig) return f1
def plot_skewT(self,plot_time,plot_latlon,dom,save_output,save_plot=1): # Defines the ranges of the plot, do not confuse with self.P_bot and self.P_top self.barb_increments = {'half': 2.5,'full':5.0,'flag':25.0} self.skewness = 37.5 self.P_bot = 100000. self.P_top = 10000. self.dp = 100. self.plevs = N.arange(self.P_bot,self.P_top-1,-self.dp) # pdb.set_trace() prof_lat, prof_lon = plot_latlon datestr = utils.string_from_time('output',plot_time) t_idx = self.W.get_time_idx(plot_time,tuple_format=1) y,x, exact_lat, exact_lon = gridded_data.getXY(self.W.lats1D,self.W.lons1D,prof_lat,prof_lon) # Create figure if save_plot: height, width = (10,10) fig = plt.figure(figsize=(width,height)) self.isotherms() self.isobars() self.dry_adiabats() self.moist_adiabats() P_slices = {'t': t_idx, 'la': y, 'lo': x} H_slices = {'t':t_idx, 'lv':0, 'la':y, 'lo':x} # pdb.set_trace() P = self.W.get('pressure',P_slices)[0,:,0,0] elev = self.W.get('HGT',H_slices) thin_locs = gridded_data.thinned_barbs(P) self.windbarbs(self.W.nc,t_idx,y,x,P,thin_locs,n=45,color='blue') self.temperature(self.W.nc,t_idx,y,x,P,linestyle='solid',color='blue') self.dewpoint(self.W.nc,t_idx,y,x,P,linestyle='dashed',color='blue') xticks = N.arange(-20,51,5) yticks = N.arange(100000.0,self.P_top-1,-10**4) ytix = ["%4u" %(p/100.0) for p in yticks] plt.xticks(xticks,['' if tick%10!=0 else str(tick) for tick in xticks]) plt.yticks(yticks,ytix) plt.axis([-20,50,105000.0,20000.0]) plt.xlabel(r'Temperature ($^{\circ}$C) at 1000 hPa') plt.xticks(xticks,['' if tick%10!=0 else str(tick) for tick in xticks]) plt.ylabel('Pressure (hPa)') plt.yticks(yticks,ytix) #yticks = N.arange(self.P_bot,P_t-1,-10**4) #plt.yticks(yticks,yticks/100) fname = '_'.join(('skewT',datestr,'{0:03d}'.format(x),'{0:03d}'.format(y))) + '.png' utils.trycreate(self.path_to_output) fpath = os.path.join(self.path_to_output,fname) plt.savefig(fpath) plt.close() # For saving Skew T data if save_output: # Pickle files are saved here: pickle_fname = '_'.join(('WRFsounding',datestr,'{0:03d}'.format(x), '{0:03d}'.format(y)+'.p')) pickle_path = os.path.join(self.C.pickledir,pickle_fname) u,v = self.return_data('wind',self.W.nc,t_idx,y,x,thin_locs) T = self.return_data('temp',self.W.nc,t_idx,y,x,thin_locs,P=P) Td = self.return_data('dwpt',self.W.nc,t_idx,y,x,thin_locs,P=P) data_dict = {'u':u,'v':v,'T':T,'Td':Td,'P':P} with open(pickle_path,'wb') as p: pickle.dump(data_dict,p) print("Saving data to {0}".format(pickle_path)) return
def twopanel_profile(self, va, time, wrf_sds, out_sd, two_panel=1, dom=1, mean=1, std=1, xlim=0, ylim=0, latlon=0, locname=0, overlay=0, ml=-2): """ Create two-panel figure with profile location on map, with profile of all ensemble members in comparison. Inputs: va : variable for profile time : time of plot wrf_sds : subdirs containing wrf file out_d : out directory for plots Optional: two_panel : add inset for plot location dom : WRF domain to use mean : overlay mean on profile std : overlay +/- std dev on profile xlim : three-item list/tuple with limits, spacing interval for xaxis, in whatever default units ylim : similarly for yaxis but in hPa or dictionary with locations (METAR etc) and two-item tuple latlon : two-item list/tuple with lat/lon. If not specified, use pop-ups to select. locname : pass this to the filename of output for saving overlay : data from the same time to overlay on inset ml : member level. negative number that corresponds to the folder in absolute string for naming purposes. """ # Initialise with first wrfout file self.W = self.get_wrfout(wrf_sds[0], dom=dom) outpath = self.get_outpath(out_sd) # Get list of all wrfout files enspaths = self.list_ncfiles(wrf_sds) self.data = 0 if two_panel: P2 = Figure(self.C, self.W, layout='inseth') if overlay: F = BirdsEye(self.C, self.W) self.data = F.plot2D('cref', time, 2000, dom, outpath, save=0, return_data=1) # Create basemap for clicker object # F = BirdsEye(self.C,self.W) # self.data = F.plot2D('cref',time,2000,dom,outpath,save=0,return_data=1) # TODO: Not sure basemap inset works for lat/lon specified if isinstance(latlon, collections.Sequence): if not len(latlon) == 2: print( "Latitude and longitude needs to be two-item list/tuple.") raise Exception lat0, lon0 = latlon C = Clicker(self.C, self.W, fig=P2.fig, ax=P2.ax0, data=self.data) x0, y0 = C.bmap(lon0, lat0) C.ax.scatter(x0, y0, marker='x') else: t_long = utils.string_from_time('output', time) print("Pick location for {0}".format(t_long)) C = Clicker(self.C, self.W, fig=P2.fig, ax=P2.ax0, data=self.data) # fig should be P2.fig. # C.fig.tight_layout() # Pick location for profile C.click_x_y(plotpoint=1) lon0, lat0 = C.bmap(C.x0, C.y0, inverse=True) # Compute profile P = Profile(self.C) P.composite_profile(va, time, (lat0, lon0), enspaths, outpath, dom=dom, mean=mean, std=std, xlim=xlim, ylim=ylim, fig=P2.fig, ax=P2.ax1, locname=locname, ml=ml)
def plot_xs(self,vrbl,ttime,outpath,clvs=0,ztop=0): """ Inputs: vrbl : variable to plot, from this list: parawind,perpwind,wind,U,V,W,T,RH, ttime : time in ... format outpath : absolute path to directory to save output """ tidx = self.W.get_time_idx(ttime) xint = self.xx.astype(int) yint = self.yy.astype(int) # Get terrain heights terrain_z, heighthalf = self.get_height(self.tidx,xint,yint,self.W.z_dim,self.hyp_pts) # Set up plot # Length of x-section in km xs_len = (1/1000.0) * N.sqrt((-1.0*self.hyp_pts*self.W.dy*N.cos(self.angle))**2 + (self.hyp_pts*self.W.dy*N.sin(self.angle))**2) # Generate ticks along cross-section xticks = N.arange(0,xs_len,xs_len/self.hyp_pts) xlabels = [r"%3.0f" %t for t in xticks] grid = N.swapaxes(N.repeat(N.array(xticks).reshape(self.hyp_pts,1),self.W.z_dim,axis=1),0,1) ######### #### ADD SELF BELOW HERE ######### # Plotting if self.W.dx != self.W.dy: print("Square domains only here") else: # TODO: allow easier change of defaults? self.fig.gca().axis([0,(hyp_pts*self.W.dx/1000.0)-1,self.D.plot_zmin,self.D.plot_zmax+self.D.plot_dz]) # Logic time # First, check to see if v is in the list of computable or default # variables within WRFOut (self.W) # If not, maybe it can be computed here. # If not, raise Exception. # pdb.set_trace() # TODO: vailable_vars in WRFOut to check this ps = {'t':tidx, 'la':yint, 'lo':xint} if vrbl in self.W.available_vrbls: data = self.W.get(vrbl,ps) elif vrbl is 'parawind': u = self.W.get('U',ps) v = self.W.get('V',ps) data = N.cos(angle)*u - N.sin(angle)*v # clvs = u_wind_levels extends = 'both' CBlabel = r'Wind Speed (ms$^{-1}$)' elif vrbl is 'perpwind': u = self.W.get('U',ps) v = self.W.get('V',ps) # Note the negative here. I think it's alright? TODO data = -N.cos(angle)*v + N.sin(angle)*u clvs = u_wind_levels extends = 'both' CBlabel = r'Wind Speed (ms$^{-1}$)' else: print("Unsupported variable",vrbl) raise Exception # lv = '2000' # Very hacky, setting surface level # S = Scales(vrbl,lv) # multiplier = S.get_multiplier(vrbl,lv) # This is awful.... # if S.cm: # cmap = S.cm # elif isinstance(S.clvs,N.ndarray): # if plottype == 'contourf': # cmap = plt.cm.jet # else: # pass # else: # cmap = plt.cm.jet # if clvs: pass # This is where to get clvs... #clvs = N.arange(-25,30,5) kwargs = {} kwargs['alpha'] = 0.6 #kwargs['extend'] = 'both' if isinstance(clvs,N.ndarray): kwargs['levels'] = clvs cf = self.ax.contourf(grid,heighthalf,data[0,...],**kwargs)#, # cf = self.ax.contourf(grid[0,:],grid[:,0],data[0,...],alpha=0.6,extend='both')#levels=clvs, # extend='both')#, cmap=cmap) #norm=, # cf = self.ax.contourf(data[0,...]) # pdb.set_trace() self.ax.plot(xticks,terrain_z,color='k',) self.ax.fill_between(xticks,terrain_z,0,facecolor='lightgrey') # What is this? TODO labeldelta = 15 self.ax.set_yticks(N.arange(self.D.plot_zmin, self.D.plot_zmax+self.D.plot_dz,self.D.plot_dz)) self.ax.set_xlabel("Distance along cross-section (km)") self.ax.set_ylabel("Height above sea level (m)") datestr = utils.string_from_time('output',ttime) if ztop: self.ax.set_ylim([0,ztop*1000]) naming = [vrbl,'xs',datestr] fname = self.create_fname(*naming) self.save(self.fig,outpath,fname) #self.close() CBlabel = str(vrbl) # Save a colorbar # Only if one doesn't exist self.just_one_colorbar(outpath,fname+'CB',cf,label=CBlabel) self.draw_transect(outpath,fname+'Tsct')
def plot2D(self,vrbl,t,lv,dom,outpath,bounding=0,smooth=1, plottype='contourf',save=1,return_data=0): """ Inputs: vrbl : variable string t : date/time in (YYYY,MM,DD,HH,MM,SS) or datenum format If tuple of two dates, it's start time and end time, e.g. for finding max/average. lv : level dom : domain outpath : absolute path to output bounding : list of four floats (Nlim, Elim, Slim, Wlim): Nlim : northern limit Elim : eastern limit Slim : southern limit Wlim : western limit smooth : smoothing. 1 is off. integer greater than one is the degree of smoothing, to be specified. save : whether to save to file """ # INITIALISE self.fig.set_size_inches(8,8) self.bmap,self.x,self.y = self.basemap_setup(smooth=smooth) self.mplcommand = plottype # Make sure smooth=0 is corrected to 1 # They are both essentially 'off'. if smooth==0: smooth = 1 # Get indices for time, level, lats, lons if isinstance(t,collections.Sequence) and len(t)!=6: # List of two dates, start and end # pdb.set_trace() it_idx = self.W.get_time_idx(t[0]) ft_idx = self.W.get_time_idx(t[1]) assert ft_idx > it_idx tidx = slice(it_idx,ft_idx,None) title = "range" datestr = "range" else: tidx = self.W.get_time_idx(t) title = utils.string_from_time('title',t) datestr = utils.string_from_time('output',t) # Until pressure coordinates are fixed TODO lvidx = 0 latidx, lonidx = self.get_limited_domain(bounding,smooth=smooth) # if vc == 'surface': # lv_idx = 0 # elif lv == 'all': # lv_idx = 'all' # else: # print("Need to sort other levels") # raise Exception # FETCH DATA ncidx = {'t': tidx, 'lv': lvidx, 'la': latidx, 'lo': lonidx} self.data = self.W.get(vrbl,ncidx)#,**vardict) self.la_n = self.data.shape[-2] self.lo_n = self.data.shape[-1] # COLORBAR, CONTOURING plotargs, plotkwargs = self.get_contouring(vrbl,lv) # S = Scales(vrbl,lv) # multiplier = S.get_multiplier(vrbl,lv) # if S.cm: # plotargs = (self.x,self.y,data.reshape((la_n,lo_n)),S.clvs) # cmap = S.cm # elif isinstance(S.clvs,N.ndarray): # if plottype == 'contourf': # plotargs = (self.x,self.y,data.reshape((la_n,lo_n)),S.clvs) # cmap = plt.cm.jet # else: # plotargs = (self.x,self.y,data.reshape((la_n,lo_n)),S.clvs) # else: # plotargs = (self.x,self.y,data.reshape((la_n,lo_n))) # cmap = plt.cm.jet # pdb.set_trace() if self.mplcommand == 'contourf': # f1 = self.bmap.contourf(*plotargs,cmap=cmap) f1 = self.bmap.contourf(*plotargs,**plotkwargs) elif self.mplcommand == 'contour': plotkwargs['colors'] = 'k' f1 = self.bmap.contour(*plotargs,**kwargs) scaling_func = M.ticker.FuncFormatter(lambda x, pos:'{0:d}'.format(int(x*multiplier))) plt.clabel(f1, inline=1, fmt=scaling_func, fontsize=9, colors='k') # LABELS, TITLES etc if self.C.plot_titles: plt.title(title) if self.mplcommand == 'contourf' and self.C.colorbar: plt.colorbar(f1,orientation='horizontal') # SAVE FIGURE # pdb.set_trace() lv_na = utils.get_level_naming(vrbl,lv) naming = [vrbl,lv_na,datestr] if dom: naming.append(dom) self.fname = self.create_fname(*naming) if save: self.save(outpath,self.fname) plt.close() if isinstance(self.data,N.ndarray): return self.data.reshape((self.la_n,self.lo_n))
def plot_average(self,vrbl,avepts,ttime,outpath,clvs=0,ztop=0,f_suffix=False, cmap='jet',contour_vrbl='skip',contour_clvs=False, cflabel=False,cftix=False): self.tidx = self.W.get_time_idx(ttime) AVEDATA = {'cf_vrbl':{},'ct_vrbl':{}} for shn in range(-avepts,avepts+1): if shn == -avepts: self.translate_xs(shn) else: self.translate_xs(1) xint = self.xx.astype(int) yint = self.yy.astype(int) # Get terrain heights terrain_z, heighthalf = self.get_height(self.tidx,xint,yint,self.W.z_dim,self.hyp_pts) # Set up plot # Length of x-section in km xs_len = (1/1000.0) * N.sqrt((-1.0*self.hyp_pts*self.W.dy*N.cos(self.angle))**2 + (self.hyp_pts*self.W.dy*N.sin(self.angle))**2) # Generate ticks along cross-section xticks = N.arange(0,xs_len,xs_len/self.hyp_pts) xlabels = [r"%3.0f" %t for t in xticks] grid = N.repeat(N.array(xticks).reshape(self.hyp_pts,1),self.W.z_dim,axis=1) # Plotting if self.W.dx != self.W.dy: print("Square domains only here") else: # TODO: allow easier change of defaults? self.fig.gca().axis([0,(self.hyp_pts*self.W.dx/1000.0)-1,self.D.plot_zmin,self.D.plot_zmax+self.D.plot_dz]) for nn, v in enumerate([vrbl,contour_vrbl]): print(v) if v == 'skip': continue elif v in self.W.available_vrbls: # data = self.W.get(vrbl,**ps) data = self.get_wrfout_slice(v,utc=self.tidx,y=yint,x=xint) elif v is 'parawind': # u = self.W.get('U',**ps) # v = self.W.get('V',**ps) u = self.get_wrfout_slice('U',utc=self.tidx,y=yint,x=xint) v = self.get_wrfout_slice('V',utc=self.tidx,y=yint,x=xint) data = N.cos(self.angle)*u + N.sin(self.angle)*v # data = N.cos(self.angle)*u - N.sin(self.angle)*v # import pdb; pdb.set_trace() # clvs = u_wind_levels extends = 'both' CBlabel = r'Wind Speed (ms$^{-1}$)' elif v is 'perpwind': u = self.get_wrfout_slice('U',utc=self.tidx,y=yint,x=xint) v = self.get_wrfout_slice('V',utc=self.tidx,y=yint,x=xint) # u = self.W.get('U',ps) # v = self.W.get('V',ps) # Note the negative here. I think it's alright? TODO data = -N.cos(self.angle)*v + N.sin(self.angle)*u # clvs = u_wind_levels extends = 'both' CBlabel = r'Wind Speed (ms$^{-1}$)' else: print("Unsupported variable",v) raise Exception if nn == 0: data = N.swapaxes(data[0,:,:],1,0) AVEDATA['cf_vrbl'][shn] = data else: data = N.swapaxes(data[0,:,:],1,0) AVEDATA['ct_vrbl'][shn] = data for nn, v in enumerate([vrbl,contour_vrbl]): if nn == 0: kwargs = {} kwargs['alpha'] = 0.6 kwargs['extend'] = 'both' if isinstance(clvs,N.ndarray): kwargs['levels'] = clvs alldata = N.zeros(((2*avepts)+1,grid.shape[0],grid.shape[1])) for n,nn in enumerate(AVEDATA['cf_vrbl'].keys()): alldata[n,:,:] = AVEDATA['cf_vrbl'][nn] avedata = N.mean(alldata,axis=0) cf = self.ax.contourf(grid,heighthalf,avedata,cmap=cmap,**kwargs)#, elif contour_vrbl is not 'skip': alldata = N.zeros(((2*avepts)+1,grid.shape[0],grid.shape[1])) for n,nn in enumerate(AVEDATA['ct_vrbl'].keys()): alldata[n,:,:] = AVEDATA['ct_vrbl'][nn] avedata = N.mean(alldata,axis=0) ct = self.ax.contour(grid,heighthalf,data,colors=['k',],levels=contour_clvs,linewidths=0.3) self.ax.clabel(ct,inline=1,fontsize=6,fmt='%d') self.ax.fill_between(xticks,terrain_z[:,0],0,facecolor='lightgrey') labeldelta = 15 self.ax.set_yticks(N.arange(self.D.plot_zmin, self.D.plot_zmax+self.D.plot_dz,self.D.plot_dz)) self.ax.set_xlabel("Distance along cross-section (km)") self.ax.set_ylabel("Height above sea level (m)") datestr = utils.string_from_time('output',ttime) if ztop: self.ax.set_ylim([0,ztop*1000]) naming = [vrbl,'xs_ave',datestr,f_suffix] fname = self.create_fname(*naming) self.save(outpath,fname) #self.close() CBlabel = str(vrbl) # Save a colorbar # Only if one doesn't exist self.just_one_colorbar(outpath,fname+'CB',cf,label=cflabel,tix=cftix) self.draw_transect(outpath,fname+'Tsct') plt.close(self.fig)
sys.path.append('/uufs/chpc.utah.edu/common/home/u0737349/gitprojects/') from DKE_settings import Settings from WEM.postWRF import WRFEnviron import WEM.utils as utils # Time script scriptstart = time.time() # Initialise settings and environment config = Settings() p = WRFEnviron(config) # User settings init_time = utils.string_from_time('dir', (2009, 9, 10, 0, 0, 0), strlen='hour') rootdir = '/uufs/chpc.utah.edu/common/home/horel-group2/lawson2/' outdir = '/uufs/chpc.utah.edu/common/home/u0737349/public_html/paper2/' # Create lists of all fig, ax, cb objects figs = {} axes = {} cbs = {} ensnames = ['c00'] + ['p{0:02d}'.format(n) for n in range(1, 11)] #for rundate in ('25','27','29'): plot_all = 1 if plot_all: # for rundate in ['25','27','29']: for rundate in ['27', '29']:
sys.path.append('/uufs/chpc.utah.edu/common/home/u0737349/gitprojects/') from DKE_settings import Settings from WEM.postWRF import WRFEnviron import WEM.utils as utils # Time script scriptstart = time.time() # Initialise settings and environment config = Settings() p = WRFEnviron(config) # User settings init_time = utils.string_from_time('dir',(2009,9,10,0,0,0),strlen='hour') rootdir = '/uufs/chpc.utah.edu/common/home/horel-group2/lawson2/' outdir = '/uufs/chpc.utah.edu/common/home/u0737349/public_html/paper2/' # Create lists of all fig, ax, cb objects figs = {} axes = {} cbs = {} ensnames = ['c00'] + ['p{0:02d}'.format(n) for n in range(1,11)] #for rundate in ('25','27','29'): plot_all = 1 if plot_all: # for rundate in ['25','27','29']: for rundate in ['27','29']:
def composite_profile(self,va,plot_time,plot_latlon,wrfouts,outpath, dom=1,mean=1,std=1,xlim=0,ylim=0,fig=0,ax=0, locname=0,ml=-2): """ Loop over wrfout files. Get profile of variable Plot all members Optional standard deviation Optional mean If ax, save image to that axis ml : member level. negative number that corresponds to the folder in absolute string for naming purposes. """ # Set up figure if isinstance(fig,M.figure.Figure): self.fig = fig self.ax = ax else: self.fig, self.ax = plt.subplots() # Plot settings if xlim: xmin, xmax, xint = xlim if ylim: if ylim[1] > ylim[0]: # top to bottom P_top, P_bot, dp = [y*100.0 for y in ylim] else: P_bot, P_top, dp = [y*100.0 for y in ylim] else: P_bot = 100000.0 P_top = 20000.0 dp = 10000.0 # plevs = N.arange(P_bot,P_top,dp) # Get wrfout prototype for information W = WRFOut(wrfouts[0]) lat, lon = plot_latlon datestr = utils.string_from_time('output',plot_time) t_idx = W.get_time_idx(plot_time,) y, x, exact_lat, exact_lon = utils.getXY(W.lats1D,W.lons1D,lat,lon) slices = {'t': t_idx, 'la': y, 'lo': x} #var_slices = {'t': t_idx, 'lv':0, 'la':y, 'lo':x} # Initialise array # Number of levels and ensembles: nPlevs = W.z_dim data = W.get(va,slices) nvarlevs = data.shape[1] nens = len(wrfouts) # 2D: (profile,member) profile_arr = N.zeros((nvarlevs,nens)) composite_P = N.zeros((nPlevs,nens)) # Set up legend labels = [] colourlist = utils.generate_colours(M,nens) # M.rcParams['axes.color_cycle'] = colourlist # Collect profiles for n,wrfout in enumerate(wrfouts): W = WRFOut(wrfout) # Get pressure levels composite_P[:,n] = W.get('pressure',slices)[0,:,0,0] #elev = self.W.get('HGT',H_slices) #pdb.set_trace() # Grab variable profile_arr[:,n] = W.get(va,slices)[0,:,0,0] # Plot variable on graph self.ax.plot(profile_arr[:,n],composite_P[:,n],color=colourlist[n]) member = wrfout.split('/')[ml] labels.append(member) # if locname=='KOAX': pdb.set_trace() # Compute mean, std etc if mean: profile_mean = N.mean(profile_arr,axis=1) profile_mean_P = N.mean(composite_P,axis=1) self.ax.plot(profile_mean,profile_mean_P,color='black') if std: # Assume mean P across ensemble is correct level # to plot standard deviation profile_std = N.std(profile_arr,axis=1) std_upper = profile_mean + profile_std std_lower = profile_mean - profile_std self.ax.plot(std_upper,profile_mean_P,'k--') self.ax.plot(std_lower,profile_mean_P,'k--') if not locname: fname = '_'.join(('profile_comp',va,datestr,'{0:03d}'.format(x),'{0:03d}'.format(y))) + '.png' else: fname = '_'.join(('profile_comp',va,datestr,locname)) + '.png' # Set semi-log graph self.ax.set_yscale('log') # Plot limits, ticks yticks = N.arange(P_bot,P_top+dp*100.0,-100*100.0) # yticks = N.arange(P_bot,P_top+dp,-dp*100) # self.ax.set_yticks(yticks) ylabels = ["%4u" %(p/100.0) for p in yticks] self.ax.set_yticks(yticks) self.ax.set_yticklabels(ylabels) # import pdb; pdb.set_trace() # self.ax.yaxis.tick_right() #plt.axis([-20,50,105000.0,20000.0]) #plt.xlabel(r'Temperature ($^{\circ}$C) at 1000 hPa') #plt.xticks(xticks,['' if tick%10!=0 else str(tick) for tick in xticks]) self.ax.set_ylabel('Pressure (hPa)') #yticks = N.arange(self.P_bot,P_t-1,-10**4) #plt.yticks(yticks,yticks/100) if xlim: self.ax.set_xlim([xmin,xmax]) xticks = N.arange(xmin,xmax+xint,xint) self.ax.set_xticks(xticks) # Flip y axis # Limits are already set self.ax.set_ylim([P_bot,P_top]) # plt.tight_layout(self.fig) #plt.autoscale(enable=1,axis='x') #ax = plt.gca() #ax.relim() #ax.autoscale_view() #plt.draw() self.ax.legend(labels,loc=2,fontsize=6) self.save(outpath,fname) plt.close(self.fig)
def plot_skewT(self, plot_time, plot_latlon, dom, outpath, save_output=0, save_plot=1): # Defines the ranges of the plot, do not confuse with self.P_bot and self.P_top self.barb_increments = {'half': 2.5, 'full': 5.0, 'flag': 25.0} self.skewness = 37.5 self.P_bot = 100000. self.P_top = 10000. self.dp = 100. self.plevs = N.arange(self.P_bot, self.P_top - 1, -self.dp) # pdb.set_trace() prof_lat, prof_lon = plot_latlon datestr = utils.string_from_time('output', plot_time) t_idx = self.W.get_time_idx(plot_time) y, x, exact_lat, exact_lon = utils.getXY(self.W.lats1D, self.W.lons1D, prof_lat, prof_lon) # Create figure if save_plot: # height, width = (10,10) # fig = plt.figure(figsize=(width,height)) self.isotherms() self.isobars() self.dry_adiabats() self.moist_adiabats() # P_slices = {'t': t_idx, 'la': y, 'lo': x} # H_slices = {'t':t_idx, 'lv':0, 'la':y, 'lo':x} # pdb.set_trace() P = self.W.get('pressure', utc=t_idx, lats=y, lons=x)[0, :, 0, 0] elev = self.W.get('HGT', utc=t_idx, level=0, lats=y, lons=x) thin_locs = utils.thinned_barbs(P) self.windbarbs(self.W.nc, t_idx, y, x, P, thin_locs, n=45, color='blue') self.temperature(self.W.nc, t_idx, y, x, P, linestyle='solid', color='blue') self.dewpoint(self.W.nc, t_idx, y, x, P, linestyle='dashed', color='blue') xticks = N.arange(-20, 51, 5) yticks = N.arange(100000.0, self.P_top - 1, -10**4) ytix = ["%4u" % (p / 100.0) for p in yticks] self.ax.set_xticks( xticks, ['' if tick % 10 != 0 else str(tick) for tick in xticks]) self.ax.set_yticks(yticks, ytix) self.ax.axis([-20, 50, 105000.0, 20000.0]) self.ax.set_xlabel(r'Temperature ($^{\circ}$C) at 1000 hPa') self.ax.set_xticks( xticks, ['' if tick % 10 != 0 else str(tick) for tick in xticks]) self.ax.set_ylabel('Pressure (hPa)') self.ax.set_yticks(yticks, ytix) #yticks = N.arange(self.P_bot,P_t-1,-10**4) #plt.yticks(yticks,yticks/100) fname = '_'.join(('skewT', datestr, '{0:03d}'.format(x), '{0:03d}'.format(y))) + '.png' # utils.trycreate(self.path_to_output) # fpath = os.path.join(self.path_to_output,fname) # plt.savefig(fpath) self.save(outpath, fname) plt.close() # For saving Skew T data if save_output: # Pickle files are saved here: pickle_fname = '_'.join( ('WRFsounding', datestr, '{0:03d}'.format(x), '{0:03d}'.format(y) + '.p')) pickle_path = os.path.join(self.C.pickledir, pickle_fname) u, v = self.return_data('wind', self.W.nc, t_idx, y, x, thin_locs) T = self.return_data('temp', self.W.nc, t_idx, y, x, thin_locs, P=P) Td = self.return_data('dwpt', self.W.nc, t_idx, y, x, thin_locs, P=P) data_dict = {'u': u, 'v': v, 'T': T, 'Td': Td, 'P': P} with open(pickle_path, 'wb') as p: pickle.dump(data_dict, p) print(("Saving data to {0}".format(pickle_path))) return else: return
def plot_diff_energy(self, ptype, energy, time, folder, fname, p2p, plotname, V, no_title=0, ax=0): """ folder : directory holding computed data fname : naming scheme of required files p2p : root directory for plots V : constant values to contour at """ sw = 0 DATA = self.load_data(folder, fname, format='pickle') if isinstance(time, collections.Sequence): time = calendar.timegm(time) #for n,t in enumerate(times): for pn, perm in enumerate(DATA): f1 = DATA[perm]['file1'] f2 = DATA[perm]['file2'] if sw == 0: # Get times and info about nc files # First time to save power W1 = WRFOut(f1) permtimes = DATA[perm]['times'] sw = 1 # Find array for required time x = N.where(N.array(permtimes) == time)[0][0] data = DATA[perm]['values'][x][0] if not pn: stack = data else: stack = N.dstack((data, stack)) stack_average = N.average(stack, axis=2) if ax: kwargs1 = {'ax': ax} kwargs2 = {'save': 0} #birdseye plot with basemap of DKE/DTE F = BirdsEye(self.C, W1, **kwargs1) # 2D figure class #F.plot2D(va,t,en,lv,da,na) # Plot/save figure tstr = utils.string_from_time('output', time) fname_t = ''.join((plotname, '_{0}'.format(tstr))) # fpath = os.path.join(p2p,fname_t) fig_obj = F.plot_data(stack_average, 'contourf', p2p, fname_t, time, V, no_title=no_title, **kwargs2) if ax: return fig_obj
def plot_xs(self,vrbl,ttime,outpath,clvs=0,ztop=0,f_suffix=False, cmap='jet',contour_vrbl='skip',contour_clvs=False): """ Inputs: vrbl : variable to plot, from this list: parawind,perpwind,wind,U,V,W,T,RH, ttime : time in ... format outpath : absolute path to directory to save output """ self.tidx = self.W.get_time_idx(ttime) xint = self.xx.astype(int) yint = self.yy.astype(int) # Get terrain heights terrain_z, heighthalf = self.get_height(self.tidx,xint,yint,self.W.z_dim,self.hyp_pts) # Set up plot # Length of x-section in km xs_len = (1/1000.0) * N.sqrt((-1.0*self.hyp_pts*self.W.dy*N.cos(self.angle))**2 + (self.hyp_pts*self.W.dy*N.sin(self.angle))**2) # Generate ticks along cross-section xticks = N.arange(0,xs_len,xs_len/self.hyp_pts) xlabels = [r"%3.0f" %t for t in xticks] grid = N.repeat(N.array(xticks).reshape(self.hyp_pts,1),self.W.z_dim,axis=1) ######### #### ADD SELF BELOW HERE ######### # Plotting if self.W.dx != self.W.dy: print("Square domains only here") else: # TODO: allow easier change of defaults? self.fig.gca().axis([0,(self.hyp_pts*self.W.dx/1000.0)-1,self.D.plot_zmin,self.D.plot_zmax+self.D.plot_dz]) # Logic time # First, check to see if v is in the list of computable or default # variables within WRFOut (self.W) # If not, maybe it can be computed here. # If not, raise Exception. # pdb.set_trace() # TODO: vailable_vars in WRFOut to check this # ps = {'utc':self.tidx, 'lats':yint, 'lons':xint} for nn, v in enumerate([vrbl,contour_vrbl]): print(v) if v == 'skip': continue elif v in self.W.available_vrbls: # data = self.W.get(vrbl,**ps) data = self.get_wrfout_slice(v,utc=self.tidx,y=yint,x=xint) elif v is 'parawind': # u = self.W.get('U',**ps) # v = self.W.get('V',**ps) u = self.get_wrfout_slice('U',utc=self.tidx,y=yint,x=xint) v = self.get_wrfout_slice('V',utc=self.tidx,y=yint,x=xint) data = N.cos(self.angle)*u + N.sin(self.angle)*v # data = N.cos(self.angle)*u - N.sin(self.angle)*v # import pdb; pdb.set_trace() # clvs = u_wind_levels extends = 'both' CBlabel = r'Wind Speed (ms$^{-1}$)' elif v is 'perpwind': u = self.get_wrfout_slice('U',utc=self.tidx,y=yint,x=xint) v = self.get_wrfout_slice('V',utc=self.tidx,y=yint,x=xint) # u = self.W.get('U',ps) # v = self.W.get('V',ps) # Note the negative here. I think it's alright? TODO data = -N.cos(self.angle)*v + N.sin(self.angle)*u # clvs = u_wind_levels extends = 'both' CBlabel = r'Wind Speed (ms$^{-1}$)' else: print("Unsupported variable",v) raise Exception if nn == 0: kwargs = {} kwargs['alpha'] = 0.6 kwargs['extend'] = 'both' if isinstance(clvs,N.ndarray): kwargs['levels'] = clvs data = N.swapaxes(data[0,:,:],1,0) cf = self.ax.contourf(grid,heighthalf,data,cmap=cmap,**kwargs)#, else: # import pdb; pdb.set_trace() data = N.swapaxes(data[0,:,:],1,0) ct = self.ax.contour(grid,heighthalf,data,colors=['k',],levels=contour_clvs,linewidths=0.3) self.ax.clabel(ct,inline=1,fontsize=6,fmt='%d') self.ax.fill_between(xticks,terrain_z[:,0],0,facecolor='lightgrey') labeldelta = 15 self.ax.set_yticks(N.arange(self.D.plot_zmin, self.D.plot_zmax+self.D.plot_dz,self.D.plot_dz)) self.ax.set_xlabel("Distance along cross-section (km)") self.ax.set_ylabel("Height above sea level (m)") datestr = utils.string_from_time('output',ttime) if ztop: self.ax.set_ylim([0,ztop*1000]) naming = [vrbl,'xs',datestr,f_suffix] fname = self.create_fname(*naming) self.save(outpath,fname) #self.close() CBlabel = str(vrbl) # Save a colorbar # Only if one doesn't exist self.just_one_colorbar(outpath,fname+'CB',cf,label=CBlabel) self.draw_transect(outpath,fname+'Tsct') plt.close(self.fig)
def plot_xs(self, vrbl, ttime, outpath, clvs=0, ztop=0, f_suffix=False, cmap='jet', contour_vrbl='skip', contour_clvs=False): """ Inputs: vrbl : variable to plot, from this list: parawind,perpwind,wind,U,V,W,T,RH, ttime : time in ... format outpath : absolute path to directory to save output """ self.tidx = self.W.get_time_idx(ttime) xint = self.xx.astype(int) yint = self.yy.astype(int) # Get terrain heights terrain_z, heighthalf = self.get_height(self.tidx, xint, yint, self.W.z_dim, self.hyp_pts) # Set up plot # Length of x-section in km xs_len = (1 / 1000.0) * N.sqrt( (-1.0 * self.hyp_pts * self.W.dy * N.cos(self.angle))**2 + (self.hyp_pts * self.W.dy * N.sin(self.angle))**2) # Generate ticks along cross-section xticks = N.arange(0, xs_len, xs_len / self.hyp_pts) xlabels = [r"%3.0f" % t for t in xticks] grid = N.repeat(N.array(xticks).reshape(self.hyp_pts, 1), self.W.z_dim, axis=1) ######### #### ADD SELF BELOW HERE ######### # Plotting if self.W.dx != self.W.dy: print("Square domains only here") else: # TODO: allow easier change of defaults? self.fig.gca().axis([ 0, (self.hyp_pts * self.W.dx / 1000.0) - 1, self.D.plot_zmin, self.D.plot_zmax + self.D.plot_dz ]) # Logic time # First, check to see if v is in the list of computable or default # variables within WRFOut (self.W) # If not, maybe it can be computed here. # If not, raise Exception. # pdb.set_trace() # TODO: vailable_vars in WRFOut to check this # ps = {'utc':self.tidx, 'lats':yint, 'lons':xint} for nn, v in enumerate([vrbl, contour_vrbl]): print(v) if v == 'skip': continue elif v in self.W.available_vrbls: # data = self.W.get(vrbl,**ps) data = self.get_wrfout_slice(v, utc=self.tidx, y=yint, x=xint) elif v is 'parawind': # u = self.W.get('U',**ps) # v = self.W.get('V',**ps) u = self.get_wrfout_slice('U', utc=self.tidx, y=yint, x=xint) v = self.get_wrfout_slice('V', utc=self.tidx, y=yint, x=xint) data = N.cos(self.angle) * u + N.sin(self.angle) * v # data = N.cos(self.angle)*u - N.sin(self.angle)*v # import pdb; pdb.set_trace() # clvs = u_wind_levels extends = 'both' CBlabel = r'Wind Speed (ms$^{-1}$)' elif v is 'perpwind': u = self.get_wrfout_slice('U', utc=self.tidx, y=yint, x=xint) v = self.get_wrfout_slice('V', utc=self.tidx, y=yint, x=xint) # u = self.W.get('U',ps) # v = self.W.get('V',ps) # Note the negative here. I think it's alright? TODO data = -N.cos(self.angle) * v + N.sin(self.angle) * u # clvs = u_wind_levels extends = 'both' CBlabel = r'Wind Speed (ms$^{-1}$)' else: print(("Unsupported variable", v)) raise Exception if nn == 0: kwargs = {} kwargs['alpha'] = 0.6 kwargs['extend'] = 'both' if isinstance(clvs, N.ndarray): kwargs['levels'] = clvs data = N.swapaxes(data[0, :, :], 1, 0) cf = self.ax.contourf(grid, heighthalf, data, cmap=cmap, **kwargs) #, else: # import pdb; pdb.set_trace() data = N.swapaxes(data[0, :, :], 1, 0) ct = self.ax.contour(grid, heighthalf, data, colors=[ 'k', ], levels=contour_clvs, linewidths=0.3) self.ax.clabel(ct, inline=1, fontsize=6, fmt='%d') self.ax.fill_between(xticks, terrain_z[:, 0], 0, facecolor='lightgrey') labeldelta = 15 self.ax.set_yticks( N.arange(self.D.plot_zmin, self.D.plot_zmax + self.D.plot_dz, self.D.plot_dz)) self.ax.set_xlabel("Distance along cross-section (km)") self.ax.set_ylabel("Height above sea level (m)") datestr = utils.string_from_time('output', ttime) if ztop: self.ax.set_ylim([0, ztop * 1000]) naming = [vrbl, 'xs', datestr, f_suffix] fname = self.create_fname(*naming) self.save(outpath, fname) #self.close() CBlabel = str(vrbl) # Save a colorbar # Only if one doesn't exist self.just_one_colorbar(outpath, fname + 'CB', cf, label=CBlabel) self.draw_transect(outpath, fname + 'Tsct') plt.close(self.fig)