forked from 3rdparty/wrf-python
				
			
			You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							291 lines
						
					
					
						
							10 KiB
						
					
					
				
			
		
		
	
	
							291 lines
						
					
					
						
							10 KiB
						
					
					
				| #!/usr/bin/env python | |
|  | |
| import traceback | |
| import sys | |
| import sqlite3 | |
| from datetime import datetime as dt | |
|  | |
| import numpy as n | |
| import matplotlib | |
| matplotlib.use('agg') | |
| import matplotlib.pyplot as plt | |
|  | |
| #from wrf.core import Constants | |
| #from wrf.var.temp import calc_temp | |
| #from wrf.plot.matplotlib.defaults import (get_basemap, get_default_map_opts, | |
| #                                          get_null_opts) | |
|                              | |
| #from wrf.plot.matplotlib.helper import (add_plot_info_text, plot_map,  | |
| #                                        plot_contourf) | |
|  | |
| #__all__ = ["plot_2d"] | |
|  | |
|  | |
|  | |
|  | |
| def get_basemap(wrfnc): | |
|     #TODO:  handle multiple projections | |
|     lat2d = wrfnc.variables["XLAT"][0,:,:] | |
|     lon2d = wrfnc.variables["XLONG"][0,:,:] | |
|      | |
|     ny = len(wrfnc.dimensions["south_north"]) | |
|     nx = len(wrfnc.dimensions["west_east"]) | |
|     nz = len(wrfnc.dimensions["bottom_top"]) | |
|      | |
|     dx = wrfnc.DX | |
|     dy = wrfnc.DY | |
|     center_lat = wrfnc.CEN_LAT | |
|     center_lon = wrfnc.CEN_LON | |
|     true_lat1 = wrfnc.TRUELAT1 | |
|     true_lat2 = wrfnc.TRUELAT2 | |
|      | |
|     basemap = Basemap(projection="lcc",  | |
|                       lat_0=center_lat, | |
|                       lon_0=center_lon, | |
|                       lat_1=true_lat1, | |
|                       lat_2=true_lat2, | |
|                       llcrnrlon=lon2d[0,0],  | |
|                       llcrnrlat=lat2d[0,0],  | |
|                       urcrnrlon=lon2d[ny-1, nx-1],  | |
|                       urcrnrlat=lat2d[ny-1, nx-1], | |
|                       resolution='i') | |
|      | |
|     return basemap | |
|  | |
| def get_default_map_opts(): | |
|     landcolor = (204/255.0, 204/255.0, 153/255.0) | |
|     oceancolor = (102/255.0, 204/255.0, 255/255.0) | |
|     return MapOptions( | |
|                  coastargs = {"linewidth":1.0, "linestyle":'solid', "color":'k'}, | |
|                  countryargs = {"linewidth":0.5, "linestyle":'solid', "color":'k'}, | |
|                  stateargs = {"linewidth":0.5, "linestyle":'solid', "color":'k'}, | |
|                  mapboundaryargs = {"color":'k', "linewidth":1.0,  | |
|                                     "fill_color":oceancolor}, | |
|                  continentfillargs = {"color":landcolor, "lake_color":oceancolor, | |
|                                       "zorder":0}) | |
|  | |
|  | |
| def get_null_opts(): | |
|      return FilledContourOptions(fcontourargs={},  | |
|                                  colorbarargs={"location" : "bottom",  | |
|                                                "size" : "5%", "pad" : "2%", | |
|                                                "extend" : "both"}) | |
|  | |
| def add_plot_info_text(ax, | |
|                        top_left_text="", top_right_text="", | |
|                        bot_left_text="", bot_right_text=""): | |
|      | |
|     plt.ioff() | |
|     if top_left_text != "": | |
|         plt.text(0.005,.995,top_left_text,  | |
|                  bbox=dict(facecolor="white"), | |
|                  horizontalalignment="left", | |
|                  verticalalignment="top", | |
|                  transform = ax.transAxes, | |
|                  fontsize=10) | |
|          | |
|     if top_right_text != "":   | |
|         plt.text(.995,.995,top_right_text,  | |
|                  bbox=dict(facecolor="white"), | |
|                  horizontalalignment="right", | |
|                  verticalalignment="top", | |
|                  transform = ax.transAxes, | |
|                  fontsize=10) | |
|      | |
|     if bot_left_text != "":   | |
|         plt.text(0.005,0.005,bot_left_text,  | |
|                  bbox=dict(facecolor="white"), | |
|                  horizontalalignment="left", | |
|                  verticalalignment="bottom", | |
|                  transform = ax.transAxes, | |
|                  fontsize=10) | |
|          | |
|     if bot_right_text != "":   | |
|         plt.text(.995,0.005,bot_right_text,  | |
|                  bbox=dict(facecolor="white"), | |
|                  horizontalalignment="right", | |
|                  verticalalignment="bottom", | |
|                  transform = ax.transAxes, | |
|                  fontsize=10) | |
|  | |
| def plot_map(basemap, mapoptions): | |
|     plt.ioff() | |
|     if mapoptions.mapboundaryargs is not None: | |
|             basemap.drawmapboundary(**mapoptions.mapboundaryargs) | |
|              | |
|     if mapoptions.continentfillargs is not None: | |
|         basemap.fillcontinents(**mapoptions.continentfillargs) | |
|      | |
|     if mapoptions.coastargs is not None: | |
|         basemap.drawcoastlines(**mapoptions.coastargs) | |
|          | |
|     if mapoptions.countryargs is not None: | |
|         basemap.drawcountries(**mapoptions.countryargs) | |
|          | |
|     if mapoptions.stateargs is not None: | |
|         basemap.drawstates(**mapoptions.stateargs) | |
|          | |
|     if mapoptions.countyargs is not None: | |
|         basemap.drawcounties(**mapoptions.countyargs) | |
|          | |
|     if mapoptions.riverargs is not None: | |
|         basemap.drawrivers(**mapoptions.riverargs) | |
|  | |
| def plot_contourf(x,y,data,basemap, contourfoptions): | |
|     plt.ioff() | |
|     cs1 = None | |
|     if contourfoptions.contourargs is not None: | |
|         cs1 = basemap.contour(x,y,data,**contourfoptions.contourargs) | |
|      | |
|     cs2 = None | |
|     if contourfoptions.fcontourargs is not None: | |
|         cs2 = basemap.contourf(x,y,data,**contourfoptions.fcontourargs) | |
|      | |
|     cb = None | |
|     if contourfoptions.colorbarargs is not None: | |
|         cb = basemap.colorbar(cs2, **contourfoptions.colorbarargs) | |
|          | |
|     if contourfoptions.labelargs is not None: | |
|         plt.clabel(cs1, **contourfoptions.labelargs) | |
|          | |
|     return cs1, cs2, cb | |
|      | |
| def get_null_opts(): | |
|      return FilledContourOptions(fcontourargs={},  | |
|                                  colorbarargs={"location" : "bottom",  | |
|                                                "size" : "5%", "pad" : "2%", | |
|                                                "extend" : "both"}) | |
|  | |
| class MapOptions(object): | |
|     def __init__(self,  | |
|                  coastargs = None, | |
|                  countyargs = None, | |
|                  countryargs = None, | |
|                  riverargs = None, | |
|                  stateargs = None, | |
|                  mapboundaryargs = None, | |
|                  continentfillargs = None): | |
|         self.coastargs = coastargs | |
|         self.countyargs = countyargs | |
|         self.countryargs = countryargs | |
|         self.riverargs = riverargs | |
|         self.stateargs = stateargs | |
|         self.mapboundaryargs = mapboundaryargs | |
|         self.continentfillargs = continentfillargs | |
|          | |
| def plot_2d(wrfnc, varname=None, outfile=None, title=None,  | |
|              map_opts=None, plot_opts=None, | |
|              top_left_info="", top_right_info="",  | |
|              bot_left_info="", bot_right_info="", | |
|              wks_type="png", var=None, | |
|              time_in=0): | |
|      | |
|     try: | |
|         plt.ioff() | |
|         print "generating %s.%s" % (outfile, wks_type) | |
|         if var is not None: | |
|             field = var | |
|         elif varname is not None: | |
|             field = wrfnc.variables[varname][time_in,:,:] | |
|          | |
|         lat2d = wrfnc.variables["XLAT"][time_in,:,:] | |
|         lon2d = wrfnc.variables["XLONG"][time_in,:,:] | |
|         times = wrfnc.variables["Times"][time_in,:] | |
|         model_time = "".join(times) | |
|         start_date = dt.strptime(model_time, "%Y-%m-%d_%H:%M:%S") | |
|          | |
|         ny = len(wrfnc.dimensions["south_north"]) | |
|         nx = len(wrfnc.dimensions["west_east"]) | |
|         nz = len(wrfnc.dimensions["bottom_top"]) | |
|          | |
|         fig = plt.figure(figsize=(8,8), dpi=200) | |
|         ax = fig.add_axes([0.1,0.1,0.8,0.8]) | |
|          | |
|         bm = get_basemap(wrfnc) | |
|         if map_opts is None: | |
|             map_opts = get_default_map_opts() | |
|         if plot_opts is None: | |
|             plot_opts = get_null_opts() | |
|          | |
|         x,y = bm(lon2d, lat2d) | |
|          | |
|         plot_map(bm,map_opts) | |
|          | |
|         plt.xticks(rotation=70) | |
|         tplot = plot_contourf(x,y,field,bm,plot_opts) | |
|          | |
|          | |
|         add_plot_info_text(ax,  | |
|                            top_left_info, top_right_info, | |
|                            bot_left_info, bot_right_info) | |
|          | |
|         ax.set_title(title,fontdict={"fontsize" : 20}) | |
|          | |
|         plt.savefig("%s.%s" % (outfile, wks_type)) | |
|          | |
|         plt.clf() | |
|         plt.close(fig) | |
|     except: | |
|         # print the stack trace since it will be lost when used in a  | |
|         # multiprocessing worker. | |
|         print traceback.format_exc() | |
|         raise | |
|     finally: | |
|         sys.stdout.flush() | |
|          | |
| def main(): | |
|     parser = argparse.ArgumentParser(description="Generate meteorological " | |
|                                      "plots for a specific data file") | |
|     parser.add_argument("-v", "--var", required=True,  | |
|                         help="variable name") | |
|     parser.add_argument("-f", "--filename", required=True,  | |
|                         help="WRF file to plot") | |
|     parser.add_argument("-o", "--outdir", default=".", required=False, | |
|                         help="output directory for images") | |
|     parser.add_argument("-l", "--levels", required=False, type=float, | |
|                         nargs="+", | |
|                         default=None, | |
|                         help=("the start, end, and increment for contour levels" | |
|                               " as a list of items with spaces between them" | |
|                               "example: 1 10 2 ")) | |
|     parser.add_argument("-c", "--customlevels", required=False, type=float, | |
|                         nargs="+", | |
|                         default=None, | |
|                         help=("a list of space delimited contour levels" | |
|                               "example: 1 2 3 4 5 19 28 200 ")) | |
|      | |
|     args = parser.parse_args() | |
|      | |
|     if not os.path.exists(args.filename): | |
|         raise RuntimeError ("%s not found" % args.filename) | |
|      | |
|     if not os.path.exists(args.outdir): | |
|         os.makedirs(args.outdir) | |
|      | |
|     basename = os.path.basename(args.filename) | |
|     wrfnc = NetCDF(args.filename, mode='r') | |
|      | |
|     outfile = os.path.join(args.outdir, domain, args.var, "%s.%s" % (basename,args.var)) | |
|     if not os.path.exists(os.path.dirname(outfile)): | |
|         os.makedirs(os.path.dirname(outfile)) | |
|      | |
|     if args.levels is not None or args.customlevels is not None: | |
|         plot_opts = get_null_opts() | |
|         if args.levels is not None: | |
|             if len(args.levels) < 2 or len(args.levels) > 3: | |
|                 raise RuntimeError("levels argument is invalid") | |
|             plot_opts.fcontourargs["levels"] = [x for x in n.arange(args.levels[0],  | |
|                                                                   args.levels[1],  | |
|                                                                   args.levels[2])] | |
|             plot_opts.fcontourargs["extend"] = "both" | |
|         elif args.customlevels is not None: | |
|             plot_opts.fcontourargs["levels"] = args.customlevels | |
|             plot_opts.fcontourargs["extend"] = "both" | |
|     else: | |
|         plot_opts = None | |
|      | |
|     plot_2d(wrfnc, args.var, outfile, "%s"%args.var, | |
|             plot_opts = plot_opts) | |
|      | |
| if __name__ == "__main__": | |
|     main() |