def plot_background(ax): ax.coastlines(resolution='10m', linewidth=2, color='black', zorder=4) political_boundaries = NaturalEarthFeature( category='cultural', name='admin_0_boundary_lines_land', scale='10m', facecolor='none') states = NaturalEarthFeature(category='cultural', name='admin_1_states_provinces_lines', scale='50m', facecolor='none') ax.add_feature(political_boundaries, linestyle='-', edgecolor='black', zorder=4) ax.add_feature(states, linestyle='-', edgecolor='black', linewidth=2, zorder=4) ax.add_feature( USCOUNTIES.with_scale('500k'), edgecolor='black', linewidth=1, zorder=1 ) #### Using Metpy's county shapefiles due to hi-resolution and they also help with spartial awareness ax.add_feature(roads, facecolor='none', edgecolor='dimgrey', zorder=1, linewidth=1) return ax
def add_geographic_features(self): """ """ self.ax.add_feature(cfeature.STATES.with_scale('50m'), edgecolor='black', linewidth=1.0) self.ax.add_feature(USCOUNTIES.with_scale('5m'), edgecolor='black', linewidth=0.1)
def test_us_county_scales(): """Test US county plotting with all scales.""" proj = ccrs.LambertConformal(central_longitude=-85.0, central_latitude=45.0) fig = plt.figure(figsize=(12, 9)) ax1 = fig.add_subplot(1, 3, 1, projection=proj) ax2 = fig.add_subplot(1, 3, 2, projection=proj) ax3 = fig.add_subplot(1, 3, 3, projection=proj) for scale, axis in zip(['20m', '5m', '500k'], [ax1, ax2, ax3]): axis.set_extent([270.25, 270.9, 38.15, 38.75], ccrs.Geodetic()) axis.add_feature(USCOUNTIES.with_scale(scale), edgecolor='black') return fig
def test_us_county_scales(): """Test US county plotting with all scales.""" proj = ccrs.LambertConformal(central_longitude=-85.0, central_latitude=45.0) fig = plt.figure(figsize=(12, 9)) ax1 = fig.add_subplot(1, 3, 1, projection=proj) ax2 = fig.add_subplot(1, 3, 2, projection=proj) ax3 = fig.add_subplot(1, 3, 3, projection=proj) for scale, axis in zip(['20m', '5m', '500k'], [ax1, ax2, ax3]): axis.set_extent([270.25, 270.9, 38.15, 38.75], ccrs.Geodetic()) axis.add_feature(USCOUNTIES.with_scale(scale)) return fig
def drawcounties(self, linewidths=0.2, linestyle='solid', color='k', res='l', ax=None, **kwargs): """ Draws county borders similarly to Basemap's m.drawcounties() function. Since cartopy currently does not offer a county shapefile, this function uses MetPy's available county shapefiles. Parameters: ---------------------- linewidths Line width (default is 0.2) linestyle Line style to plot (default is solid) color Color of line (default is black) res Resolution of country borders. Can be a character ('l','m','h') or one of MetPy's available resolutions ('20m','5m','500k'). If none is specified, then the default resolution specified when creating an instance of Map is used. ax Axes instance, if not None then overrides the default axes instance. """ #Get current axes if not specified ax = ax or self._check_ax() #Error check resolution res = self.check_res(res, counties=True) #Draw counties using metpy counties = ax.add_feature(USCOUNTIES.with_scale(res), linewidths=linewidths, linestyle=linestyle, edgecolor=color, **kwargs) #Return value return counties
mslp = data['mslp'] / 100. mslpc = mslp.squeeze() mslpc = ndimage.gaussian_filter(mslpc, sigma=1, order=0) sfc_pressure = data['spres'].squeeze() / 100 #This creates a nice-looking datetime label dtfs = str(time.dt.strftime('%Y-%m-%d_%H%MZ').item()) ########## SET UP FIGURE ################################################## fig = plt.figure(figsize=(15, 15)) ax1 = fig.add_subplot(111, projection=zH5_crs) ax1.coastlines(resolution='10m') ax1.add_feature(cfeature.BORDERS.with_scale('10m'), linewidth=1.5) ax1.add_feature(cfeature.STATES.with_scale('10m'), linewidth=2.0) ax1.add_feature(USCOUNTIES.with_scale('500k'), edgecolor='silver') ########## PLOTTING ####################################################### #Plot 2m 32F isotherm tmp_2m32 = ax1.contour(x, y, t2m, colors='b', alpha=0.8, levels=[32]) #Plot labeled MSLP contours h_contour = ax1.contour(x, y, mslpc, colors='dimgray', levels=range(940, 1080, 4), linewidths=1, alpha=0.7) #h_contour.clabel(fontsize=14, colors='dimgray', inline=1, inline_spacing=4, fmt='%i mb', rightside_up=True, use_clabeltext=True)
def common_features( scale="110m", ax=None, crs=pc, *, figsize=None, dpi=None, counties_scale="20m", dark=False, verbose=False, COASTLINES=True, COASTLINES_kwargs={}, BORDERS=False, BORDERS_kwargs={}, STATES=False, STATES_kwargs={}, COUNTIES=False, COUNTIES_kwargs={}, OCEAN=False, OCEAN_kwargs={}, LAND=False, LAND_kwargs={}, RIVERS=False, RIVERS_kwargs={}, LAKES=False, LAKES_kwargs={}, ROADS=False, ROADS_kwargs={}, PLACES=False, PLACES_kwargs={}, STAMEN=False, STAMEN_kwargs={}, OSM=False, OSM_kwargs={}, **kwargs, ): """ Add common features to a cartopy axis. This completes about 95% of my cartopy needs. .. tip:: This is a great way to initialize a new cartopy axes. Parameters ---------- scale : {'10m', '50m' 110m'} The cartopy feature's level of detail. .. note:: The ``'10m'`` scale for OCEAN and LAND takes a *long* time. ax : plot axes The axis to add the feature to. If None, it will create a new cartopy axes with ``crs``. crs : cartopy.crs Coordinate reference system (aka "projection") to create new map if no cartopy axes is given. Default is ccrs.PlateCarree. dark : bool If True, use alternative "dark theme" colors for land and water. .. figure:: _static/BB_maps/common_features-1.png .. figure:: _static/BB_maps/common_features-2.png counties_scale: {'20m', '5m', '500k'} Counties are plotted via MetPy and have different resolutions available than other features. - 20m = 20,000,000 resolution (Ok if you show a large area) - 5m = 5,000,000 resolution (provides good detail) - 500k = 500,000 resolution (high resolution, plots very slow) figsize : tuple Set the figure size dpi : int Set the figure dpi FEATURES : bool Toggle on various features. By default, only COASTLINES is turned on. Each feature has a cooresponding ``FEATURE_kwargs={}`` dictionary to supply additional arguments to cartopy's add_feature method (e.g., change line color or width by feature type). ========== ========================================================= FEATURE Description ========== ========================================================= COASTLINES Coastlines, boundary between land and ocean. BORDERS Borders between countries. *Does not includes coast*. STATES US state borders. Includes coast. COUNTIES US Counties. Includes coast. OCEAN Colored ocean area LAND Colored land area RIVERS Lines where rivers exist LAKES Colored lake area ROADS All major roads. Can break filter by road type. PLACES Points and labels for major cities (filter by rank). ========== ========================================================= ========== ========================================================= MAP TILE Description ========== ========================================================= Stamen Specify type and zoom level. http://maps.stamen.com/ Style: ``terrain-background``, ``terrain``, ``toner-background``, ``toner``, `watercolor`` zoom: int [0-10] alpha: [0-1] alpha_color: an overlay color to put on top of map use 'k' to darken background use 'w' to lighten background OSM Open Street Maps zoom: int ========== ========================================================= .. note:: For ``ROADS_kwargs`` you may provide a key for 'type' to filter out the types of roads you want. The road type may be a single string or a list of road types. For example ``ROADS_kwargs=dict(type='Major Highway')`` or ``ROADS_kwargs=dict(type=['Secondary Highway', 'Major Highway']) Of course, the shapefile has many other road classifiers for each road, like "level" (Federal, State, Interstate), road "name", "length_km", etc. Filters for each of these could be added if I need them later. .. note:: When adding a tile product to a map, it might be better to add it to the map first, then set the map extent, then make a separate call to ``common_features`` to add other features like roads and counties. The reason is because, if you add a tile map to Methods ------- .adjust_extent .center_extent .copy_extent Examples -------- https://github.com/blaylockbk/Carpenter_Workshop/blob/main/notebooks/demo_cartopy_tools.ipynb Returns ------- The cartopy axes (obviously you don't need this if you gave an ax as an argument, but it is useful if you initialize a new map). """ ax = check_cartopy_axes(ax=ax, crs=crs, verbose=verbose) if (LAND or OCEAN) and scale in ["10m"]: if verbose: warnings.warn( "🕖 OCEAN or LAND features at 10m may take a long time (3+ mins) to display on large maps." ) kwargs.setdefault("linewidth", 0.75) COASTLINES_kwargs.setdefault("zorder", 100) COASTLINES_kwargs.setdefault("facecolor", "none") COUNTIES_kwargs.setdefault("linewidth", 0.5) STATES_kwargs.setdefault("alpha", 0.15) LAND_kwargs.setdefault("edgecolor", "none") LAND_kwargs.setdefault("linewidth", 0) OCEAN_kwargs.setdefault("edgecolor", "none") LAKES_kwargs.setdefault("linewidth", 0) # NOTE: I don't use the 'setdefault' method here because it doesn't # work as expect when switching between dark and normal themes. # The defaults would be set the first time the function is called, # but the next time it is called and `dark=True` the defaults do not # reset. I don't know why this is the behavior. if dark: land = "#060613" water = "#0f2b38" # https://github.com/SciTools/cartopy/issues/880 ax.set_facecolor(land) # requires cartopy >= 0.18 kwargs = {**{"edgecolor": ".5"}, **kwargs} LAND_kwargs = {**{"facecolor": land}, **LAND_kwargs} OCEAN_kwargs = {**{"facecolor": water}, **OCEAN_kwargs} RIVERS_kwargs = {**{"edgecolor": water}, **RIVERS_kwargs} LAKES_kwargs = {**{"facecolor": water}, **LAKES_kwargs} else: kwargs = {**{"edgecolor": ".15"}, **kwargs} RIVERS_kwargs = { **{ "edgecolor": feature.COLORS["water"] }, **RIVERS_kwargs } LAKES_kwargs = { **{ "edgecolor": feature.COLORS["water"] }, **LAKES_kwargs } ##------------------------------------------------------------------ ## Add each element to the plot ## When combining kwargs, ## - kwargs is the main value ## - FEATURE_kwargs is the overwrite for the feature ## For example: ## {**kwargs, **FEATURE_kwargs} ## the kwargs are overwritten by FEATURE_kwargs ##------------------------------------------------------------------ if COASTLINES: # ax.coastlines(scale, **kwargs) # Nah, use the crs.feature instead ax.add_feature(feature.COASTLINE.with_scale(scale), **{ **kwargs, **COASTLINES_kwargs }) if verbose == "debug": print("🐛 COASTLINES:", {**kwargs, **COASTLINES_kwargs}) if BORDERS: ax.add_feature(feature.BORDERS.with_scale(scale), **{ **kwargs, **BORDERS_kwargs }) if verbose == "debug": print("🐛 BORDERS:", {**kwargs, **BORDERS_kwargs}) if STATES: ax.add_feature(feature.STATES.with_scale(scale), **{ **kwargs, **STATES_kwargs }) if verbose == "debug": print("🐛 STATES:", {**kwargs, **STATES_kwargs}) if COUNTIES: _counties_scale = {"20m", "5m", "500k"} assert ( counties_scale in _counties_scale), f"counties_scale must be {_counties_scale}" ax.add_feature(USCOUNTIES.with_scale(counties_scale), **{ **kwargs, **COUNTIES_kwargs }) if verbose == "debug": print("🐛 COUNTIES:", {**kwargs, **COUNTIES_kwargs}) if OCEAN: ax.add_feature(feature.OCEAN.with_scale(scale), **{ **kwargs, **OCEAN_kwargs }) if verbose == "debug": print("🐛 OCEAN:", {**kwargs, **OCEAN_kwargs}) if LAND and not dark: # If `dark=True`, the face_color is the land color. ax.add_feature(feature.LAND.with_scale(scale), **{ **kwargs, **LAND_kwargs }) if verbose == "debug": print("🐛 LAND:", {**kwargs, **LAND_kwargs}) if RIVERS: ax.add_feature(feature.RIVERS.with_scale(scale), **{ **kwargs, **RIVERS_kwargs }) if verbose == "debug": print("🐛 RIVERS:", {**kwargs, **RIVERS_kwargs}) if LAKES: ax.add_feature(feature.LAKES.with_scale(scale), **{ **kwargs, **LAKES_kwargs }) if verbose == "debug": print("🐛 LAKES:", {**kwargs, **LAKES_kwargs}) if ROADS: ROADS_kwargs.setdefault("edgecolor", "#b30000") ROADS_kwargs.setdefault("facecolor", "none") ROADS_kwargs.setdefault("linewidth", 0.2) if "type" not in ROADS_kwargs: # Plot all roadways roads = feature.NaturalEarthFeature("cultural", "roads", "10m", **ROADS_kwargs) ax.add_feature(roads) else: # Specify the type of road to include in plot road_types = ROADS_kwargs.pop("type") if isinstance(road_types, str): road_types = [road_types] shpfilename = shapereader.natural_earth("10m", "cultural", "roads") df = geopandas.read_file(shpfilename) _types = df["type"].unique() assert np.all([ i in _types for i in road_types ]), f"`ROADS_kwargs['type']` must be a list of these: {_types}" road_geos = df.loc[df["type"].apply( lambda x: x in road_types)].geometry.values ax.add_geometries(road_geos, crs=pc, **ROADS_kwargs) if verbose == "debug": print("🐛 ROADS:", ROADS_kwargs) if PLACES: PLACES_kwargs.setdefault("country", "United States") PLACES_kwargs.setdefault("rank", 2) PLACES_kwargs.setdefault("scatter_kw", {"marker": "."}) PLACES_kwargs.setdefault("label_kw", dict(fontweight="bold", alpha=0.5)) country = PLACES_kwargs.pop("country") rank = PLACES_kwargs.pop("rank") scatter_kw = PLACES_kwargs.pop("scatter_kw") label_kw = PLACES_kwargs.pop("label_kw") places = shapereader.natural_earth("10m", "cultural", "populated_places") df = geopandas.read_file(places) df = df[df.SOV0NAME == country] df = df[df.SCALERANK <= rank] xs = df.geometry.values.x ys = df.geometry.values.y names = df.NAME if scatter_kw is not None: ax.scatter(xs, ys, transform=pc, **scatter_kw) if label_kw is not None: for x, y, name in zip(xs, ys, names): plt.text(x, y, name, clip_on=True, **label_kw) if STAMEN: if verbose: print( "😎 Please use `ax.set_extent` before increasing Zoom level for faster plotting." ) STAMEN_kwargs.setdefault("style", "terrain-background") STAMEN_kwargs.setdefault("zoom", 3) stamen_terrain = cimgt.Stamen(STAMEN_kwargs["style"]) ax.add_image(stamen_terrain, STAMEN_kwargs["zoom"]) if "alpha" in STAMEN_kwargs: # Need to manually put a white layer over the STAMEN terrain if dark: STAMEN_kwargs.setdefault("alpha_color", "k") else: STAMEN_kwargs.setdefault("alpha_color", "w") poly = ax.projection.domain ax.add_feature( feature.ShapelyFeature([poly], ax.projection), color=STAMEN_kwargs["alpha_color"], alpha=1 - STAMEN_kwargs["alpha"], zorder=1, ) if verbose == "debug": print("🐛 STAMEN:", STAMEN_kwargs) if OSM: image = cimgt.OSM() OSM_kwargs.setdefault("zoom", 1) ax.add_image(image, OSM_kwargs["zoom"]) if "alpha" in OSM_kwargs: # Need to manually put a white layer over the STAMEN terrain if dark: OSM_kwargs.setdefault("alpha_color", "k") else: OSM_kwargs.setdefault("alpha_color", "w") poly = ax.projection.domain ax.add_feature( feature.ShapelyFeature([poly], ax.projection), color=OSM_kwargs["alpha_color"], alpha=1 - OSM_kwargs["alpha"], zorder=1, ) if verbose == "debug": print("🐛 OSM:", OSM_kwargs) if figsize is not None: plt.gcf().set_figwidth(figsize[0]) plt.gcf().set_figheight(figsize[1]) if dpi is not None: plt.gcf().set_dpi(dpi) # Add my custom methods ax.__class__.adjust_extent = _adjust_extent ax.__class__.center_extent = _center_extent ax.__class__.copy_extent = _copy_extent return ax
basin = sys.argv[1].upper() season = sys.argv[2] tc = sys.argv[3].capitalize() #### Load the NHC HURDAT2 best-track for the desired TC via the 'onetrack' function track = np.array(onetrack(season, basin, tc, printalert=False)[1]) tcdates = np.array([ datetime.strptime(track[t, 0], '%Y%m%d%H%M') for t in range(track.shape[0]) ]) #### Declare fixed variables for mapping purposes mlon, xlon, mlat, xlat = [-97., -85., 27., 35. ] # fixed region centered on Louisiana/Mississippi lat = None pc = ccrs.PlateCarree() counties = USCOUNTIES.with_scale('5m') scl = '10m' borders = cfeature.BORDERS.with_scale(scl) lakes = cfeature.LAKES.with_scale(scl) coast = cfeature.COASTLINE.with_scale(scl) states = cfeature.NaturalEarthFeature(category='cultural', name='admin_1_states_provinces_lines', scale=scl, facecolor='none') levs = np.arange( 0., 12.1, 0.5) # will shade rainfall values every 0.5 inches from 0 to 12 cmap = plt.get_cmap('gist_heat_r') # colormap for mapping rainfall values mapProj = ccrs.LambertConformal(central_longitude=(xlon - mlon) / 2. + mlon, central_latitude=(xlat - mlat) / 2. + mlat) #### Iterate through available AHPS netCDF files to create 24-h rainfall maps
def makeStationPlot(plotTitle, plotFileName, maxDataAge, maxLat, minLat, maxLon, minLon, stationDensity, textSize, figX, figY, dpi, showCountryBorders, showStateBorders, showCountyBorders): # # Data Polling # Get data from AWC TDS dataURL = "https://www.aviationweather.gov/adds/dataserver_current/httpparam?dataSource=metars&requestType=retrieve&format=csv&minLat=" + str( minLat) + "&minLon=" + str(minLon) + "&maxLat=" + str( maxLat) + "&maxLon=" + str(maxLon) + "&hoursBeforeNow=" + str( maxDataAge) # First read in the data. We use pandas because it simplifies a lot of tasks, like dealing # with strings data = pd.read_csv(dataURL, header=5, usecols=(1, 3, 4, 5, 6, 7, 8, 12, 21, 22), names=[ 'stid', 'lat', 'lon', 'air_temperature', 'dew_point_temperature', 'wind_dir', 'wind_speed', 'slp', 'weather', 'cloud_fraction' ], na_values=-99999) # # Data Handling # convert T and Td from °C to °F data['air_temperature'] = (data['air_temperature'] * (9 / 5.0)) + 32 data['dew_point_temperature'] = (data['dew_point_temperature'] * (9 / 5.0)) + 32 # change sky category to % data['cloud_fraction'] = data['cloud_fraction'].replace( 'SKC', 0.0).replace('CLR', 0.0).replace('CAVOK', 0.0).replace( 'FEW', 0.1875).replace('SCT', 0.4375).replace('BKN', 0.750).replace( 'OVC', 1.000).replace('OVX', 1.000) # Drop rows with missing winds data = data.dropna(how='any', subset=['wind_dir', 'wind_speed']) # Set up the map projection proj = ccrs.LambertConformal( central_longitude=(minLon + (maxLon - minLon) / 2), central_latitude=(minLat + (maxLat - minLat) / 2)) # Set station density, in x meter radius point_locs = proj.transform_points(ccrs.PlateCarree(), data['lon'].values, data['lat'].values) data = data[reduce_point_density(point_locs, stationDensity * 1000)] # Get the wind components, converting from m/s to knots as will be appropriate u, v = wind_components( (data['wind_speed'].values * units('m/s')).to('knots'), data['wind_dir'].values * units.degree) # Convert the fraction value into a code of 0-8 and compensate for NaN values cloud_frac = (8 * data['cloud_fraction']) cloud_frac[np.isnan(cloud_frac)] = 10 cloud_frac = cloud_frac.astype(int) # Map weather strings to WMO codes. Only use the first symbol if there are multiple wx = [ wx_code_map[s.split()[0] if ' ' in s else s] for s in data['weather'].fillna('') ] # # Plot Setup # Set DPI of the resulting figure plt.rcParams['savefig.dpi'] = dpi # Create the figure and an axes set to the projection. fig = plt.figure(figsize=(figX, figY)) ax = fig.add_subplot(1, 1, 1, projection=proj) # Set plot bounds ax.set_extent((minLon, maxLon, minLat, maxLat)) # Add geographic features if showCountyBorders: ax.add_feature(USCOUNTIES.with_scale('500k'), edgecolor='gray', linewidth=0.25) if showStateBorders: state_borders = cfeature.NaturalEarthFeature( category='cultural', name='admin_1_states_provinces_lakes', scale='50m', facecolor='none') ax.add_feature(state_borders, edgecolor='gray', linewidth=0.5) if showCountryBorders: country_borders = cfeature.NaturalEarthFeature( category='cultural', name='admin_0_countries', scale='50m', facecolor='none') ax.add_feature(country_borders, edgecolor='black', linewidth=0.7) # # Create Station Plots # Set station location, setup plot stationplot = StationPlot(ax, data['lon'].values, data['lat'].values, clip_on=True, transform=ccrs.PlateCarree(), fontsize=textSize) # Plot the temperature and dew point stationplot.plot_parameter('NW', data['air_temperature'], color='red') stationplot.plot_parameter('SW', data['dew_point_temperature'], color='darkgreen') # Plot pressure data stationplot.plot_parameter('NE', data['slp'], formatter=lambda v: format(10 * v, '.0f')[-3:]) # Plot cloud cover stationplot.plot_symbol('C', cloud_frac, sky_cover) # Plot current weather stationplot.plot_symbol('W', wx, current_weather) # Add wind barbs stationplot.plot_barb(u, v) # Plot station id stationplot.plot_text((2, 0), data['stid']) # Set a title and show the plot ax.set_title(plotTitle) # Export fig fig.savefig('/home/CarterHumphreys/bin/send2web/' + datetime.utcnow().strftime("%Y%m%d-%H00") + '_' + plotFileName + '.png', bbox_inches='tight') fig.savefig('/home/CarterHumphreys/bin/send2web/' + plotFileName + '.png', bbox_inches='tight')
# Copyright (c) 2018 MetPy Developers. # Distributed under the terms of the BSD 3-Clause License. # SPDX-License-Identifier: BSD-3-Clause """ US Counties =========== Demonstrate how to plot US counties at all three available resolutions. """ import cartopy.crs as ccrs import matplotlib.pyplot as plt from metpy.plots import USCOUNTIES ########################################### proj = ccrs.LambertConformal(central_longitude=-85.0, central_latitude=45.0) fig = plt.figure(figsize=(12, 9)) ax1 = fig.add_subplot(1, 3, 1, projection=proj) ax2 = fig.add_subplot(1, 3, 2, projection=proj) ax3 = fig.add_subplot(1, 3, 3, projection=proj) for scale, axis in zip(['20m', '5m', '500k'], [ax1, ax2, ax3]): axis.set_extent([270.25, 270.9, 38.15, 38.75], ccrs.Geodetic()) axis.add_feature(USCOUNTIES.with_scale(scale), edgecolor='black')
def radsite_counties(site): radlon, radlat = nexrad_loc(site) # read all vertices uscnt = USCOUNTIES.with_scale('20m').geometries() cntx = [] cnty = [] for usc in uscnt: if isinstance(usc, Polygon): usc = [usc] for poly in usc: lon, lat = poly.exterior.xy # convert to radar-relative x-y coordinates x, y = lonlat2xy(np.array(lon), np.array(lat), radlon, radlat) cntx.append(x) cnty.append(y) ''' for poly in uscnt: lon, lat = poly.exterior.xy # convert to radar-relative x-y coordinates x, y = lonlat2xy(np.array(lon), np.array(lat), radlon, radlat) cntx.append(x) cnty.append(y) ''' # subset county polygons close enough to radar site ncnt = len(cntx) cntx_sub = [] cnty_sub = [] maxdist = 450. for i in range(ncnt): dist = np.sqrt(cntx[i]**2. + cnty[i]**2.) if np.min(dist) < maxdist: cntx_sub.append(cntx[i]) cnty_sub.append(cnty[i]) # create matplotlib path arrays npoly_cnt = len(cntx_sub) verts = np.vstack((cntx_sub[0], cnty_sub[0])).T codes = np.full(len(cntx_sub[0]), Path.LINETO) codes[0] = Path.MOVETO codes[-1] = Path.CLOSEPOLY for i in range(npoly_cnt - 1): verts = np.concatenate( (verts, np.vstack((cntx_sub[i + 1], cnty_sub[i + 1])).T)) codes_new = np.full(len(cntx_sub[i + 1]), Path.LINETO) codes_new[0] = Path.MOVETO codes_new[-1] = Path.CLOSEPOLY codes = np.concatenate((codes, codes_new)) # write to netcdf file nvert = len(codes) cfile = Dataset(f'site_geom/{site}_counties.nc', 'w') vind = cfile.createDimension('vert_ind', nvert) cdim = cfile.createDimension('coor_dim', 2) vert = cfile.createVariable('vertex', 'f4', ('vert_ind', 'coor_dim')) vertc = cfile.createVariable('vertex_code', 'i4', ('vert_ind')) vert.units = 'km' vertc.units = '' vert.description = 'distances of vertex from radar site' vertc.description = 'matplotlib path code for vertex' vert[:] = verts vertc[:] = codes cfile.close()
import cartopy.feature as cfeature from metpy.plots import USCOUNTIES # Plot extent plotExtent = [-81, -74.5, 42.3, 45.3] # Create the figure and an axes set to the projection proj = ccrs.Stereographic( central_longitude=((plotExtent[1] - plotExtent[0]) / 2 + plotExtent[0]), central_latitude=((plotExtent[3] - plotExtent[2]) / 2 + plotExtent[2])) fig = plt.figure(figsize=(15, 15)) ax = fig.add_subplot(1, 1, 1, projection=proj) ax.set_extent(plotExtent) # Add geographic features ax.add_feature(USCOUNTIES.with_scale('500k'), edgecolor='gray', linewidth=0.25) state_borders = cfeature.NaturalEarthFeature( category='cultural', name='admin_1_states_provinces_lakes', scale='50m', facecolor='none') ax.add_feature(state_borders, edgecolor='black', linewidth=0.5) country_borders = cfeature.NaturalEarthFeature(category='cultural', name='admin_0_countries', scale='50m', facecolor='none') ax.add_feature(country_borders, edgecolor='black', linewidth=1.0) # Plot Points markerSymbol = 'o' markerSize = 100
def mapper(self,zoom=None): """ This method will map all the points found in the find_my_station method. It uses cartopy, so make sure you have that if you want a map. zoom: int, how far you wish to zoom out (if positive). In degrees """ if self.station_df is None: print('ERROR: Please run find_my_station method first') else: ###import cartopy stuff import cartopy import cartopy.crs as ccrs import cartopy.feature as cfeature import matplotlib.ticker as mticker from cartopy.mpl.gridliner import LONGITUDE_FORMATTER, LATITUDE_FORMATTER import cartopy.io.shapereader as shpreader from cartopy.mpl.geoaxes import GeoAxes from mpl_toolkits.axes_grid1 import AxesGrid from cartopy.mpl.ticker import LongitudeFormatter, LatitudeFormatter from metpy.plots import USCOUNTIES ### #make figure fig = plt.figure(figsize=(10, 10)) #add the map ax = fig.add_subplot(1, 1, 1,projection=ccrs.PlateCarree()) #draw map things ax.add_feature(cfeature.STATES.with_scale('10m'),lw=0.5) ax.add_feature(cartopy.feature.OCEAN.with_scale('50m')) ax.add_feature(cartopy.feature.LAND.with_scale('50m'), edgecolor='black',lw=0.5,facecolor=[0.95,0.95,0.95]) ax.add_feature(cartopy.feature.LAKES.with_scale('50m'), edgecolor='black') ax.add_feature(cartopy.feature.RIVERS.with_scale('50m')) ax.add_feature(USCOUNTIES.with_scale('5m')) if zoom is None: zoom = 1 #set corners of the map. corners = [CS.reference_point[1] - zoom,CS.reference_point[1] + zoom,CS.reference_point[0]- zoom,CS.reference_point[0]+ zoom] #this set_extent crashes the python session. Not sure why... # ax.set_extent((CS.reference_point[1] - 5,CS.reference_point[1] + 5,CS.reference_point[0]- 2,CS.reference_point[0]+ 2),crs=ccrs.PlateCarree()) #draw ticks ax.set_xticks(np.arange(corners[0], corners[1], 1), crs=ccrs.PlateCarree()) ax.set_yticks(np.linspace(corners[2], corners[3], 5), crs=ccrs.PlateCarree()) lon_formatter = LongitudeFormatter(zero_direction_label=True) lat_formatter = LatitudeFormatter() ax.xaxis.set_major_formatter(lon_formatter) ax.yaxis.set_major_formatter(lat_formatter) #force bounds ax.set_xlim([corners[0],corners[1]]) ax.set_ylim([corners[2],corners[3]]) #plot stations colored by distance pm = ax.scatter(self.station_df.longitude,self.station_df.latitude,c=self.station_df.distance,s=(self.station_df.length_of_record.values.astype(int)/3.154e+16)/2,zorder=2) plt.colorbar(pm,ax=ax,label='Distance') ax.plot(self.reference_point[1],self.reference_point[0],'*k',ms=15,markerfacecolor='w',markeredgewidth=2,zorder=10,label='Reference_point') ax.plot(self.station.longitude,self.station.latitude,'sk',ms=10,markerfacecolor='w',markeredgewidth=2,label='Closest_Station') ax.legend()
# Copyright (c) 2018 MetPy Developers. # Distributed under the terms of the BSD 3-Clause License. # SPDX-License-Identifier: BSD-3-Clause """ US Counties =========== Demonstrate how to plot US counties at all three available resolutions. """ import cartopy.crs as ccrs import matplotlib.pyplot as plt from metpy.plots import USCOUNTIES ########################################### proj = ccrs.LambertConformal(central_longitude=-85.0, central_latitude=45.0) fig = plt.figure(figsize=(12, 9)) ax1 = fig.add_subplot(1, 3, 1, projection=proj) ax2 = fig.add_subplot(1, 3, 2, projection=proj) ax3 = fig.add_subplot(1, 3, 3, projection=proj) for scale, axis in zip(['20m', '5m', '500k'], [ax1, ax2, ax3]): axis.set_extent([270.25, 270.9, 38.15, 38.75], ccrs.Geodetic()) axis.add_feature(USCOUNTIES.with_scale(scale))
def plot_low_sweeps(site, fpath, ds_set=150., xcen_set=150., ycen_set=70., sw_ang=0.5): # open radar file radar = read_nexrad_archive(fpath) radlat = radar.latitude['data'][0] radlon = radar.longitude['data'][0] nyvel = radar.get_nyquist_vel(1) # plot stuff mpl.rc('font', **{'family': 'sans-serif', 'sans-serif': ['Helvetica']}) mpl.rc('text', usetex=True) figcnt = 0 # get lat lon corners of data domain ds = ds_set xcen = xcen_set ycen = ycen_set minlat, minlon = xy2latlon(xcen - ds, ycen - ds, radlat, radlon) maxlat, maxlon = xy2latlon(xcen + ds, ycen + ds, radlat, radlon) xlabel = 'X-distance (km)' ylabel = 'Y-distance (km)' # color map stuff zh_map = createCmap('zh2_map') zdr_map = createCmap('zdr_map') vel_map = createCmap('vel2_map') phv_map = createCmap('phv_map') kdp_map = createCmap('kdp_map') numcolors = 33 numlevs = numcolors - 1 cinds = np.linspace(0., 254., numcolors).astype(int) zh_cols = zh_map.colors[cinds] zdr_cols = zdr_map.colors[cinds] vel_cols = vel_map.colors[cinds] phv_cols = phv_map.colors[cinds] kdp_cols = kdp_map.colors[cinds] zh_levs = np.linspace(-10., 70., numlevs) sw_levs = np.linspace(0., 8., numlevs) zdr_levs = np.linspace(-2.4, 6.9, numlevs) phidp_levs = np.linspace(50., 100., numlevs) phv_levs = np.linspace(0.71, 1.06, numlevs) kdp_levs = np.linspace(-0.8, 2.3, numlevs) vel_levs = np.linspace(-35., 35., numlevs) zh_mapn, zh_norm = cm.from_levels_and_colors(zh_levs, zh_cols, extend='both') zdr_mapn, zdr_norm = cm.from_levels_and_colors(zdr_levs, zdr_cols, extend='both') phidp_mapn, phidp_norm = cm.from_levels_and_colors(phidp_levs, zh_cols, extend='both') phv_mapn, phv_norm = cm.from_levels_and_colors(phv_levs, phv_cols, extend='both') kdp_mapn, kdp_norm = cm.from_levels_and_colors(kdp_levs, kdp_cols, extend='both') vel_mapn, vel_norm = cm.from_levels_and_colors(vel_levs, vel_cols, extend='both') sw_mapn, sw_norm = cm.from_levels_and_colors(sw_levs, zh_cols, extend='both') # set common font sizes cblb_fsize = 18 cbti_fsize = 16 axtl_fsize = 20 axlb_fsize = 20 axti_fsize = 18 # cartopy features coast = cfeature.GSHHSFeature(scale='high', levels=[1], edgecolor='gray') states = cfeature.STATES.with_scale('50m') shapename = 'admin_1_states_provinces_lakes_shp' states_shp = shpreader.natural_earth(resolution='50m', category='cultural', name=shapename) # create basemap #m = Basemap(llcrnrlon=minlon, llcrnrlat=minlat, urcrnrlon=maxlon, urcrnrlat=maxlat, # projection='merc', lat_1=15., lat_2=35., lon_0=-80., # resolution='h', area_thresh=1000.) # get sweeps fixed_angles = radar.fixed_angle['data'] nang = len(fixed_angles) sw05 = np.arange(nang)[np.abs(fixed_angles - sw_ang) < 0.2] print(fixed_angles) # seperate out z and mdv sweeps sw_inds = sw05[::2] swv_inds = sw05[1::2] # loop over sweeps for sw in sw_inds: azi_p = 90. - radar.get_azimuth(sw) elev_p = radar.get_elevation(sw) ran = radar.range['data'] sweep = radar.extract_sweeps([sw]) fixed_angle = fixed_angles[sw] if fixed_angle < 2.: sweep_v = radar.extract_sweeps([sw + 1]) else: sweep_v = sweep # calculate sweep time vol_time = sweep.time['units'] sw_toffs = sweep.time['data'][0] sw_time = datetime.fromtimestamp( time.mktime( time.strptime(vol_time, 'seconds since %Y-%m-%dT%H:%M:%SZ'))) sw_time = sw_time + timedelta(seconds=sw_toffs) # get time strings yyyy = '{:04d}'.format(sw_time.year) mm = '{:02d}'.format(sw_time.month) dd = '{:02d}'.format(sw_time.day) hh = '{:02d}'.format(sw_time.hour) mn = '{:02d}'.format(sw_time.minute) ss = '{:02d}'.format(sw_time.second) print(yyyy, mm, dd, hh, mn, ss) ref_p = sweep.fields['reflectivity']['data'] zdr_p = sweep.fields['differential_reflectivity']['data'] rhohv_p = sweep.fields['cross_correlation_ratio']['data'] vel_p = sweep_v.fields['velocity']['data'] phidp_p = sweep.fields['differential_phase']['data'] sw_p = sweep_v.fields['spectrum_width']['data'] azi_v_p = 90. - radar.get_azimuth(sw + 1) elev_v_p = radar.get_elevation(sw + 1) dims = ref_p.shape numradials = dims[0] + 1 numgates = dims[1] # expand radially to remove no data spike elev = np.empty([numradials]) elev_v = np.empty([numradials]) azi = np.empty([numradials]) azi_v = np.empty([numradials]) ref = np.empty([numradials, numgates]) zdr = np.empty([numradials, numgates]) phidp = np.empty([numradials, numgates]) rhohv = np.empty([numradials, numgates]) vel = np.empty([numradials, numgates]) sw = np.empty([numradials, numgates]) elev[0:numradials - 1] = elev_p elev[numradials - 1] = elev_p[0] elev_v[0:numradials - 1] = elev_v_p elev_v[numradials - 1] = elev_v_p[0] azi[0:numradials - 1] = azi_p azi[numradials - 1] = azi_p[0] azi_v[0:numradials - 1] = azi_v_p azi_v[numradials - 1] = azi_v_p[0] ref[0:numradials - 1, :] = ref_p ref[numradials - 1, :] = ref_p[0] zdr[0:numradials - 1, :] = zdr_p zdr[numradials - 1, :] = zdr_p[0] phidp[0:numradials - 1, :] = phidp_p phidp[numradials - 1, :] = phidp_p[0] rhohv[0:numradials - 1, :] = rhohv_p rhohv[numradials - 1, :] = rhohv_p[0] vel[0:numradials - 1, :] = vel_p vel[numradials - 1, :] = vel_p[0] sw[0:numradials - 1, :] = sw_p sw[numradials - 1, :] = sw_p[0] # get stats on velocity vcount = Counter(vel.flatten()) angle = np.mean(elev) angle_v = np.mean(elev_v) # mask data by rhohv and threshold #----------------------------------------------- ref = np.ma.masked_where(rhohv < 0.4, ref) zdr = np.ma.masked_where(rhohv < 0.4, zdr) phidp = np.ma.masked_where(rhohv < 0.4, phidp) vel = np.ma.masked_where(rhohv < 0.4, vel) sw = np.ma.masked_where(rhohv < 0.4, sw) rhohv = np.ma.masked_where(rhohv < 0.4, rhohv) zdr = np.ma.masked_where(ref < -15., zdr) phidp = np.ma.masked_where(ref < -15., phidp) rhohv = np.ma.masked_where(ref < -15., rhohv) vel = np.ma.masked_where(ref < -15., vel) sw = np.ma.masked_where(ref < -15., sw) ref = np.ma.masked_where(ref < -15., ref) # calculate kdp #----------------------------------------------- print('Calculating KDP...') phidp = dealiasPhiDP(phidp) kdp_alt, delta, phidp_alt = calc_kdp(phidp) kdp_alt = np.ma.masked_where(ref < -5., kdp_alt) # calculate x and y coordinates (wrt beampath) for plotting #----------------------------------------------------------- ran_2d = np.tile(ran, (numradials, 1)) azi.shape = (azi.shape[0], 1) azi_v.shape = (azi_v.shape[0], 1) azi_2d = np.tile(azi, (1, numgates)) azi_v_2d = np.tile(azi_v, (1, numgates)) radz = 10. erad = np.pi * angle / 180. erad_v = np.pi * angle_v / 180. ke = 4. / 3. a = 6378137. # beam height and beam distance zcor = np.sqrt(ran_2d**2. + (ke * a)**2. + 2. * ran_2d * ke * a * np.sin(erad)) - ke * a + radz scor = ke * a * np.arcsin(ran_2d * np.cos(erad) / (ke * a + zcor)) / 1000. xcor = scor * np.cos(np.pi * azi_2d / 180.) ycor = scor * np.sin(np.pi * azi_2d / 180.) # for velocity zcor_v = np.sqrt(ran_2d**2. + (ke * a)**2. + 2. * ran_2d * ke * a * np.sin(erad_v)) - ke * a + radz scor_v = ke * a * np.arcsin(ran_2d * np.cos(erad_v) / (ke * a + zcor)) / 1000. xcor_v = scor_v * np.cos(np.pi * azi_v_2d / 180.) ycor_v = scor_v * np.sin(np.pi * azi_v_2d / 180.) # convert to lon,lat for basemap plotting lat, lon = xy2latlon(xcor, ycor, radlat, radlon) lat_v, lon_v = xy2latlon(xcor_v, ycor_v, radlat, radlon) # plot #--------------------- print('Plotting...') plt.figure(figcnt) figcnt = figcnt + 1 #x, y = m(lon, lat) #x_v, y_v = m(lon_v, lat_v) #rx, ry = m(radlon, radlat) # ZH plot #------------------------------ ax1 = plt.subplot(2, 2, 1, projection=ccrs.PlateCarree()) plt.pcolormesh(lon, lat, ref, cmap=zh_map, vmin=-10., vmax=80., transform=ccrs.PlateCarree()) cb1 = plt.colorbar(fraction=0.04) cb1.set_label('(dBZ)', fontsize=cblb_fsize) cb1_la = [f'{ti:.0f}' for ti in cb1.get_ticks()] cb1.ax.set_yticklabels(cb1_la, fontsize=cbti_fsize) ax1.set_title('Z$\sf{_H}$', x=0.0, y=1.02, horizontalalignment='left', fontsize=axtl_fsize) #ax1.add_feature(coast) #ax1.add_feature(states, edgecolor='k') ax1.add_geometries(shpreader.Reader(states_shp).geometries(), ccrs.PlateCarree(), edgecolor='k', facecolor='none', linewidth=0.5) ax1.add_feature(USCOUNTIES.with_scale('20m'), edgecolor='k', linewidth=0.2) ax1.set_extent([minlon, maxlon, minlat, maxlat]) # ZDR plot #------------------------------ ax2 = plt.subplot(2, 2, 2, projection=ccrs.PlateCarree()) plt.pcolormesh(lon, lat, zdr, cmap=zdr_map, vmin=-2.4, vmax=6.9, transform=ccrs.PlateCarree()) cb2 = plt.colorbar(fraction=0.04) cb2.set_label('(dB)', fontsize=cblb_fsize) cb2_la = [f'{ti:.1f}' for ti in cb2.get_ticks()] cb2.ax.set_yticklabels(cb2_la, fontsize=cbti_fsize) ax2.set_title('Z$_{\sf{DR}}$', x=0.0, y=1.02, horizontalalignment='left', fontsize=axtl_fsize) ax2.add_geometries(shpreader.Reader(states_shp).geometries(), ccrs.PlateCarree(), edgecolor='k', facecolor='none', linewidth=0.5) ax2.add_feature(USCOUNTIES.with_scale('20m'), edgecolor='k', linewidth=0.2) ax2.set_extent([minlon, maxlon, minlat, maxlat]) # KDP plot #------------------------------ ax3 = plt.subplot(2, 2, 3, projection=ccrs.PlateCarree()) plt.pcolormesh(lon, lat, kdp_alt, cmap=kdp_map, vmin=-1.6, vmax=4.3, transform=ccrs.PlateCarree()) cb3 = plt.colorbar(fraction=0.04) cb3.set_label('(deg./km)', fontsize=cblb_fsize) cb3_la = [f'{ti:.1f}' for ti in cb3.get_ticks()] cb3.ax.set_yticklabels(cb3_la, fontsize=cbti_fsize) ax3.set_title('$\sf{K_{DP}}$', x=0.0, y=1.02, horizontalalignment='left', fontsize=axtl_fsize) ax3.add_geometries(shpreader.Reader(states_shp).geometries(), ccrs.PlateCarree(), edgecolor='k', facecolor='none', linewidth=0.5) ax3.add_feature(USCOUNTIES.with_scale('20m'), edgecolor='k', linewidth=0.2) ax3.set_extent([minlon, maxlon, minlat, maxlat]) # RhoHV plot #------------------------------ ax4 = plt.subplot(2, 2, 4, projection=ccrs.PlateCarree()) plt.pcolormesh(lon, lat, rhohv, cmap=phv_map, vmin=0.695, vmax=1.045, transform=ccrs.PlateCarree()) cb4 = plt.colorbar(fraction=0.04) cb4.set_label('', fontsize=20) cb4_la = [f'{ti:.2f}' for ti in cb4.get_ticks()] cb4.ax.set_yticklabels(cb4_la, fontsize=cbti_fsize) ax4.set_title('$\\rho\sf{_{HV}}$', x=0.0, y=1.02, horizontalalignment='left', fontsize=axtl_fsize) ax4.add_geometries(shpreader.Reader(states_shp).geometries(), ccrs.PlateCarree(), edgecolor='k', facecolor='none', linewidth=0.5) ax4.add_feature(USCOUNTIES.with_scale('20m'), edgecolor='k', linewidth=0.2) ax4.set_extent([minlon, maxlon, minlat, maxlat]) # save image as .png #------------------------------- title = '{} - {}/{}/{} - {}:{} UTC - {:.1f} deg. PPI'.format( site, yyyy, mm, dd, hh, mn, float(angle)) plt.suptitle(title, fontsize=24) plt.subplots_adjust(top=0.95, hspace=-0.1, wspace=0.2) imgname = yyyy + mm + dd + '_' + hh + mn + '_' + site.lower() + '.png' plt.savefig(imgname, format='png', dpi=120) plt.close() # crop out white space from figure os.system('convert -trim ' + imgname + ' ' + imgname)
geoms = (intersection(geom) for geom in geometries if bounds.intersects(geom)) print(vtec[phensigString]['hdln'] + " (" + phensigString + ") issued at " + str(ref) + " (" + str(poly.geom_type) + geom_count + ")") color = warning_color(phensigString) shape_feature = ShapelyFeature(geoms, ccrs.PlateCarree(), facecolor=color, edgecolor=color) ax.add_feature(shape_feature) # Add geographic features ax.add_feature(USCOUNTIES.with_scale('500k'), edgecolor='gray', linewidth=0.25) state_borders = cfeature.NaturalEarthFeature( category='cultural', name='admin_1_states_provinces_lakes', scale='50m', facecolor='none') ax.add_feature(state_borders, edgecolor='gray', linewidth=0.5) country_borders = cfeature.NaturalEarthFeature(category='cultural', name='admin_0_countries', scale='50m', facecolor='none') ax.add_feature(country_borders, edgecolor='black', linewidth=0.7)
# Copyright (c) 2018 MetPy Developers. # Distributed under the terms of the BSD 3-Clause License. # SPDX-License-Identifier: BSD-3-Clause """ =========== US Counties =========== Demonstrate how to plot US counties at all three available resolutions. """ import cartopy.crs as ccrs import matplotlib.pyplot as plt from metpy.plots import USCOUNTIES ########################################### proj = ccrs.LambertConformal(central_longitude=-85.0, central_latitude=45.0) fig = plt.figure(figsize=(12, 9)) ax1 = fig.add_subplot(1, 3, 1, projection=proj) ax2 = fig.add_subplot(1, 3, 2, projection=proj) ax3 = fig.add_subplot(1, 3, 3, projection=proj) for scale, axis in zip(['20m', '5m', '500k'], [ax1, ax2, ax3]): axis.set_extent([270.25, 270.9, 38.15, 38.75], ccrs.Geodetic()) axis.add_feature(USCOUNTIES.with_scale(scale))
import cartopy.feature as cfeature import matplotlib.pyplot as plt import awips from awips.dataaccess import DataAccessLayer from metpy.plots import USCOUNTIES #Setting the Projection proj = ccrs.LambertConformal(central_longitude=-72.5, central_latitude=42, standard_parallels=[35]) plt.rcParams['savefig.dpi'] #Creating the Internal Figure fig = plt.figure(figsize = (20,10)) ax = fig.add_subplot(1,1,1, projection=proj) #Adding County Boundaries for scale, axis in zip(['5m'], ['ax']): ax.add_feature(USCOUNTIES.with_scale(scale), edgecolor="lightgray") #Adding State Boundaries ax.add_feature(cfeature.STATES) ax.add_feature(cfeature.BORDERS) ax.set_extent((-65, -80, 37, 47)) ax.set_title(str("***ADD HEADLINE HERE***")) plt.show()
def create_map(alert): ''' Create the alert map''' alert_map_info = (convert_geojson_to_geopandas_df(alert) if alert['geometry'] else calculate_ugc_geography(alert)) warning_cmap = { 'Flood Watch': '#2E8B57', 'Flash Flood Watch': '#2E8B57', 'Flash Flood Warning': '#8B0000', 'Flood Warning': '#00FF00', 'Coastal Flood Watch': '#66CDAA', 'Coastal Flood Warning': '#228B22', 'Severe Thunderstorm Watch': '#DB7093', 'Severe Thunderstorm Warning': '#FFA500', 'Special Weather Statement': '#FFE4B5', 'Tornado Watch': '#FFFF00', 'Tornado Warning': '#FF0000', 'Storm Surge Watch': '#DB7FF7', 'Storm Surge Warning': '#B524F7', 'Dense Fog Advisory': '#708090', 'Rip Current Statement': '#40E0D0', 'Red Flag Warning': '#FF1493' } google_tiles = GoogleTiles() data_crs = ccrs.PlateCarree() # Setup matplotlib figure fig = Figure(figsize=(1280 / 72, 720 / 72)) ax = fig.add_axes([0, 0, 1, 1], projection=data_crs) ax.add_image(google_tiles, 8) ax.set_extent([ alert_map_info['west_bound'] - 0.5, alert_map_info['east_bound'] + 0.5, alert_map_info['south_bound'] - 0.5, alert_map_info['north_bound'] + 0.6 ], data_crs) ax.set_adjustable('datalim') # Setup borders (states, countries, coastlines, etc) ax.add_feature(USCOUNTIES.with_scale('20m'), edgecolor='gray', zorder=5, linewidth=1.2) ax.add_feature(cfeature.STATES.with_scale('10m'), linewidth=3, zorder=5) # Add radar ax.add_wms( wms='https://mesonet.agron.iastate.edu/cgi-bin/wms/nexrad/n0q-t.cgi?', layers='nexrad-n0q-wmst', wms_kwargs={ 'transparent': True, 'time': get_radar_timestamp() }, zorder=4, alpha=0.4) # Plot alerts on the map for key in warning_cmap.keys(): if key == alert['properties']['event'] and alert['geometry']: ax.add_geometries(alert_map_info['polygon'], crs=data_crs, facecolor=warning_cmap[key], edgecolor='black', linewidth=4, zorder=6, alpha=0.04) elif key == alert['properties']['event'] and not alert['geometry']: for polys in alert_map_info['polygon']: ax.add_geometries(polys, crs=data_crs, facecolor=warning_cmap[key], edgecolor='black', linewidth=4, alpha=0.5, zorder=6) else: continue # Set title title = ('SIGNIFICANT WEATHER ALERT' if alert['properties']['event'] == 'Special Weather Statement' else alert['properties']['event'].upper()) ax.set_title(title, loc='left', ha='left', va='top', fontsize=48, color='white', fontweight='bold', fontname='Arial', y=0.96, x=0.03, zorder=11, bbox={ 'facecolor': '#0c3245', 'alpha': 1.0, 'edgecolor': 'none', 'boxstyle': 'square,pad=0.2' }) fig.savefig('alert_visual.png', dpi=72)
import cartopy.io.shapereader as shpreader from matplotlib.axes import Axes from cartopy.mpl.geoaxes import GeoAxes GeoAxes._pcolormesh_patched = Axes.pcolormesh proj_cart = ccrs.PlateCarree(central_longitude=-95) # Add a note about plotting counties by default if metpy is available in docs, and how to add your own map data without relying on built-ins. # reader = shpreader.Reader('/Users/vannac/Documents/UScounties/UScounties.shp') # reader = shpreader.Reader('/home/vanna/status_plots/UScounties/UScounties.shp') # counties = list(reader.geometries()) # COUNTIES = cfeature.ShapelyFeature(counties, ccrs.PlateCarree()) try: from metpy.plots import USCOUNTIES county_scales = ['20m', '5m', '500k'] COUNTIES = USCOUNTIES.with_scale(county_scales[0]) except ImportError: COUNTIES = None M2KM = 1000.0 COORD_TH = [0.1, 0.8, 0.83, 0.1] COORD_PLAN = [0.1, 0.1, 0.65, 0.5] COORD_LON = [0.1, 0.65, 0.65, 0.1] COORD_LAT = [0.8, 0.1, 0.13, 0.5] COORD_HIST = [0.8, 0.65, 0.13, 0.1] xdiv = 0.01 ydiv = 0.01 zdiv = 0.1 class FractionalSecondFormatter(Formatter):
def common_features(scale='110m', counties_scale='20m', figsize=None, *, ax=None, projection=pc, verbose=False, dark_theme=False, COASTLINES=True, BORDERS=False, STATES=False, COUNTIES=False, OCEAN=False, LAND=False, RIVERS=False, LAKES=False, STAMEN=False, COASTLINES_kwargs={}, BORDERS_kwargs={}, STATES_kwargs={}, COUNTIES_kwargs={}, OCEAN_kwargs={}, LAND_kwargs={}, RIVERS_kwargs={}, LAKES_kwargs={}, STAMEN_kwargs={}, **kwargs): """ Add common features to a cartopy axis. .. Tip:: This is a great way to initialize a new cartopy axes. Parameters ---------- scale : {'10m', '50m' 110m'} The cartopy feature's level of detail .. note:: The ``'10m'`` scale for OCEAN and LAND takes a *long* time. Consider using ``'50m'`` if you need OCEAN and LAND colored. counties_scale: {'20m', '5m', '500k'} Counties are plotted via MetPy and have different resolutions available than other features. - 20m = 20,000,000 resolution (Ok if you show a large area) - 5m = 5,000,000 resolution (provides good detail) - 500k = 500,000 resolution (plots very slow) ax : plot axes The axis to add the feature to. If None, it will create a new cartopy axes with ``projection``. projection : cartopy.crs Projection to create new map if no cartopy axes is given. Default is PlateCarree. dark_theme : bool If True, use alternative "dark theme" colors for land and water. .. figure:: _static/BB_maps/common_features-1.png .. figure:: _static/BB_maps/common_features-2.png FEATURES : bool Toggle on various features. By default, only COASTLINES is turned on. Each feature has a cooresponding ``FEATURE_kwargs={}`` dictionary to supply additional arguments to cartopy's add_feature method (e.g., change line color or width by feature type). ========== ========================================================= FEATURE Description ========== ========================================================= COASTLINES Coastlines, boundary between land and ocean. BORDERS Borders between countries. *Does not includes coast*. STATES US state borders. Includes coast. COUNTIES US Counties. Includes coast. OCEAN Colored ocean area LAND Colored land area RIVERS Lines where rivers exist LAKES Colored lake area ========== ========================================================= ========== ========================================================= MAP TILE Description ========== ========================================================= Stamen Specify type and zoom level. http://maps.stamen.com/ Style: ``terrain-background``, ``terrain``, ``toner-background``, ``toner``, `watercolor`` Zoom: int [0-10] Examples -------- https://inversion.nrlmry.navy.mil/confluence/display/~Blaylock/2020/08/07/Cartopy%3A+Add+Common+Features Each feature can be toggled on by setting the argument to ``True``. .. figure:: _static/BB_maps/individual_features.png By default, the COASTLINES=True .. figure:: _static/BB_maps/features_with_coastlines.png .. figure:: _static/BB_maps/features_with_coastlines_DARK.png The next two illustrate the level of detail for ``'50m'`` and ``'10m'``. Note that the OCEAN and LAND features take 3+ minutes to render for the 10m resolution the first time you plot it. .. figure:: _static/BB_maps/features_with_coastlines_10m.png .. figure:: _static/BB_maps/features_with_coastlines_50m.png Returns ------- The cartopy axes (obviously you don't need this if you gave an ax as an argument, but it is useful if you initialize a new map). """ ax = check_cartopy_axes(ax, projection) if (LAND or OCEAN) and scale in ['10m']: warnings.warn( '🕖 OCEAN or LAND features at 10m will take a long time (3+ mins) to display.' ) kwargs.setdefault('linewidth', .75) COASTLINES_kwargs = { **dict(zorder=100, facecolor='none'), **COASTLINES_kwargs } COUNTIES_kwargs = {**{'linewidth': .5}, **COUNTIES_kwargs} LAND_kwargs = {**{'edgecolor': 'none'}, **LAND_kwargs} OCEAN_kwargs = {**{'edgecolor': 'none'}, **OCEAN_kwargs} LAKES_kwargs = {**{'linewidth': 0}, **LAKES_kwargs} if dark_theme: kwargs = {**kwargs, **{'edgecolor': '.5'}} land = '#060613' water = '#0f2b38' LAND_kwargs = {**{'facecolor': land}, **LAND_kwargs} OCEAN_kwargs = {**{'facecolor': water}, **OCEAN_kwargs} RIVERS_kwargs = {**{'edgecolor': water}, **RIVERS_kwargs} LAKES_kwargs = {**{'facecolor': water}, **LAKES_kwargs} #https://github.com/SciTools/cartopy/issues/880 ax.background_patch.set_facecolor(land) # depreciated #ax.set_facecolor(land) # Might work if I update cartopy else: kwargs = {**kwargs, **{'edgecolor': '.15'}} RIVERS_kwargs = { **{ 'edgecolor': feature.COLORS['water'] }, **RIVERS_kwargs } ##------------------------------------------------------------------ ## Add each element to the plot ## When combining kwargs, ## - kwargs is the main value ## - FEATURE_kwargs is the overwrite for the feature ## For example: ## {**kwargs, **FEATURE_kwargs} ## the kwargs are overwritten by FEATURE kwargs ##------------------------------------------------------------------ if COASTLINES: #ax.coastlines(scale, **kwargs) # Nah, use the crs.feature instead ax.add_feature(feature.COASTLINE.with_scale(scale), **{ **kwargs, **COASTLINES_kwargs }) if BORDERS: ax.add_feature(feature.BORDERS.with_scale(scale), **{ **kwargs, **BORDERS_kwargs }) if STATES: ax.add_feature(feature.STATES.with_scale(scale), **{ **kwargs, **STATES_kwargs }) if COUNTIES: _counties_scale = {'20m', '5m', '500k'} assert counties_scale in _counties_scale, f"counties_scale must be {_counties_scale}" ax.add_feature(USCOUNTIES.with_scale(counties_scale), **{ **kwargs, **COUNTIES_kwargs }) if OCEAN: ax.add_feature(feature.OCEAN.with_scale(scale), **{ **kwargs, **OCEAN_kwargs }) if LAND and not dark_theme: # If `dark_theme=True`, the face_color is the land color. ax.add_feature(feature.LAND.with_scale(scale), **{ **kwargs, **LAND_kwargs }) if RIVERS: ax.add_feature(feature.RIVERS.with_scale(scale), **{ **kwargs, **RIVERS_kwargs }) if LAKES: ax.add_feature(feature.LAKES.with_scale(scale), **{ **kwargs, **LAKES_kwargs }) if STAMEN: if verbose: print("Please use `ax.set_extent` before increasing Zoom level.") STAMEN_kwargs.setdefault('style', 'terrain-background') STAMEN_kwargs.setdefault('zoom', 3) style = STAMEN_kwargs['style'] zoom = STAMEN_kwargs['zoom'] stamen_terrain = cimgt.Stamen(style) ax.add_image(stamen_terrain, zoom) if 'alpha' in STAMEN_kwargs: # Need to manually put a white layer over the STAMEN terrain STAMEN_kwargs.setdefault('alpha_color', 'w') poly = ax.projection.domain ax.add_feature(feature.ShapelyFeature([poly], ax.projection), color=STAMEN_kwargs['alpha_color'], alpha=1 - STAMEN_kwargs['alpha'], zorder=1) if figsize is not None: plt.gcf().set_figwidth(figsize[0]) plt.gcf().set_figheight(figsize[1]) return ax