def main(): download_dataset() parser = argparse.ArgumentParser() parser.add_argument('-m', '--map', help='Which type of map to be generated.') args = parser.parse_args() if args.map == 'verywide': map_ = map_utils.VeryWide() elif args.map == 'regional': map_ = map_utils.Regional() elif args.map == 'local': map_ = map_utils.Local() else: print("Invalid Map Type Requested.") return # Open dataset file = '../output/DHLPCoR_data.grb2' data = pygrib.open(file) # Grab the keys from the data we want maximum_temperatures = data.select(name='Maximum temperature') minimum_temperatures = data.select(name='Minimum temperature') percent_chance_rain = data.select( name='Probability of 0.01 inch of precipitation (POP)') # loops Day by day (1-5) day = 1 for max_temperatures, min_temperatures, percent_chance_rains in zip( maximum_temperatures, minimum_temperatures, percent_chance_rain): # Max Temperature data max_temperature_data = [] max_temp_latitudes, max_temp_longitudes = max_temperatures.latlons() max_temp_values = max_temperatures.values for latitudes, longitudes, values in zip(max_temp_latitudes, max_temp_longitudes, max_temp_values): for lat, lon, value in zip(latitudes, longitudes, values): max_temperature_data.append({ 'lat': lat, 'lon': lon, 'value': value }) # Min Temperature data min_temperature_data = [] min_temp_lats, min_temp_lons = min_temperatures.latlons() min_temp_values = min_temperatures.values for latitudes, longitudes, values in zip(min_temp_lats, min_temp_lons, min_temp_values): for lat, lon, value in zip(latitudes, longitudes, values): min_temperature_data.append({ 'lat': lat, 'lon': lon, 'value': value }) # Percent chance of rain data percent_chance_rain_data = [] per_chance_rain_lats, per_chance_rain_lons = percent_chance_rains.latlons( ) per_chance_rain_values = percent_chance_rains.values for latitudes, longitudes, values in zip(per_chance_rain_lats, per_chance_rain_lons, per_chance_rain_values): for lat, lon, value in zip(latitudes, longitudes, values): percent_chance_rain_data.append({ 'lat': lat, 'lon': lon, 'value': value }) # Create the figure for graphing fig = plt.figure(figsize=(15, 9)) ax = fig.add_subplot(1, 1, 1, projection=ccrs.Mercator()) ax.set_extent(map_.NorthSouthEastWest[::-1], crs=ccrs.Geodetic()) # Add boundaries to plot ax.add_feature(cfeature.OCEAN, facecolor=cfeature.COLORS['water']) if map_.map_type == 'verywide': ax.add_feature(cfeature.STATES.with_scale('50m'), linewidth=0.5, facecolor=cfeature.COLORS['land']) elif map_.map_type == 'regional' or map_.map_type == 'local': ax.add_feature(cfeature.STATES.with_scale('50m'), linewidth=0.5, facecolor=cfeature.COLORS['land']) reader = shpreader.Reader('../county_data/countyl010g.shp') counties = list(reader.geometries()) COUNTIES = cfeature.ShapelyFeature(counties, ccrs.PlateCarree()) ax.add_feature(COUNTIES, facecolor='none', edgecolor='black', linewidth=0.3) elif map_.map_type == 'tropical': countries = cfeature.NaturalEarthFeature(category='cultural', name='admin_0_countries', scale='50m', facecolor='none') ax.add_feature(cfeature.LAND) ax.add_feature(countries, edgecolor='black', linewidth=0.5) # Set the additional info on the map ax.set_title('Daily High / Low / Percent Chance of Rain taken ' + str(max_temperatures.validDate)[:-9] + ' UTC', fontsize=12, loc='left') text = AnchoredText(r'$\mathcircled{{c}}$ NickelBlock Forecasting', loc=4, prop={'size': 9}, frameon=True) ax.add_artist(text) # Data Model data_model = AnchoredText('NWS/NDFD CONUS model', loc=3, prop={'size': 9}, frameon=True) ax.add_artist(data_model) # Add logo logo = Utils.get_logo() if map_.map_type == 'verywide': ax.figure.figimage(logo, 1140, 137, zorder=1) elif map_.map_type == 'regional': ax.figure.figimage(logo, 1000, 137, zorder=1) elif map_.map_type == 'local': ax.figure.figimage(logo, 973, 137, zorder=1) else: ax.figure.figimage(logo, 1140, 181, zorder=1) # Plot the cities' information if map_.map_type is not 'tropical': for city in map_.cities: for max_temp, min_temp, per_chance_rain in zip( max_temperature_data, min_temperature_data, percent_chance_rain_data): if round(city.lat, 1) == round(max_temp['lat'], 1) and round( city.lon, 1) == round(max_temp['lon'], 1): ax.plot(city.lon, city.lat, 'ro', zorder=9, markersize=1.90, transform=ccrs.Geodetic()) # City Name if city.city_name == 'Pensacola' and map_.map_type == 'verywide': ax.text(city.lon - 0.13, city.lat + 0.045, city.city_name, fontsize='small', fontweight='bold', transform=ccrs.PlateCarree()) elif map_.map_type == 'local': ax.text(city.lon - 0.2, city.lat + 0.04, city.city_name, fontsize='small', fontweight='bold', transform=ccrs.PlateCarree()) else: ax.text(city.lon - 0.45, city.lat + 0.07, city.city_name, fontsize='small', fontweight='bold', transform=ccrs.PlateCarree()) # City Min/Max Temperature text = str(int(round( min_temp['value'] * 1.8 - 459.67))) + ' / ' + str( int(round(max_temp['value'] * 1.8 - 459.67))) if map_.map_type == 'local': ax.text(city.lon - 0.17, city.lat - 0.1, text, fontsize='small', fontweight='bold', transform=ccrs.PlateCarree()) else: ax.text(city.lon - 0.34, city.lat - 0.175, text, fontsize='small', fontweight='bold', transform=ccrs.PlateCarree()) # City Percent Chance of Rain text = str(int(round(per_chance_rain['value']))) + '%' if map_.map_type == 'local': ax.text(city.lon - 0.07, city.lat - 0.18, text, fontsize='small', fontweight='bold', transform=ccrs.PlateCarree()) else: ax.text(city.lon - 0.2, city.lat - 0.36, text, fontsize='small', fontweight='bold', transform=ccrs.PlateCarree()) break plt.savefig('Day_{}_{}_DailyHighLowPerChanceRain.png'.format( day, map_.map_type)) day += 1
import os import argparse import cartopy.crs as ccrs import cartopy.feature as cfeature import cartopy.io.shapereader as shpreader import matplotlib.pyplot as plt from matplotlib.offsetbox import AnchoredText import pygrib import Map_Utils as map_utils Utils = map_utils.Utils() def main(): download_dataset() parser = argparse.ArgumentParser() parser.add_argument('-m', '--map', help='Which type of map to be generated.') args = parser.parse_args() if args.map == 'verywide': map_ = map_utils.VeryWide() elif args.map == 'regional': map_ = map_utils.Regional() elif args.map == 'local': map_ = map_utils.Local() else: print("Invalid Map Type Requested.")
def main(): download_dataset() parser = argparse.ArgumentParser() parser.add_argument('-m', '--map', help='Which type of map to be generated.') args = parser.parse_args() if args.map == 'verywide': map_ = map_utils.VeryWide() elif args.map == 'regional': map_ = map_utils.Regional() elif args.map == 'local': map_ = map_utils.Local() elif args.map == 'tropical': map_ = map_utils.Tropical() elif args.map == 'country': map_ = map_utils.Country() # Open dataset and capture relevant info file = '../output/CPC_data.grb2' dataset = pygrib.open(file) # Grab the temperature and precipitation data from the dataset precipitation_data = [] temperature_data = dataset.select(name='Temperature') for d in dataset: if str(d) not in str(temperature_data): precipitation_data.append(d) temperature_precipitation_data = { 'Temperatures': temperature_data, 'Precipitations': precipitation_data, }.items() for key, values in temperature_precipitation_data: fig = plt.figure(figsize=(15, 9)) ax = fig.add_subplot(1, 1, 1, projection=ccrs.Mercator()) ax.set_extent(map_.NorthSouthEastWest[::-1], crs=ccrs.Geodetic()) for value in values: lats, lons = value.latlons() vals = value.values # Add boundaries to plot ax.add_feature(cfeature.OCEAN, facecolor=cfeature.COLORS['water']) if map_.map_type == 'verywide': ax.add_feature(cfeature.STATES.with_scale('50m'), linewidth=0.5) elif map_.map_type == 'regional' or map_.map_type == 'local': ax.add_feature(cfeature.STATES.with_scale('50m'), linewidth=0.5) reader = shpreader.Reader('../county_data/countyl010g.shp') counties = list(reader.geometries()) COUNTIES = cfeature.ShapelyFeature(counties, ccrs.PlateCarree()) ax.add_feature(COUNTIES, facecolor='none', edgecolor='black', linewidth=0.3) elif map_.map_type == 'tropical' or map_.map_type == 'country': countries = cfeature.NaturalEarthFeature( category='cultural', name='admin_0_countries', scale='50m', facecolor='none') ax.add_feature(cfeature.LAND) ax.add_feature(countries, edgecolor='black', linewidth=0.5) ax.add_feature(cfeature.STATES.with_scale('50m'), linewidth=0.5) # Contour temperature value at each lat/lon depending on the key if 'event below' in str(value): if key == 'Temperatures': # Contour temperature at each lat/long cf = ax.contourf(lons, lats, vals, levels=[33, 40, 50, 60, 70, 80, 90], transform=ccrs.PlateCarree(), cmap='Blues') cb1 = plt.colorbar(cf, ax=ax, orientation='horizontal', fraction=0.045, pad=0.04) elif key == 'Precipitations': # Contour temperature at each lat/long cf = ax.contourf(lons, lats, vals, levels=[33, 40, 50, 60, 70, 80, 90], transform=ccrs.PlateCarree(), cmap='Blues') cb1 = plt.colorbar(cf, ax=ax, orientation='horizontal', fraction=0.035, pad=0.08) cb1.ax.set_xlabel('Probability of Below (%)') elif 'event above' in str(value): if key == 'Temperatures': # Contour temperature at each lat/long cf = ax.contourf(lons, lats, vals, levels=[33, 40, 50, 60, 70, 80, 90], transform=ccrs.PlateCarree(), cmap='Reds') cb2 = plt.colorbar(cf, ax=ax, orientation='horizontal', fraction=0.0395, pad=0.08) elif key == 'Precipitations': # Contour temperature at each lat/long cf = ax.contourf(lons, lats, vals, levels=[33, 40, 50, 60, 70, 80, 90], transform=ccrs.PlateCarree(), cmap='Greens') cb2 = plt.colorbar(cf, ax=ax, orientation='horizontal', fraction=0.0395, pad=0.04) cb2.ax.set_xlabel('Probability of Above (%)') # Plot all the cities if map_.map_type is not 'tropical' and map_.map_type is not 'country': for city in map_.cities: ax.plot(city.lon, city.lat, 'ro', zorder=9, markersize=1.90, transform=ccrs.Geodetic()) if map_.map_type == 'local': ax.text(city.lon - 0.3, city.lat + 0.04, city.city_name, fontsize='small', fontweight='bold', transform=ccrs.PlateCarree()) else: ax.text(city.lon - 0.5, city.lat + 0.09, city.city_name, fontsize='small', fontweight='bold', transform=ccrs.PlateCarree()) # Title ax.set_title('{} Probability for {} UTC'.format( key, str(value.validDate)), fontsize=12, loc='left') # Company copyright bottom right corner text = AnchoredText(r'$\mathcircled{{c}}$ NickelBlock Forecasting', loc=4, prop={'size': 9}, frameon=True) ax.add_artist(text) # Data model data_model = AnchoredText('CPC Probability Outlook model', loc=3, prop={'size': 9}, frameon=True) ax.add_artist(data_model) # Add logo logo = Utils.get_logo() if map_.map_type == 'verywide': if key == 'Temperatures': ax.figure.figimage(logo, 1040, 272, zorder=1) elif key == 'Precipitations': ax.figure.figimage(logo, 1045, 265, zorder=1) elif map_.map_type == 'regional': if key == 'Temperatures': ax.figure.figimage(logo, 925, 273, zorder=1) elif key == 'Precipitations': ax.figure.figimage(logo, 930, 267, zorder=1) elif map_.map_type == 'local': if key == 'Temperatures': ax.figure.figimage(logo, 904, 270, zorder=1) elif key == 'Precipitations': ax.figure.figimage(logo, 909, 265, zorder=1) elif map_.map_type == 'tropical': if key == 'Temperatures': ax.figure.figimage(logo, 1110, 272, zorder=1) elif key == 'Precipitations': ax.figure.figimage(logo, 1115, 267, zorder=1) elif map_.map_type == 'country': if key == 'Temperatures': ax.figure.figimage(logo, 1070, 271, zorder=1) elif key == 'Precipitations': ax.figure.figimage(logo, 1075, 266, zorder=1) plt.savefig('CPC_{}_{}_Map.png'.format(key, value.validDate))
def main(): # Parse the arguments from the command line parser = argparse.ArgumentParser() parser.add_argument('-m', '--map', help='Which type of map to be generated.') parser.add_argument('-t', '--time', nargs='+', help='Access and plot weather data X hours from now.', type=int, default=0) args = parser.parse_args() if args.map == 'verywide': map_ = map_utils.VeryWide() elif args.map == 'regional': map_ = map_utils.Regional() elif args.map == 'local': map_ = map_utils.Local() elif args.map == 'tropical': map_ = map_utils.Tropical() else: print("Invalid Map Type Requested.") return # Create maps for each time declared on command line for t in args.time: # Acquire the datasets from the GFS Global Catalog GFS_data = TDSCatalog( 'http://thredds.ucar.edu/thredds/catalog/grib/NCEP/GFS/' 'Global_0p25deg/catalog.xml?dataset=grib/NCEP/GFS/Global_0p25deg/Best' ) # Pull out our dataset and get the NCSS access point used to query data from the dataset dataset = GFS_data.datasets[0] ncss = dataset.subset() # Use the `ncss` object to create a new query object query = ncss.query() time = (datetime.utcnow() + timedelta(hours=t) ) # Time of data requested query.time(time) query.accept('netcdf4') query.variables('Temperature_surface') # Set the lat lon box for which specific area of the dataset to query if map_.map_type is not 'tropical': query.lonlat_box(north=map_.NorthSouthEastWest[0], south=map_.NorthSouthEastWest[1], east=map_.NorthSouthEastWest[2], west=map_.NorthSouthEastWest[3]) else: query.lonlat_box(north=map_.NorthSouthEastWest[0] + 10, south=map_.NorthSouthEastWest[1], east=map_.NorthSouthEastWest[2], west=map_.NorthSouthEastWest[3]) data = ncss.get_data(query) # Grab the keys from the data we want temperatures = data.variables['Temperature_surface'] latitudes = data.variables['lat'] longitudes = data.variables['lon'] # Remove 1d arrays from data for plotting temperatures = temperatures[:].squeeze() latitudes = latitudes[:].squeeze() longitudes = longitudes[:].squeeze() # Convert temps to Fahrenheit from Kelvin temperatures = convert_temperature_to_fahrenheit(temperatures) # Combine 1D latitude and longitudes into a 2D grid of locations lon_2d, lat_2d = np.meshgrid(longitudes, latitudes) # Create figure for plotting fig = plt.figure(figsize=(15, 9)) ax = fig.add_subplot(1, 1, 1, projection=ccrs.Mercator()) ax.set_extent(map_.NorthSouthEastWest[::-1], crs=ccrs.Geodetic()) # Add map features depending on map type ax.add_feature(cfeature.STATES.with_scale('50m'), linewidth=0.5) if map_.map_type == 'regional' or map_.map_type == 'local': reader = shpreader.Reader('../county_data/countyl010g.shp') counties = list(reader.geometries()) COUNTIES = cfeature.ShapelyFeature(counties, ccrs.PlateCarree()) ax.add_feature(COUNTIES, facecolor='none', edgecolor='black', linewidth=0.3) elif map_.map_type == 'tropical': countries = cfeature.NaturalEarthFeature(category='cultural', name='admin_0_countries', scale='50m', facecolor='none') ax.add_feature(cfeature.LAND) ax.add_feature(countries, edgecolor='black', linewidth=0.5) # Contour temperature value at each lat/lon cf = ax.contourf(lon_2d, lat_2d, temperatures, 40, extend='both', transform=ccrs.PlateCarree(), cmap='coolwarm') # Plot a colorbar to show temperature values colorbar = plt.colorbar(cf, ax=ax, fraction=0.032) colorbar.set_label('Temperature (\u00b0F)') # Plot all the cities if map_.map_type is not 'tropical': for city in map_.cities: for lat in range(len(latitudes)): for lon in range(len(longitudes)): if round_temps( city.lat) == latitudes[lat] and round_temps( city.lon) == (longitudes[lon] - 360): cityTemp_latlon = Utils.plot_latlon_cityTemp_by_maptype( lat=city.lat, lon=city.lon, map_type=map_.map_type) ax.text(cityTemp_latlon[1], cityTemp_latlon[0], int(round(temperatures[lat][lon])), fontsize='10', fontweight='bold', transform=ccrs.PlateCarree()) ax.plot(city.lon, city.lat, 'ro', zorder=9, markersize=2.00, transform=ccrs.Geodetic()) cityName_latlon = Utils.plot_latlon_cityName_by_maptype( lat=city.lat, lon=city.lon, map_type=map_.map_type) ax.text(cityName_latlon[1], cityName_latlon[0], city.city_name, fontsize='small', fontweight='bold', transform=ccrs.PlateCarree()) # Create a title with the time value ax.set_title('Temperature forecast (\u00b0F) for {} UTC'.format( str(time)[:-7]), fontsize=12, loc='left') # Company copyright text = AnchoredText(r'$\mathcircled{{c}}$ NickelBlock Forecasting', loc=4, prop={'size': 9}, frameon=True) ax.add_artist(text) # Data model data_model = AnchoredText('GFS 12z model', loc=3, prop={'size': 9}, frameon=True) ax.add_artist(data_model) # Add logo logo = Utils.get_logo() if map_.map_type is not 'tropical': ax.figure.figimage(logo, 1105, 137, zorder=1) else: ax.figure.figimage(logo, 1105, 181, zorder=1) plt.savefig('{}_Temperature_Hour_{}.png'.format(map_.map_type, t))
def main(): download_dataset() parser = argparse.ArgumentParser() parser.add_argument('-m', '--map', help='Which type of map to be generated.') args = parser.parse_args() if args.map == 'verywide': map_ = map_utils.VeryWide() elif args.map == 'regional': map_ = map_utils.Regional() elif args.map == 'local': map_ = map_utils.Local() elif args.map == 'tropical': map_ = map_utils.Tropical() elif args.map == 'country': map_ = map_utils.Country() else: print("Invalid Map Type Requested.") return # Open dataset and capture relevant info file = '../output/SPC_data.grb2' dataset = pygrib.open(file) data = pygrib.open(file) valid_days_data = get_valid_days(dataset, data) for data in valid_days_data: print(data.validDate) lats, lons = data.latlons() values = data.values # Create the figure for graphing fig = plt.figure(figsize=(15, 9)) ax = fig.add_subplot(1, 1, 1, projection=ccrs.Mercator()) ax.set_extent(map_.NorthSouthEastWest[::-1], crs=ccrs.Geodetic()) # Add boundaries to plot ax.add_feature(cfeature.OCEAN, facecolor=cfeature.COLORS['water']) if map_.map_type == 'verywide': ax.add_feature(cfeature.STATES.with_scale('50m'), linewidth=0.5) elif map_.map_type == 'regional' or map_.map_type == 'local': ax.add_feature(cfeature.STATES.with_scale('50m'), linewidth=0.5) reader = shpreader.Reader('../county_data/countyl010g.shp') counties = list(reader.geometries()) COUNTIES = cfeature.ShapelyFeature(counties, ccrs.PlateCarree()) ax.add_feature(COUNTIES, facecolor='none', edgecolor='black', linewidth=0.3) elif map_.map_type == 'tropical' or map_.map_type == 'country': countries = cfeature.NaturalEarthFeature(category='cultural', name='admin_0_countries', scale='50m', facecolor='none') ax.add_feature(cfeature.LAND) ax.add_feature(countries, edgecolor='black', linewidth=0.5) ax.add_feature(cfeature.STATES.with_scale('50m'), linewidth=0.5) # Contour temperature at each lat/long cf = ax.contourf(lons, lats, values, levels=[0, 1, 2, 3, 4, 5], transform=ccrs.PlateCarree(), cmap='Greens') # Plot all the cities if map_.map_type is not 'tropical' and map_.map_type is not 'country': for city in map_.cities: ax.plot(city.lon, city.lat, 'ro', zorder=9, markersize=1.90, transform=ccrs.Geodetic()) ax.text(city.lon - 0.5, city.lat + 0.09, city.city_name, fontsize='small', fontweight='bold', transform=ccrs.PlateCarree()) # Make a title with the time value ax.set_title('SPC Categorical Outlook for {} UTC'.format( str(data.validDate)), fontsize=12, loc='left') # Company copyright on the bottom right corner text = AnchoredText(r'$\mathcircled{{c}}$ NickelBlock Forecasting', loc=4, prop={'size': 9}, frameon=True) ax.add_artist(text) # Data Model data_model = AnchoredText( 'SPC Probabilistic to Categorical Outlook model', loc=3, prop={'size': 9}, frameon=True) ax.add_artist(data_model) # Add logo logo = Utils.get_logo() if map_.map_type == 'verywide': ax.figure.figimage(logo, 1090, 205, zorder=1) elif map_.map_type == 'regional': ax.figure.figimage(logo, 960, 205, zorder=1) elif map_.map_type == 'local': ax.figure.figimage(logo, 937, 205, zorder=1) elif map_.map_type == 'tropical': ax.figure.figimage(logo, 1170, 205, zorder=1) elif map_.map_type == 'country': ax.figure.figimage(logo, 1124, 205, zorder=1) # Plot a colorbar to show temperature and reduce the size of it cb = plt.colorbar(cf, ax=ax, fraction=0.056, orientation='horizontal', pad=0.04) cb.ax.set_xlabel('( 1:MRGL, 2:SLGT, 3:ENH, 4:MDT, 5:HIGH )') plt.savefig('SPC_{}_{}_Map.png'.format(map_.map_type, str(data.validDate)))
def main(): # Parse the arguments from the command line parser = argparse.ArgumentParser() parser.add_argument('-m', '--map', help='Which type of map to be generated.') parser.add_argument('-t', '--time', nargs='+', help='Access and plot weather data X hours from now.', type=int, default=0) args = parser.parse_args() if args.map == 'verywide': map_ = map_utils.VeryWide() elif args.map == 'regional': map_ = map_utils.Regional() elif args.map == 'local': map_ = map_utils.Local() elif args.map == 'tropical': map_ = map_utils.Tropical() else: print("Invalid Map Type Requested.") return for t in args.time: # Acquire the datasets from the GFS Global Catalog GFS_data = TDSCatalog( 'http://thredds.ucar.edu/thredds/catalog/grib/NCEP/GFS/' 'Global_0p25deg/catalog.xml?dataset=grib/NCEP/GFS/Global_0p25deg/Best' ) # Pull out our dataset and get the NCSS access point used to query data from the dataset dataset = GFS_data.datasets[0] ncss = dataset.subset() # Use the `ncss` object to create a new query object query = ncss.query() time = (datetime.utcnow() + timedelta(hours=t) ) # Time of data requested query.time(time) query.accept('netcdf4') query.variables('Precipitation_rate_surface') # Set the lat lon box for which specific area of the dataset to query if map_.map_type is not 'tropical': query.lonlat_box(north=map_.NorthSouthEastWest[0], south=map_.NorthSouthEastWest[1], east=map_.NorthSouthEastWest[2], west=map_.NorthSouthEastWest[3]) else: query.lonlat_box(north=map_.NorthSouthEastWest[0] + 10, south=map_.NorthSouthEastWest[1], east=map_.NorthSouthEastWest[2], west=map_.NorthSouthEastWest[3]) data = ncss.get_data(query) # Grab the keys from the data we want precipitations = data.variables['Precipitation_rate_surface'] latitudes = data.variables['lat'] longitudes = data.variables['lon'] # Remove 1d arrays from data for plotting precipitations = precipitations[:].squeeze() latitudes = latitudes[:].squeeze() longitudes = longitudes[:].squeeze() # Convert all precipitation values from kg/m^2/s (kilograms per meter squared per second) to inches for i in range(len(latitudes)): for k in range(len(longitudes)): precipitations[i][k] = kg_per_msquared_to_inches( precipitations[i][k]) # Combine 1D latitude and longitudes into a 2D grid of locations lon_2d, lat_2d = np.meshgrid(longitudes, latitudes) # Create figure for plotting fig = plt.figure(figsize=(15, 9)) ax = fig.add_subplot(1, 1, 1, projection=ccrs.Mercator()) ax.set_extent(map_.NorthSouthEastWest[::-1], crs=ccrs.Geodetic()) # Add map features depending on map type ax.add_feature(cfeature.STATES.with_scale('50m'), linewidth=0.5) if map_.map_type == 'regional' or map_.map_type == 'local': reader = shpreader.Reader('../county_data/countyl010g.shp') counties = list(reader.geometries()) COUNTIES = cfeature.ShapelyFeature(counties, ccrs.PlateCarree()) ax.add_feature(COUNTIES, facecolor='none', edgecolor='black', linewidth=0.3) elif map_.map_type == 'tropical': countries = cfeature.NaturalEarthFeature(category='cultural', name='admin_0_countries', scale='50m', facecolor='none') ax.add_feature(cfeature.LAND) ax.add_feature(countries, edgecolor='black', linewidth=0.5) # Create the custom color map for rain colormap = ListedColormap([ 'white', # Greens '#7dcf65', '#6fba59', '#63a351', '#5c914d', '#508641', '#48793b', '#396a2d', '#315d27', '#245817', '#1c4711', '#1c4711', '#1c4711', '#1c4711', '#1c4711', '#1c4711', # Oranges '#ffea5d', '#ffea5d', '#dddf32', '#dfcc4b', '#DBC634', 'orange' ]) # Contour temperature at each lat/long cf = ax.contourf(lon_2d, lat_2d, precipitations, levels=[ 0.001, 0.01, 0.025, 0.045, 0.065, 0.085, 0.105, 0.125, 0.150, 0.175, 0.200, 0.250, 0.5, 1.0 ], extend='both', transform=ccrs.PlateCarree(), cmap=colormap) # Plot a colorbar to show temperature and reduce the size of it colorbar = plt.colorbar(cf, ax=ax, cmap=colormap, fraction=0.032, ticks=[ 0.001, 0.01, 0.025, 0.045, 0.065, 0.085, 0.105, 0.125, 0.150, 0.175, 0.200, 0.250, 0.500, 1.00 ]) colorbar.set_label('Precipitation Rate (inches per hour)') # Plot all the cities if map_.map_type is not 'tropical': for city in map_.cities: ax.plot(city.lon, city.lat, 'ro', zorder=9, markersize=1.90, transform=ccrs.Geodetic()) cityName_latlon = Utils.plot_latlon_cityName_by_maptype( lat=city.lat, lon=city.lon, map_type=map_.map_type) ax.text(cityName_latlon[1], cityName_latlon[0], city.city_name, fontsize='small', fontweight='bold', transform=ccrs.PlateCarree()) # Create a title with the time value ax.set_title('Precipitation Rate Forecast (inches) for {} UTC'.format( str(time)[:-7]), fontsize=12, loc='left') # Company copyright text = AnchoredText(r'$\mathcircled{{c}}$ NickelBlock Forecasting', loc=4, prop={'size': 9}, frameon=True) ax.add_artist(text) # Data model data_model = AnchoredText('GFS 12z model', loc=3, prop={'size': 9}, frameon=True) ax.add_artist(data_model) # Add logo logo = Utils.get_logo() if map_.map_type is not 'tropical': ax.figure.figimage(logo, 1105, 137, zorder=1) else: ax.figure.figimage(logo, 1105, 181, zorder=1) plt.savefig('{}_Precipitation_Hour_{}.png'.format(map_.map_type, t))