def plot_strongest_wind(self, itime, ftime, levels, wrf_sd=0, wrf_nc=0, out_sd=0, f_prefix=0, f_suffix=0, bounding=0, dom=0): """ Plot strongest wind at level lv between itime and ftime. Path to wrfout file is in config file. Path to plot output is also in config Inputs: levels : level(s) for wind 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. f_prefix : custom filename prefix f_suffix : custom filename suffix bounding : list of four floats (Nlim, Elim, Slim, Wlim): Nlim : northern limit Elim : eastern limit Slim : southern limit Wlim : western limit smooth : smoothing. 0 is off. non-zero integer is the degree of smoothing, to be specified. dom : domain for plotting. If zero, the only netCDF file present will be plotted. If list of integers, the script will loop over domains. """ self.W = self.get_wrfout(wrf_sd, wrf_nc, dom=dom) outpath = self.get_outpath(out_sd) # Make sure times are in datenum format and sequence. it = utils.ensure_sequence_datenum(itime) ft = utils.ensure_sequence_datenum(ftime) d_list = utils.get_sequence(dom) lv_list = utils.get_sequence(levels) for l, d in itertools.product(lv_list, d_list): F = BirdsEye(self.C, self.W) F.plot2D('strongestwind', it + ft, l, d, outpath, bounding=bounding)
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 plot_variable2D(self,va,pt,en,lv,p2p,na=0,da=0): """Plot a longitude--latitude cross-section (bird's-eye-view). Use Basemap to create geographical data ======== REQUIRED ======== va = variable(s) pt = plot time(s) nc = ensemble member(s) lv = level(s) p2p = path to plots ======== OPTIONAL ======== da = smaller domain area(s), needs dictionary || DEFAULT = 0 na = naming scheme for plot files || DEFAULT = get what you're given """ va = self.get_sequence(va) pt = self.get_sequence(pt,SoS=1) en = self.get_sequence(en) lv = self.get_sequence(lv) da = self.get_sequence(da) perms = self.make_iterator(va,pt,en,lv,da) # Find some way of looping over wrfout files first, avoiding need # to create new W instances # print("Beginning plotting of {0} figures.".format(len(list(perms)))) #pdb.set_trace() for x in perms: va,pt,en,lv,da = x W = WRFOut(en) # wrfout file class using path F = BirdsEye(self.C,W,p2p) # 2D figure class F.plot2D(va,pt,en,lv,da,na) # Plot/save figure pt_s = utils.string_from_time('title',pt) print("Plotting from file {0}: \n variable = {1}" " time = {2}, level = {3}, area = {4}.".format(en,va,pt_s,lv,da))
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 plot2D(self, vrbl, times, levels, wrf_sd=0, wrf_nc=0, out_sd=0, f_prefix=0, f_suffix=0, bounding=0, dom=0): """ Path to wrfout file is in config file. Path to plot output is also in config This script is top-most and decides if the variables is built into WRF default output or needs computing. It unstaggers and slices data from the wrfout file appropriately. Inputs: vrbl : string of variable name times : one or more date/times. Can be tuple format (YYYY,MM,DD,HH,MM,SS - calendar.timegm) Can be integer of datenum. (time.gmtime) Can be a tuple or list of either. levels : one or more levels. Lowest model level is integer 2000. Pressure level is integer in hPa, e.g. 850 Isentropic surface is a string + K, e.g. '320K' Geometric height is a string + m, e.g. '4000m' 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. f_prefix : custom filename prefix f_suffix : custom filename suffix bounding : list of four floats (Nlim, Elim, Slim, Wlim): Nlim : northern limit Elim : eastern limit Slim : southern limit Wlim : western limit smooth : smoothing. 0 is off. non-zero integer is the degree of smoothing, to be specified. dom : domain for plotting. If zero, the only netCDF file present will be plotted. If list of integers, the script will loop over domains. """ # import pdb; pdb.set_trace() self.W = self.get_wrfout(wrf_sd, wrf_nc, dom=dom) outpath = self.get_outpath(out_sd) # Make sure times are in datenum format and sequence. t_list = utils.ensure_sequence_datenum(times) d_list = utils.get_sequence(dom) lv_list = utils.get_sequence(levels) for t, l, d in itertools.product(t_list, lv_list, d_list): F = BirdsEye(self.C, self.W) F.plot2D(vrbl, t, l, d, outpath, bounding=bounding)
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