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
Esempio n. 2
0
    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)
Esempio n. 3
0
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
Esempio n. 4
0
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
Esempio n. 5
0
    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
Esempio n. 6
0
        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')
Esempio n. 10
0
# 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')
Esempio n. 11
0
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
Esempio n. 13
0
  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()
Esempio n. 14
0
# 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))
Esempio n. 15
0
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)
Esempio n. 16
0
            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)
Esempio n. 17
0
# 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))
Esempio n. 18
0
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()
Esempio n. 19
0
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)
Esempio n. 20
0
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