Example #1
0
File: grid.py Project: silvioda/rtm
def define_grid(lon_0,
                lat_0,
                x_radius,
                y_radius,
                spacing,
                projected=False,
                plot_preview=False):
    """
    Define the spatial grid of trial source locations. Grid can be defined in
    either a latitude/longitude or projected UTM (i.e., Cartesian) coordinate
    system.

    Args:
        lon_0: [deg] Longitude of grid center
        lat_0: [deg] Latitude of grid center
        x_radius: [deg or m] Distance from lon_0 to edge of grid (i.e., radius)
        y_radius: [deg or m] Distance from lat_0 to edge of grid (i.e., radius)
        spacing: [deg or m] Desired grid spacing
        projected: Boolean controlling whether a latitude/longitude or UTM grid
                   is used. If True, a UTM grid is used and the units of
                   x_radius, y_radius, and spacing are interpreted in meters
                   instead of in degrees (default: False)
        plot_preview: Toggle plotting a preview of the grid for reference and
                      troubleshooting (default: False)
    Returns:
        grid_out: xarray.DataArray object containing the grid coordinates and
                  metadata
    """

    print('-------------')
    print('DEFINING GRID')
    print('-------------')

    # Make coordinate vectors
    if projected:
        x_0, y_0, zone_number, _ = utm.from_latlon(lat_0, lon_0)
    else:
        x_0, y_0, = lon_0, lat_0
    # Using np.linspace() in favor of np.arange() due to precision advantages
    x, dx = np.linspace(x_0 - x_radius,
                        x_0 + x_radius,
                        int(2 * x_radius / spacing) + 1,
                        retstep=True)
    y, dy = np.linspace(y_0 - y_radius,
                        y_0 + y_radius,
                        int(2 * y_radius / spacing) + 1,
                        retstep=True)

    # Basic grid checks
    if dx != spacing:
        warnings.warn(
            f'Requested spacing of {spacing} does not match '
            f'np.linspace()-returned x-axis spacing of {dx}.', RTMWarning)
    if dy != spacing:
        warnings.warn(
            f'Requested spacing of {spacing} does not match '
            f'np.linspace()-returned y-axis spacing of {dy}.', RTMWarning)
    if not (x_0 in x and y_0 in y):
        warnings.warn(
            '(x_0, y_0) is not located in grid. Check for numerical '
            'precision problems (i.e., rounding error).', RTMWarning)
    if projected:
        # Create list of grid corners
        corners = dict(SW=(x.min(), y.min()),
                       NW=(x.min(), y.max()),
                       NE=(x.max(), y.max()),
                       SE=(x.max(), y.min()))
        for label, corner in corners.items():
            # "Un-project" back to latitude/longitude
            lat, lon = utm.to_latlon(*corner,
                                     zone_number,
                                     northern=lat_0 >= 0,
                                     strict=False)
            # "Re-project" to UTM
            _, _, new_zone_number, _ = utm.from_latlon(lat, lon)
            if new_zone_number != zone_number:
                warnings.warn(
                    f'{label} grid corner locates to UTM zone '
                    f'{new_zone_number} instead of origin UTM zone '
                    f'{zone_number}. Consider reducing grid extent '
                    'or using an unprojected grid.', RTMWarning)

    # Create grid
    data = np.full((y.size, x.size), np.nan)  # Initialize an array of NaNs
    # Add grid "metadata"
    attrs = dict(grid_center=(lon_0, lat_0),
                 x_radius=x_radius,
                 y_radius=y_radius,
                 spacing=spacing)
    if projected:
        # Add the projection information to the grid metadata
        attrs['UTM'] = dict(zone=zone_number, southern_hemisphere=lat_0 < 0)
    else:
        attrs['UTM'] = None
    grid_out = DataArray(data, coords=[('y', y), ('x', x)], attrs=attrs)

    print('Done')

    # Plot grid preview, if specified
    if plot_preview:
        print('Generating grid preview plot...')
        if projected:
            proj = ccrs.UTM(**grid_out.UTM)
            transform = proj
        else:
            # This is a good projection to use since it preserves area
            proj = ccrs.AlbersEqualArea(central_longitude=lon_0,
                                        central_latitude=lat_0,
                                        standard_parallels=(y.min(), y.max()))
            transform = ccrs.PlateCarree()

        fig, ax = plt.subplots(figsize=(10, 10),
                               subplot_kw=dict(projection=proj))

        _plot_geographic_context(ax=ax, utm=projected)

        # Note that trial source locations are at the CENTER of each plotted
        # grid box
        grid_out.plot.pcolormesh(ax=ax,
                                 transform=transform,
                                 edgecolor='black',
                                 add_colorbar=False)

        # Plot the center of the grid
        ax.scatter(lon_0,
                   lat_0,
                   s=50,
                   color='limegreen',
                   edgecolor='black',
                   label='Grid center',
                   transform=ccrs.Geodetic())

        # Add a legend
        ax.legend(loc='best')

        fig.canvas.draw()  # Needed to make fig.tight_layout() work
        fig.tight_layout()
        fig.show()

        print('Done')

    return grid_out
from Visualization import *
import cartopy.crs as ccrs
import matplotlib.pyplot as plt

#Figzise
plt.figure(figsize=(10,5))

ax = plt.axes(projection=ccrs.PlateCarree())
ax.coastlines()

#Central warehouses
elc_lon, elc_lat = 10.33, 52.14
alc_lon, alc_lat = -87.63, 41.87
flc_lon, flc_lat = 114.1, 22.4

# Production facilities
mx_lon, mx_lat = -117.04, 32.51
pl_lon, pl_lat = 21.01, 52.23
as_is_lon, as_is_lat = 114.06, 22.54

#Alternative to Geodetic = PlateCarree
#MX 

plt.plot([mx_lon, elc_lon], [mx_lat, elc_lat],
         color='red', linewidth=2, alpha=0.5, marker='o',
         transform=ccrs.Geodetic(),
         )
plt.plot([mx_lon, flc_lon], [mx_lat, flc_lat],
         color='red', linewidth=2, alpha=0.5, marker='o',
         transform=ccrs.Geodetic(),
         )
Example #3
0
import netCDF4
import numpy as np
import cartopy.crs as ccrs
from cartopy.mpl.gridliner import (LONGITUDE_FORMATTER, LATITUDE_FORMATTER)

from typhon.plots.maps import get_cfeatures_at_scale


# Read air temperature data.
with netCDF4.Dataset('_data/test_data.nc') as nc:
    lon, lat = np.meshgrid(nc.variables['lon'][:], nc.variables['lat'][:])
    temp = nc.variables['temp'][:]

# Create plot with PlateCarree projection.
fig = plt.figure(figsize=(10, 8))
ax = fig.add_subplot(111, projection=ccrs.PlateCarree())
ax.set_extent([3, 16, 47, 56])

# Add map "features".
features = get_cfeatures_at_scale(scale='50m')
ax.add_feature(features.BORDERS)
ax.add_feature(features.COASTLINE)
ax.add_feature(features.LAND)
ax.add_feature(features.OCEAN)

# Plot the actual data.
sm = ax.pcolormesh(lon, lat, temp,
                   cmap='temperature',
                   rasterized=True,
                   transform=ccrs.PlateCarree(),
                   )
Example #4
0
ytick = [33.0, 33.5, 34, 34.5, 35, 35.5, 36.0, 36.5]
axesrange = [134.4, 136.7, 33.75, 35.8]

#Plot time mean of the moments.

import matplotlib
import matplotlib.pyplot as plt
import matplotlib.ticker as mticker
import cartopy.crs as ccrs

blues = ['#001a33', '#004d99', '#0073e6', '#3399ff', '#66b3ff', '#b3d9ff']
reds = ['#ffb3b3', '#ff6666', '#ff0000', '#b30000', '#660000', '#1a0000']

fig = plt.figure(1, figsize=[6.5, 5])

ax = fig.add_subplot(111, projection=ccrs.PlateCarree())

#The pcolor
smin = np.nanmin(my_data['topo'])
smax = np.nanmax(my_data['topo'])

p = ax.pcolor(lon,
              lat,
              topo,
              transform=ccrs.PlateCarree(),
              vmin=smin,
              vmax=smax,
              cmap=cpf.cmap_discretize('copper_r', 41))
ax.set_extent(axesrange, ccrs.PlateCarree())

topo[topo > 1.2] = np.nan
def feature():
    unit_circle = sgeom.Point(0, 0).buffer(0.5)
    unit_square = unit_circle.envelope
    geoms = [unit_circle, unit_square]
    feature = ShapelyFeature(geoms, ccrs.PlateCarree())
    return feature
Example #6
0
def plot_em_global_tonnes(u_title, u_file_output, u_data, u_pl):
    #    u_title = ''
    cbar_label = 'kg/' + 'km\u00b2'
    u_res_text = 'Resolution: 1 degree x 1 degree lat-lon'
    u_color = 'jet'  #'YlOrBr' #'hot_r' #'jet'
    fig_w, fig_h = 12, 16
    x_min, x_max, x_step = -180, 181, 60
    y_min, y_max, y_step = -90, 91, 45
    u_pl_min, u_pl_max = 10, 100000

    fig, ax = plt.subplots(1,
                           1,
                           figsize=(fig_w, fig_h),
                           subplot_kw={"projection": ccrs.PlateCarree()})
    u_data_pl = u_data[u_pl].fillna(u_pl_min)
    em = u_data_pl.plot.pcolormesh(ax=ax,
                                   norm=colors.LogNorm(vmin=u_pl_min,
                                                       vmax=u_pl_max),
                                   cmap=u_color,
                                   add_colorbar=False,
                                   xticks=np.arange(x_min, x_max, step=x_step),
                                   yticks=np.arange(y_min, y_max, step=y_step))
    cax = fig.add_axes([
        ax.get_position().x1 + 0.01,
        ax.get_position().y0, 0.02,
        ax.get_position().height
    ])
    cb = plt.colorbar(em, cax=cax, extend='both')
    cb.ax.set_title(cbar_label, fontsize=14, x=1.0, y=1.01)
    cb.ax.tick_params(labelsize=12)
    ax.set_title(u_title, fontweight='regular',
                 fontsize=20)  #'light','normal','regular','semibold','bold'
    ax.set_xlabel("")
    ax.set_ylabel("")
    lon_formatter = LongitudeFormatter()
    lat_formatter = LatitudeFormatter()
    ax.xaxis.set_major_formatter(lon_formatter)
    ax.yaxis.set_major_formatter(lat_formatter)
    ax.tick_params(axis='both', which='major', labelsize=12)
    ax.text(0.9,
            0.025,
            u_res_text,
            horizontalalignment='right',
            verticalalignment='bottom',
            fontsize=12,
            color='white',
            transform=ax.transAxes)
    ax.coastlines(color='whitesmoke')  #'dimgrey','white','whitesmoke'
    plt.savefig(u_file_output + '.svg',
                dpi=150,
                bbox_inches='tight',
                format='svg')
    plt.savefig(u_file_output + '.png',
                dpi=150,
                bbox_inches='tight',
                format='png')
    plt.savefig(u_file_output + '.pdf',
                dpi=150,
                bbox_inches='tight',
                format='pdf')
    plt.savefig(u_file_output + '.eps',
                dpi=150,
                bbox_inches='tight',
                format='eps')

    return
def main():
    config = load_config()

    hazard_cols = ['hazard_type', 'climate_scenario', 'year']
    duration = 10

    hazard_set = [{
        'hazard': 'fluvial flooding',
        'name': 'Fluvial flooding'
    }, {
        'hazard': 'pluvial flooding',
        'name': 'Pluvial flooding'
    }]
    change_colors = [
        '#1a9850', '#66bd63', '#a6d96a', '#d9ef8b', '#fee08b', '#fdae61',
        '#f46d43', '#d73027', '#969696'
    ]
    change_labels = [
        '< -100', '-100 to -50', '-50 to -10', '-10 to 0', '0 to 10',
        '10 to 50', '50 to 100', ' > 100', 'No change/value'
    ]
    change_ranges = [(-1e10, -100), (-100, -50), (-50, -10), (-10, 0),
                     (0.001, 10), (10, 50), (50, 100), (100, 1e10)]

    eael_set = [{
        'column': 'min_eael',
        'title': 'Min EAEL',
        'legend_label': "EAEL (million USD)",
        'divisor': 1000000,
        'significance': 0
    }, {
        'column': 'max_eael',
        'title': 'Max EAEL',
        'legend_label': "EAEL (million USD)",
        'divisor': 1000000,
        'significance': 0
    }]
    data_path = config['paths']['data']

    region_file_path = os.path.join(config['paths']['data'], 'network',
                                    'rail_edges.shp')
    flow_file_path = os.path.join(config['paths']['output'],
                                  'flow_mapping_combined',
                                  'weighted_flows_rail_100_percent.csv')
    region_file = gpd.read_file(region_file_path, encoding='utf-8')
    flow_file = pd.read_csv(flow_file_path)
    region_file = pd.merge(region_file, flow_file, how='left',
                           on=['edge_id']).fillna(0)

    region_file = region_file[region_file['max_total_tons'] > 0]
    del flow_file

    flow_file_path = os.path.join(
        config['paths']['output'], 'failure_results',
        'minmax_combined_scenarios',
        'single_edge_failures_minmax_rail_100_percent_disrupt.csv')
    flow_file = pd.read_csv(flow_file_path)

    flow_file_path = os.path.join(
        config['paths']['output'], 'network_stats',
        'rail_hazard_intersections_risk_weights.csv')

    fail_sc = pd.read_csv(flow_file_path)
    fail_scenarios = pd.merge(fail_sc, flow_file, how='left',
                              on=['edge_id']).fillna(0)
    del flow_file, fail_sc

    fail_scenarios['min_eael'] = duration * fail_scenarios[
        'risk_wt'] * fail_scenarios['min_econ_impact']
    fail_scenarios['max_eael'] = duration * fail_scenarios[
        'risk_wt'] * fail_scenarios['max_econ_impact']
    all_edge_fail_scenarios = fail_scenarios[
        hazard_cols + ['edge_id', 'min_eael', 'max_eael']]
    all_edge_fail_scenarios = all_edge_fail_scenarios.groupby(
        hazard_cols + ['edge_id'])['min_eael', 'max_eael'].max().reset_index()

    # Climate change effects
    all_edge_fail_scenarios = all_edge_fail_scenarios.set_index(
        ['hazard_type', 'edge_id'])
    scenarios = list(set(all_edge_fail_scenarios.index.values.tolist()))
    change_tup = []
    for sc in scenarios:
        eael = all_edge_fail_scenarios.loc[[sc], 'max_eael'].values.tolist()
        yrs = all_edge_fail_scenarios.loc[[sc], 'year'].values.tolist()
        cl = all_edge_fail_scenarios.loc[[sc],
                                         'climate_scenario'].values.tolist()
        if 2016 not in yrs:
            for e in range(len(eael)):
                if eael[e] > 0:
                    # change_tup += list(zip([sc[0]]*len(cl),[sc[1]]*len(cl),cl,yrs,[0]*len(cl),eael,[1e9]*len(cl)))
                    change_tup += [(sc[0], sc[1], cl[e], yrs[e], 0, eael[e],
                                    1e9)]
        elif len(yrs) > 1:
            vals = list(zip(cl, eael, yrs))
            vals = sorted(vals, key=lambda pair: pair[-1])
            change = 100.0 * (np.array([p for (c, p, y) in vals[1:]]) -
                              vals[0][1]) / vals[0][1]
            cl = [c for (c, p, y) in vals[1:]]
            yrs = [y for (c, p, y) in vals[1:]]
            fut = [p for (c, p, y) in vals[1:]]
            change_tup += list(
                zip([sc[0]] * len(cl), [sc[1]] * len(cl), cl, yrs,
                    [vals[0][1]] * len(cl), fut, change))

    change_df = pd.DataFrame(change_tup,
                             columns=[
                                 'hazard_type', 'edge_id', 'climate_scenario',
                                 'year', 'current', 'future', 'change'
                             ]).fillna('inf')
    change_df = change_df[change_df['change'] != 'inf']
    change_df.to_csv(os.path.join(config['paths']['output'], 'network_stats',
                                  'national_rail_eael_climate_change.csv'),
                     index=False)

    # Change effects
    change_df = change_df.set_index(hazard_cols)
    scenarios = list(set(change_df.index.values.tolist()))
    for sc in scenarios:
        hazard_type = sc[0]
        climate_scenario = sc[1]
        year = sc[2]
        percentage = change_df.loc[[sc], 'change'].values.tolist()
        edges = change_df.loc[[sc], 'edge_id'].values.tolist()
        edges_df = pd.DataFrame(list(zip(edges, percentage)),
                                columns=['edge_id', 'change'])
        edges_vals = pd.merge(region_file,
                              edges_df,
                              how='left',
                              on=['edge_id']).fillna(0)
        del percentage, edges, edges_df

        proj_lat_lon = ccrs.PlateCarree()
        ax = get_axes()
        plot_basemap(ax, data_path)
        scale_bar(ax, location=(0.8, 0.05))
        plot_basemap_labels(ax, data_path, include_regions=True)

        name = [c['name'] for c in hazard_set if c['hazard'] == hazard_type][0]
        for record in edges_vals.itertuples():
            geom = record.geometry
            region_val = record.change
            if region_val:
                cl = [
                    c for c in range(len((change_ranges)))
                    if region_val >= change_ranges[c][0]
                    and region_val < change_ranges[c][1]
                ]
                if cl:
                    c = cl[0]
                    ax.add_geometries([geom],
                                      crs=proj_lat_lon,
                                      linewidth=2.0,
                                      edgecolor=change_colors[c],
                                      facecolor='none',
                                      zorder=8)
                    # ax.add_geometries([geom.buffer(0.1)],crs=proj_lat_lon,linewidth=0,facecolor=change_colors[c],edgecolor='none',zorder=8)
            else:
                ax.add_geometries([geom],
                                  crs=proj_lat_lon,
                                  linewidth=1.5,
                                  edgecolor=change_colors[-1],
                                  facecolor='none',
                                  zorder=7)
                # ax.add_geometries([geom.buffer(0.1)], crs=proj_lat_lon, linewidth=0,facecolor=change_colors[-1],edgecolor='none',zorder=7)
        # Legend
        legend_handles = []
        for c in range(len(change_colors)):
            legend_handles.append(
                mpatches.Patch(color=change_colors[c], label=change_labels[c]))

        ax.legend(handles=legend_handles,
                  title='Percentage change in EAEL',
                  loc=(0.55, 0.2),
                  fancybox=True,
                  framealpha=1.0)
        if climate_scenario == 'none':
            climate_scenario = 'current'
        else:
            climate_scenario = climate_scenario.upper()

        title = 'Percentage change in EAEL for {} {} {}'.format(
            name,
            climate_scenario.replace('_', ' ').title(), year)
        print(" * Plotting {}".format(title))

        plt.title(title, fontsize=10)
        output_file = os.path.join(
            config['paths']['figures'],
            'national-rail-{}-{}-{}-risks-change-percentage.png'.format(
                name,
                climate_scenario.replace('-', ' ').title(), year))
        save_fig(output_file)
        plt.close()

    # Absolute effects
    all_edge_fail_scenarios = all_edge_fail_scenarios.reset_index()
    all_edge_fail_scenarios = all_edge_fail_scenarios.set_index(hazard_cols)
    scenarios = list(set(all_edge_fail_scenarios.index.values.tolist()))
    for sc in scenarios:
        hazard_type = sc[0]
        climate_scenario = sc[1]
        if climate_scenario == 'none':
            climate_scenario = 'current'
        else:
            climate_scenario = climate_scenario.upper()
        year = sc[2]
        min_eael = all_edge_fail_scenarios.loc[[sc],
                                               'min_eael'].values.tolist()
        max_eael = all_edge_fail_scenarios.loc[[sc],
                                               'max_eael'].values.tolist()
        edges = all_edge_fail_scenarios.loc[[sc], 'edge_id'].values.tolist()
        edges_df = pd.DataFrame(list(zip(edges, min_eael, max_eael)),
                                columns=['edge_id', 'min_eael', 'max_eael'])
        edges_vals = pd.merge(region_file,
                              edges_df,
                              how='left',
                              on=['edge_id']).fillna(0)
        del edges_df

        for c in range(len(eael_set)):
            proj_lat_lon = ccrs.PlateCarree()
            ax = get_axes()
            plot_basemap(ax, data_path)
            scale_bar(ax, location=(0.8, 0.05))
            plot_basemap_labels(ax, data_path, include_regions=True)

            # generate weight bins
            column = eael_set[c]['column']
            weights = [
                record[column] for iter_, record in edges_vals.iterrows()
            ]

            max_weight = max(weights)
            width_by_range = generate_weight_bins(weights,
                                                  width_step=0.04,
                                                  n_steps=5)

            rail_geoms_by_category = {'1': [], '2': []}

            for iter_, record in edges_vals.iterrows():
                geom = record.geometry
                val = record[column]
                if val == 0:
                    cat = '2'
                else:
                    cat = '1'

                buffered_geom = None
                for (nmin, nmax), width in width_by_range.items():
                    if nmin <= val and val < nmax:
                        buffered_geom = geom.buffer(width)

                if buffered_geom is not None:
                    rail_geoms_by_category[cat].append(buffered_geom)
                else:
                    print("Feature was outside range to plot", iter_)

            styles = OrderedDict([
                ('1',
                 Style(color='#006d2c',
                       zindex=9,
                       label='Hazard failure effect')),  # green
                ('2',
                 Style(color='#969696',
                       zindex=7,
                       label='No hazard exposure/effect'))
            ])

            for cat, geoms in rail_geoms_by_category.items():
                cat_style = styles[cat]
                ax.add_geometries(geoms,
                                  crs=proj_lat_lon,
                                  linewidth=0,
                                  facecolor=cat_style.color,
                                  edgecolor='none',
                                  zorder=cat_style.zindex)
            name = [
                h['name'] for h in hazard_set if h['hazard'] == hazard_type
            ][0]

            x_l = -62.4
            x_r = x_l + 0.4
            base_y = -42.1
            y_step = 0.8
            y_text_nudge = 0.2
            x_text_nudge = 0.2

            ax.text(x_l,
                    base_y + y_step - y_text_nudge,
                    eael_set[c]['legend_label'],
                    horizontalalignment='left',
                    transform=proj_lat_lon,
                    size=10)

            divisor = eael_set[c]['divisor']
            significance_ndigits = eael_set[c]['significance']
            max_sig = []
            for (i, ((nmin, nmax),
                     line_style)) in enumerate(width_by_range.items()):
                if round(nmin / divisor, significance_ndigits) < round(
                        nmax / divisor, significance_ndigits):
                    max_sig.append(significance_ndigits)
                elif round(nmin / divisor, significance_ndigits + 1) < round(
                        nmax / divisor, significance_ndigits + 1):
                    max_sig.append(significance_ndigits + 1)
                elif round(nmin / divisor, significance_ndigits + 2) < round(
                        nmax / divisor, significance_ndigits + 2):
                    max_sig.append(significance_ndigits + 2)
                else:
                    max_sig.append(significance_ndigits + 3)

            significance_ndigits = max(max_sig)
            for (i, ((nmin, nmax),
                     width)) in enumerate(width_by_range.items()):
                y = base_y - (i * y_step)
                line = LineString([(x_l, y), (x_r, y)]).buffer(width)
                ax.add_geometries([line],
                                  crs=proj_lat_lon,
                                  linewidth=0,
                                  edgecolor='#000000',
                                  facecolor='#000000',
                                  zorder=2)
                if nmin == max_weight:
                    value_template = '>{:.' + str(significance_ndigits) + 'f}'
                    label = value_template.format(
                        round(max_weight / divisor, significance_ndigits))
                else:
                    value_template = '{:.' + str(significance_ndigits) + \
                        'f}-{:.' + str(significance_ndigits) + 'f}'
                    label = value_template.format(
                        round(nmin / divisor, significance_ndigits),
                        round(nmax / divisor, significance_ndigits))

                ax.text(x_r + x_text_nudge,
                        y - y_text_nudge,
                        label,
                        horizontalalignment='left',
                        transform=proj_lat_lon,
                        size=10)

            if climate_scenario == 'none':
                climate_scenario = 'Current'

            climate_scenario = climate_scenario.replace('_', ' ')
            title = 'Railways ({}) {} {} {}'.format(eael_set[c]['title'], name,
                                                    climate_scenario.title(),
                                                    year)
            print('* Plotting ', title)

            plt.title(title, fontsize=12)
            legend_from_style_spec(ax, styles, loc='lower left')

            # output
            output_file = os.path.join(
                config['paths']['figures'],
                'national-rail-{}-{}-{}-{}.png'.format(
                    name.replace(' ', ''), climate_scenario.replace('.', ''),
                    year, eael_set[c]['column']))
            save_fig(output_file)
            plt.close()
Example #8
0
def project_extents(extents, src_proj, dest_proj, tol=1e-6):
    x1, y1, x2, y2 = extents

    if (isinstance(src_proj, ccrs.PlateCarree) and
        not isinstance(dest_proj, ccrs.PlateCarree) and
        src_proj.proj4_params['lon_0'] != 0):
        xoffset = src_proj.proj4_params['lon_0']
        x1 = x1 - xoffset
        x2 = x2 - xoffset
        src_proj = ccrs.PlateCarree()

    # Limit latitudes
    cy1, cy2 = src_proj.y_limits
    if y1 < cy1: y1 = cy1
    if y2 > cy2:  y2 = cy2

    # Offset with tolerances
    x1 += tol
    x2 -= tol
    y1 += tol
    y2 -= tol

    # Wrap longitudes
    cx1, cx2 = src_proj.x_limits
    if isinstance(src_proj, ccrs._CylindricalProjection):
        lons = wrap_lons(np.linspace(x1, x2, 10000), -180., 360.)
        x1, x2 = lons.min(), lons.max()
    else:
        if x1 < cx1: x1 = cx1
        if x2 > cx2: x2 = cx2

    domain_in_src_proj = Polygon([[x1, y1], [x2, y1],
                                  [x2, y2], [x1, y2],
                                  [x1, y1]])
    boundary_poly = Polygon(src_proj.boundary)
    dest_poly = src_proj.project_geometry(Polygon(dest_proj.boundary), dest_proj).buffer(0)
    if src_proj != dest_proj:
        # Erode boundary by threshold to avoid transform issues.
        # This is a workaround for numerical issues at the boundary.
        eroded_boundary = boundary_poly.buffer(-src_proj.threshold)
        geom_in_src_proj = eroded_boundary.intersection(
            domain_in_src_proj)
        try:
            geom_clipped_to_dest_proj = dest_poly.intersection(
                geom_in_src_proj)
        except:
            geom_clipped_to_dest_proj = None
        if geom_clipped_to_dest_proj:
            geom_in_src_proj = geom_clipped_to_dest_proj
        try:
            geom_in_crs = dest_proj.project_geometry(geom_in_src_proj, src_proj)
        except ValueError:
            src_name =type(src_proj).__name__
            dest_name =type(dest_proj).__name__
            raise ValueError('Could not project data from %s projection '
                             'to %s projection. Ensure the coordinate '
                             'reference system (crs) matches your data '
                             'and the kdims.' %
                             (src_name, dest_name))
    else:
        geom_in_crs = boundary_poly.intersection(domain_in_src_proj)
    return geom_in_crs.bounds
Example #9
0
def plot_map(ds: xr.Dataset,
             var: VarName.TYPE = None,
             index: DictLike.TYPE = None,
             time: Union[str, int] = None,
             region: PolygonLike.TYPE = None,
             projection: str = 'PlateCarree',
             central_lon: float = 0.0,
             file: str = None) -> None:
    """
    Plot the given variable from the given dataset on a map with coastal lines.
    In case no variable name is given, the first encountered variable in the
    dataset is plotted. In case no time index is given, the first time slice
    is taken. It is also possible to set extents of the plot. If no extents
    are given, a global plot is created.

    The plot can either be shown using pyplot functionality, or saved,
    if a path is given. The following file formats for saving the plot
    are supported: eps, jpeg, jpg, pdf, pgf, png, ps, raw, rgba, svg,
    svgz, tif, tiff

    :param ds: xr.Dataset to plot
    :param var: variable name in the dataset to plot
    :param index: Optional index into the variable's data array. The *index* is a dictionary
                  that maps the variable's dimension names to constant labels. For example,
                  ``lat`` and ``lon`` are given in decimal degrees, while a ``time`` value may be provided as
                  datetime object or a date string. *index* may also be a comma-separated string of key-value pairs,
                  e.g. "lat=12.4, time='2012-05-02'".
    :param time: time slice index to plot
    :param region: Region to plot
    :param projection: name of a global projection, see http://scitools.org.uk/cartopy/docs/v0.15/crs/projections.html
    :param central_lon: central longitude of the projection in degrees
    :param file: path to a file in which to save the plot
    """
    if not isinstance(ds, xr.Dataset):
        raise NotImplementedError('Only raster datasets are currently '
                                  'supported')

    var_name = None
    if not var:
        for key in ds.data_vars.keys():
            var_name = key
            break
    else:
        var_name = VarName.convert(var)

    var = ds[var_name]
    index = DictLike.convert(index)

    # 0 is a valid index, hence test if time is None
    if time is not None and isinstance(time, int) and 'time' in var.coords:
        time = var.coords['time'][time]

    if time:
        if not index:
            index = dict()
        index['time'] = time

    for dim_name in var.dims:
        if dim_name not in ('lat', 'lon'):
            if not index:
                index = dict()
            if dim_name not in index:
                index[dim_name] = 0

    if region is None:
        lat_min = -90.0
        lat_max = 90.0
        lon_min = -180.0
        lon_max = 180.0
    else:
        region = PolygonLike.convert(region)
        lon_min, lat_min, lon_max, lat_max = region.bounds

    if not _check_bounding_box(lat_min, lat_max, lon_min, lon_max):
        raise ValueError(
            'Provided plot extents do not form a valid bounding box '
            'within [-180.0,+180.0,-90.0,+90.0]')
    extents = [lon_min, lon_max, lat_min, lat_max]

    # See http://scitools.org.uk/cartopy/docs/v0.15/crs/projections.html#
    if projection == 'PlateCarree':
        proj = ccrs.PlateCarree(central_longitude=central_lon)
    elif projection == 'LambertCylindrical':
        proj = ccrs.LambertCylindrical(central_longitude=central_lon)
    elif projection == 'Mercator':
        proj = ccrs.Mercator(central_longitude=central_lon)
    elif projection == 'Miller':
        proj = ccrs.Miller(central_longitude=central_lon)
    elif projection == 'Mollweide':
        proj = ccrs.Mollweide(central_longitude=central_lon)
    elif projection == 'Orthographic':
        proj = ccrs.Orthographic(central_longitude=central_lon)
    elif projection == 'Robinson':
        proj = ccrs.Robinson(central_longitude=central_lon)
    elif projection == 'Sinusoidal':
        proj = ccrs.Sinusoidal(central_longitude=central_lon)
    elif projection == 'NorthPolarStereo':
        proj = ccrs.NorthPolarStereo(central_longitude=central_lon)
    elif projection == 'SouthPolarStereo':
        proj = ccrs.SouthPolarStereo(central_longitude=central_lon)
    else:
        raise ValueError('illegal projection')

    try:
        if index:
            var_data = var.sel(**index)
        else:
            var_data = var
    except ValueError:
        var_data = var

    fig = plt.figure(figsize=(16, 8))
    ax = plt.axes(projection=proj)
    if extents:
        ax.set_extent(extents)
    else:
        ax.set_global()

    ax.coastlines()
    var_data.plot.contourf(ax=ax, transform=proj)
    if file:
        fig.savefig(file)
Example #10
0
nlayers = 20

MAP_COLOR_LIMS = {'ec550dryaer': [0, 1000]}

if var in MAP_COLOR_LIMS:
    map_vmin, map_vmax = MAP_COLOR_LIMS[var]
else:
    map_vmin, map_vmax = vardef.map_vmin, vardef.map_vmax

if any([x is None for x in [map_vmin, map_vmax]]):
    raise ValueError

cm = plt.cm.get_cmap('Reds', nlayers)
levels = np.linspace(map_vmin, map_vmax, nlayers)

proj = ccrs.PlateCarree()
ax = plt.axes(projection=proj)

csf = {}

if not data.check_dimcoords_tseries():
    data.reorder_dimensions_tseries()

nparr = data.cube.data
lats = data.latitude.points
lons = data.longitude.points

geojson = {}

for i, month in enumerate(data.time_stamps()):
    date = str(month).split('T')[0]
Example #11
0
def plot_panel(n,
               fig,
               proj,
               pole,
               var,
               clevels,
               cmap,
               title,
               parameters,
               stats=None):

    var = add_cyclic(var)
    lon = var.getLongitude()
    lat = var.getLatitude()
    var = ma.squeeze(var.asma())

    # Contour levels
    levels = None
    norm = None
    if len(clevels) > 0:
        levels = [-1.0e8] + clevels + [1.0e8]
        norm = colors.BoundaryNorm(boundaries=levels, ncolors=256)

    # Contour plot
    ax = fig.add_axes(panel[n], projection=proj)
    ax.set_global()

    ax.gridlines()
    if pole == 'N':
        ax.set_extent([-180, 180, 50, 90], crs=ccrs.PlateCarree())
    elif pole == 'S':
        ax.set_extent([-180, 180, -55, -90], crs=ccrs.PlateCarree())

    cmap = get_colormap(cmap, parameters)
    p1 = ax.contourf(
        lon,
        lat,
        var,
        transform=ccrs.PlateCarree(),
        norm=norm,
        levels=levels,
        cmap=cmap,
        extend='both',
    )
    ax.set_aspect('auto')
    ax.coastlines(lw=0.3)

    theta = np.linspace(0, 2 * np.pi, 100)
    center, radius = [0.5, 0.5], 0.5
    verts = np.vstack([np.sin(theta), np.cos(theta)]).T
    circle = mpath.Path(verts * radius + center)
    ax.set_boundary(circle, transform=ax.transAxes)

    # Plot titles
    for i in range(3):
        if title[i] == None: title[i] = ''

    t = ax.set_title('%s\n%s' % (title[0], title[2]),
                     loc='left',
                     fontdict=plotSideTitle)

    t = ax.set_title(title[1], fontdict=plotTitle)
    if title[0] != '' or title[2] != '': t.set_position([.5, 1.06])

    # Color bar
    cbax = fig.add_axes(
        (panel[n][0] + 0.35, panel[n][1] + 0.0354, 0.0326, 0.1792))
    cbar = fig.colorbar(p1, cax=cbax)
    w, h = get_ax_size(fig, cbax)

    if levels == None:
        cbar.ax.tick_params(labelsize=9.0, length=0)

    else:
        maxval = np.amax(np.absolute(levels[1:-1]))
        if maxval < 10.0:
            fmt = "%5.2f"
            pad = 25
        elif maxval < 100.0:
            fmt = "%5.1f"
            pad = 25
        else:
            fmt = "%6.1f"
            pad = 30
        cbar.set_ticks(levels[1:-1])
        labels = [fmt % l for l in levels[1:-1]]
        cbar.ax.set_yticklabels(labels, ha='right')
        cbar.ax.tick_params(labelsize=9.0, pad=pad, length=0)

    # Min, Mean, Max
    fig.text(panel[n][0] + 0.35,
             panel[n][1] + 0.225,
             "Max\nMean\nMin",
             ha='left',
             fontdict=plotSideTitle)
    fig.text(panel[n][0] + 0.45,
             panel[n][1] + 0.225,
             "%.2f\n%.2f\n%.2f" % stats[0:3],
             ha='right',
             fontdict=plotSideTitle)

    # RMSE, CORR
    if len(stats) == 5:
        fig.text(panel[n][0] + 0.35,
                 panel[n][1] + 0.,
                 "RMSE\nCORR",
                 ha='left',
                 fontdict=plotSideTitle)
        fig.text(panel[n][0] + 0.45,
                 panel[n][1] + 0.,
                 "%.2f\n%.2f" % stats[3:5],
                 ha='right',
                 fontdict=plotSideTitle)
Example #12
0
'''
This dataset is for rainfall satellite estimations from the PERSIANN platform
only for the Amazon Basin area.

You can easily select the area and download the data at the Portal: https://chrsdata.eng.uci.edu/
The shapefile for the Basin comes with the data.
'''

dset = xr.open_dataset('CDR_amazonbasin.nc')
# masking undefined values outside the basin area
dset['precip'] = dset['precip'].where(dset['precip'] != -99.)
# seasonal cycle
season = dset['precip'].groupby('datetime.season').mean('datetime')

basin = 'amazon_shape.shp' # shapefile
proj  =  ccrs.PlateCarree() # cartopy projection

f, ax = plot.subplots(axwidth=3.5, nrows=2, ncols=2, tight=True, proj='pcarree',
                      proj_kw={'lon_0':180},)

ax.format(land=False, coast=True, innerborders=True, borders=True, grid=False,
          geogridlinewidth=0, labels=True,
          latlim=(-21, 12), lonlim=(275, 315),
          latlines=plot.arange(-20, 10, 5), lonlines=plot.arange(-95, -20, 5),
          large='15px')

map1 = ax[0,0].contourf(dset['lon'], dset['lat'], season[0,:,:],
                     cmap='BuPu', levels=np.arange(50, 500, 50), extend='both')
map2 = ax[0,1].contourf(dset['lon'], dset['lat'], season[2,:,:],
                     cmap='BuPu', levels=np.arange(50, 500, 50), extend='both')
map3 = ax[1,0].contourf(dset['lon'], dset['lat'], season[1,:,:],
Example #13
0
Months[:] = np.NaN
for i in np.arange(len(Months)):
    #Months[i]=int(str(AllData.iloc[i,2])[5:7])
    Months[i] = int(str(O2invData.iloc[i, 3])[5:7])

O2invData['Month'] = Months

lon = O2invData.loc[:, 'Lon']
lat = O2invData.loc[:, 'Lat']
O2inv = O2invData.loc[:, 'O2Inv']
O2eqinv = O2invData.loc[:, 'O2EqInv']
DiffInv = O2inv - O2eqinv
O2invData['DiffEq'] = DiffInv

fig, axs = plt.subplots(1, 1, figsize=(10, 6))
ax = plt.subplot(1, 1, 1, projection=ccrs.PlateCarree())
ax.coastlines('50m')
ax.set_extent([lab_W, lab_E, lab_S, lab_N], ccrs.PlateCarree())
cm_cbr = ax.scatter(lon,
                    lat,
                    c=O2inv,
                    vmin=minval,
                    vmax=maxval,
                    marker='o',
                    s=2,
                    cmap=cmap_choice)  #cmo.balance
ax.set_title('Total Oxygen Inventory (mol/m2)')
fig.colorbar(cm_cbr)
plt.savefig(FigDir + 'Map_Inventory_Total.jpg')
plt.close()
Example #14
0
except ImportError:
    WebMapService = None
    WebFeatureService = None
    _OWSLIB_AVAILABLE = False

import cartopy.crs as ccrs
from cartopy.io import LocatedImage, RasterSource
from cartopy.img_transform import warp_array


_OWSLIB_REQUIRED = 'OWSLib is required to use OGC web services.'

# Hardcode some known EPSG codes for now.
# The order given here determines the preferred SRS for WMS retrievals.
_CRS_TO_OGC_SRS = collections.OrderedDict(
    [(ccrs.PlateCarree(), 'EPSG:4326'),
     (ccrs.GOOGLE_MERCATOR, 'EPSG:900913')])

# Standard pixel size of 0.28 mm as defined by WMTS.
METERS_PER_PIXEL = 0.28e-3

_WGS84_METERS_PER_UNIT = 2 * math.pi * 6378137 / 360

METERS_PER_UNIT = {
    'urn:ogc:def:crs:EPSG::27700': 1,
    'urn:ogc:def:crs:EPSG::900913': 1,
    'urn:ogc:def:crs:OGC:1.3:CRS84': _WGS84_METERS_PER_UNIT,
}

_URN_TO_CRS = {
    'urn:ogc:def:crs:EPSG::27700': ccrs.OSGB(),
Example #15
0
def plot_data(pwrf, pgrid, gridded_data, lon_pts, lat_pts):
    """plot_data: Plot the data

    Input:
        pwrf -- (class) ModelData
        pgrid -- class AnalysisGrid
        gridded_data -- (masked-array) frontal strength values
        lon_pts -- (list) Longitude points of front
        lat_pts -- (list) Latitude points of front
    Output:
        Optional: Save Figure
        None
    """
    ## Get/Store WPS Data - recreate the domain
    wps = wps_info(pwrf.wpsfile)

    ## SET UP PLOT
    fig1 = plt.figure(figsize=[8, 8], dpi=100)
    ax1 = plt.axes(projection=wps.calc_wps_domain_info()[0]) #wpsproj - namelist.wps

    ax1.set_title("WRFv4 "+ pwrf.version +" Frontal Strength\nTime: "+\
                  pwrf.wrf_dt[pwrf.time_idx].strftime("%Y-%m-%d %H:%M")+"Z",\
                  size=20)

    #Plot the front threshold data (after it's been cleaned)
    plt1 = plt.pcolormesh(pwrf.lons[pgrid.south_start:pgrid.north_end,\
                                  pgrid.west_start:pgrid.east_end-pgrid.gradient_distance],\
                        pwrf.lats[pgrid.south_start:pgrid.north_end,\
                                  pgrid.west_start:pgrid.east_end-pgrid.gradient_distance],\
                        gridded_data[pgrid.south_start:pgrid.north_end,\
                                     pgrid.west_start:pgrid.east_end-pgrid.gradient_distance],\
                        cmap='jet', vmin=pgrid.threshold, vmax=3, transform=ccrs.PlateCarree())

    plt1.cmap.set_under("white")

    #plot the front points
    for ijk in range(len(lon_pts)):
        ax1.plot(lon_pts[ijk], lat_pts[ijk], 'rp', markersize=4, transform=ccrs.PlateCarree())

    #Add map layers for counties/states/coastlines/etc.
    try:
        reader = shpreader.Reader(os.getcwd()+'/countyl010g_shp_nt00964/countyl010g.shp')
        counties = list(reader.geometries())
        obj_counties = cfeature.ShapelyFeature(counties, ccrs.PlateCarree())
        ax1.add_feature(obj_counties, facecolor='none', edgecolor='darkslategray')
    except ImportError:
        ax1.add_feature(cartopy.feature.STATES.with_scale('10m'),\
                          edgecolor='darkslategray', linewidth=1)
        ax1.coastlines('10m', 'darkslategray', linewidth=1)

    # Set/Add colorbar
    cbar_ax = fig1.add_axes([0, 0, 0.1, 0.1])
    posn = ax1.get_position()
    cbar_ax.set_position([posn.x0 + posn.width + 0.01, posn.y0, 0.04, posn.height])
    plt.colorbar(plt1, cax=cbar_ax, extend='min')

    if pwrf.save:
        plt.savefig(pwrf.mappath+"/Frontal_Strength_Analysis_"+\
                    pwrf.wrf_dt[pwrf.time_idx].strftime("%Y_%m_%d_%H%M")+\
                    "_"+pwrf.version+".png", transparent=True, dpi=600)
    else:
        plt.show()

    plt.close()
Example #16
0
def plot_diff(slice1, title, lim1, lim2, step):
    #plt.figure()
    plt.figure(figsize=(12, 6))  # this works
    #plt.figure(figsize=(12, 4.8))# this works
    data = slice1.data
    lon = slice1.coord('longitude').points
    lat = slice1.coord('latitude').points
    new_lon = []
    for k in range(len(lon)):
        if lon[k] > 180:
            #temp=lon[k]
            temp = lon[k] - 360
            new_lon = np.append(new_lon, temp)
        else:
            new_lon = np.append(new_lon, lon[k])
    #lon=lon-180    #basemap correction
    #new_lon=temp

#..............basemap requires lat and lon to be in increasing order

    data_1 = data[:, 0:96]
    data_2 = data[:, 96:]
    data_21 = np.hstack((data_2, data_1))

    new_lon_1 = new_lon[0:96]
    new_lon_2 = new_lon[96:]
    new_lon_21 = np.hstack((new_lon_2, new_lon_1))

    data_final = data_21
    new_lon_final = new_lon_21

    ticks = np.arange(lim1, lim2, step)
    ticks6 = [1e0, 1e3, 1e5, 1e8, 1e10]
    ticks6_label = ['1e0', '1e3', '1e5', '1e8', '1e10']
    ticks6 = [1e-2, 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9]
    ticks6_label = [
        '-1e2', '1e0', '1e1', '1e2', '1e3', '1e4', '1e5', '1e6', '1e7', '1e8',
        '1e9'
    ]
    ticks6 = [1e-33, 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9]
    ticks6_label = [
        '-1e2', '1e0', '1e1', '1e2', '1e3', '1e4', '1e5', '1e6', '1e7', '1e8',
        '1e9'
    ]
    ticks6 = [1e-35, 1e-30, 1e-25, 1e-20, 1e-15]
    ticks6_label = ['1e-35', '1e-30', '1e-25', '1e-20', '1e-15']
    ticks6 = [1e-35, 1e-32, 1e-29, 1e-26, 1e-23, 1e-20, 1e-17, 1e-14]
    ticks6_label = [
        '1e-35', '1e-32', '1e-29', '1e-26', '1e-23', '1e-20', '1e-17', '1e-14'
    ]

    ticks6 = [1e-20, 1e-8, 1e-7, 1e-6, 1e-5, 1e-4, 1e-3, 1e-2, 1e-1, 1e0]

    ticks6 = [1e-20, 1e-8, 1e-7, 1e-6, 1e-5, 1e-4, 1e-3, 1e-2, 1e-1, 1e0]
    ticks6 = [-300, -250, -200, -150, -100, -50, 0,
              50]  # this is a percentage change plot
    ticks6 = [-100, -90, -80, -70, -60, -50, -40, -30, -20, -10,
              0]  # this is a percentage change plot
    ticks6_label = [str(o) for o in ticks6]
    #ticks6_label = ['1e-35','1e-32','1e-29','1e-26','1e-23','1e-20','1e-17','1e-14']
    #ticks6_label = ['1e-35','1e-30','1e-25','1e-20','1e-15']
    #ticks6_label = ['-1e2','1e0','1e1','1e2','1e3','1e4','1e5','1e6','1e7','1e8','1e9']
    # ticks6 = [-1e-22,1e-30,1e-16]
    # ticks6_label = ['-1e-22','1e-30','1e-16']

    ax = plt.axes(projection=ccrs.PlateCarree())
    #data_final = np.where(data_final>1.0,data_final,1e-1)
    #x=plt.contourf(new_lon_final,lat,data_final,transform=ccrs.PlateCarree(),cmap='RdYlBu_r',levels=ticks)
    #x=plt.contourf(new_lon_final,lat,data_final,norm=colors.LogNorm(vmin=1e-8,vmax=1e0),transform=ccrs.PlateCarree(),cmap='RdYlBu_r',levels=ticks6)
    x = plt.contourf(new_lon_final,
                     lat,
                     data_final,
                     vmin=-100,
                     vmax=0,
                     transform=ccrs.PlateCarree(),
                     cmap='RdGy',
                     levels=ticks6)
    #x=plt.contourf(new_lon_final,lat,data_final,norm=colors.LogNorm(vmin=pow(10,-35),vmax=1e-15),transform=ccrs.PlateCarree(),cmap='RdYlBu_r',levels=ticks6)
    norm = mpl.colors.Normalize(vmin=lim1, vmax=lim2)
    #plt.title(title,fontdict={'fontsize':16})

    plt.title(title, fontsize=12)

    ax.coastlines()

    gl = ax.gridlines(crs=ccrs.PlateCarree(),
                      draw_labels=True,
                      linewidth=2,
                      color='black',
                      alpha=0.5,
                      linestyle='--')
    gl.xlabels_top = False
    gl.ylabels_right = False
    #gl.xlines = False
    gl.xlocator = mticker.FixedLocator([-180, -90, 0, 90, 180])
    gl.ylocator = mticker.FixedLocator([-90, -45, 0, 45, 90])
    gl.xformatter = LONGITUDE_FORMATTER
    gl.yformatter = LATITUDE_FORMATTER
    gl.xlabel_style = {'size': 15, 'color': 'gray'}
    gl.xlabel_style = {'color': 'black', 'weight': 'bold'}

    gl.ylabel_style = {'size': 15, 'color': 'gray'}
    gl.ylabel_style = {'color': 'black', 'weight': 'bold'}
    """
    cbar=plt.colorbar(x,ax=ax,ticks=ticks)
    cbar.ax.tick_params(labelsize=16)
    ax.set_aspect('auto')
    plt.savefig(title+'.png')
   
    """
    cbar = plt.colorbar(x, ax=ax)
    cbar.set_ticks(ticks6)
    cbar.set_ticklabels(ticks6_label)
    cbar.ax.tick_params(labelsize=16)
    ax.set_aspect('auto')
Example #17
0
    _OWSLIB_AVAILABLE = True
except ImportError:
    WebMapService = None
    WebFeatureService = None
    _OWSLIB_AVAILABLE = False

import cartopy.crs as ccrs
from cartopy.io import LocatedImage, RasterSource
from cartopy.img_transform import warp_array

_OWSLIB_REQUIRED = 'OWSLib is required to use OGC web services.'

# Hardcode some known EPSG codes for now.
# The order given here determines the preferred SRS for WMS retrievals.
_CRS_TO_OGC_SRS = collections.OrderedDict([
    (ccrs.PlateCarree(), 'EPSG:4326'), (ccrs.Mercator.GOOGLE, 'EPSG:900913'),
    (ccrs.OSGB(approx=True), 'EPSG:27700')
])

# Standard pixel size of 0.28 mm as defined by WMTS.
METERS_PER_PIXEL = 0.28e-3

_WGS84_METERS_PER_UNIT = 2 * math.pi * 6378137 / 360

METERS_PER_UNIT = {
    'urn:ogc:def:crs:EPSG::27700': 1,
    'urn:ogc:def:crs:EPSG::900913': 1,
    'urn:ogc:def:crs:OGC:1.3:CRS84': _WGS84_METERS_PER_UNIT,
    'urn:ogc:def:crs:EPSG::3031': 1,
    'urn:ogc:def:crs:EPSG::3413': 1,
    'urn:ogc:def:crs:EPSG::3857': 1,
Example #18
0
                        region=region,
                        spacing=spacing)
grid = chain.grid(
    region=region,
    spacing=spacing,
    projection=projection,
    dims=["latitude", "longitude"],
    data_names=["velocity"],
)
grid = grid.where(mask)

fig, axes = plt.subplots(1,
                         2,
                         figsize=(9, 7),
                         subplot_kw=dict(projection=ccrs.Mercator()))
crs = ccrs.PlateCarree()
# Plot the data uncertainties
ax = axes[0]
ax.set_title("Data uncertainty")
# Plot the uncertainties in mm/yr and using a power law for the color scale to highlight
# the smaller values
pc = ax.scatter(*coordinates,
                c=data.std_up * 1000,
                s=20,
                cmap="magma",
                transform=crs,
                norm=PowerNorm(gamma=1 / 2))
cb = plt.colorbar(pc, ax=ax, orientation="horizontal", pad=0.05)
cb.set_label("uncertainty [mm/yr]")
vd.datasets.setup_california_gps_map(ax)
# Plot the gridded velocities
Example #19
0
def main():
    config = load_config()
    data_path = config['paths']['data']
    mode_file_path = os.path.join(config['paths']['data'], 'network',
                                  'road_edges.shp')
    flow_file_path = os.path.join(config['paths']['output'],
                                  'flow_mapping_combined',
                                  'weighted_flows_road_100_percent.csv')

    mode_file = gpd.read_file(mode_file_path, encoding='utf-8')
    flow_file = pd.read_csv(flow_file_path)
    mode_file = pd.merge(mode_file, flow_file, how='left',
                         on=['edge_id']).fillna(0)
    mode_file = mode_file[(mode_file['road_type'] == 'national') |
                          (mode_file['road_type'] == 'province') |
                          (mode_file['road_type'] == 'rural')]

    plot_sets = [
        {
            'file_tag': 'tmda',
            'legend_label': "AADT ('000 vehicles/day)",
            'divisor': 1000,
            'columns': ['tmda_count'],
            'title_cols': ['Vehicle Count'],
            'significance': 0
        },
        {
            'file_tag':
            'commodities',
            'legend_label':
            "AADF ('000 tons/day)",
            'divisor':
            1000,
            'columns': [
                'max_{}'.format(x) for x in [
                    'total_tons',
                    'AGRICULTURA, GANADERÍA, CAZA Y SILVICULTURA', 'Carnes',
                    'Combustibles', 'EXPLOTACIÓN DE MINAS Y CANTERAS',
                    'Granos', 'INDUSTRIA MANUFACTURERA', 'Industrializados',
                    'Mineria', 'PESCA', 'Regionales', 'Semiterminados'
                ]
            ],
            'title_cols': [
                'Total tonnage', 'AGRICULTURA, GANADERÍA, CAZA Y SILVICULTURA',
                'Carnes', 'Combustibles', 'EXPLOTACIÓN DE MINAS Y CANTERAS',
                'Granos', 'INDUSTRIA MANUFACTURERA', 'Industrializados',
                'Mineria', 'PESCA', 'Regionales', 'Semiterminados'
            ],
            'significance':
            0
        },
    ]

    for plot_set in plot_sets:
        for c in range(len(plot_set['columns'])):
            # basemap
            proj_lat_lon = ccrs.PlateCarree()
            ax = get_axes()
            plot_basemap(ax, data_path)
            scale_bar(ax, location=(0.8, 0.05))
            plot_basemap_labels(ax, data_path, include_regions=False)

            # generate weight bins
            if plot_set['columns'][c] == 'tmda':
                column = plot_set['columns'][c]
                weights = [
                    int(str(record[column]))
                    for iter_, record in mode_file.iterrows()
                    if str(record[column]).isdigit() is True
                    and int(str(record[column])) > 0
                ]
                max_weight = max(weights)
                width_by_range = generate_weight_bins(weights,
                                                      n_steps=7,
                                                      width_step=0.02)
                # width_by_range = generate_weight_bins(weights, n_steps=9, width_step=0.01, interpolation='log')
            else:
                column = 'max_total_tons'
                weights = [
                    record[column] for iter_, record in mode_file.iterrows()
                ]
                max_weight = max(weights)
                width_by_range = generate_weight_bins(weights,
                                                      n_steps=7,
                                                      width_step=0.02)

            road_geoms_by_category = {
                'national': [],
                'province': [],
                'rural': [],
            }

            column = plot_set['columns'][c]
            for iter_, record in mode_file.iterrows():
                if column == 'tmda':
                    if str(record[column]).isdigit() is False:
                        val = 0
                    else:
                        val = int(str(record[column]))
                else:
                    val = record[column]

                if val > 0:
                    cat = str(record['road_type']).lower().strip()
                    if cat not in road_geoms_by_category:
                        raise Exception
                    geom = record.geometry

                    buffered_geom = None
                    for (nmin, nmax), width in width_by_range.items():
                        if nmin <= val and val < nmax:
                            buffered_geom = geom.buffer(width)

                    if buffered_geom is not None:
                        road_geoms_by_category[cat].append(buffered_geom)
                    else:
                        print("Feature was outside range to plot", iter_)

            styles = OrderedDict([
                ('national', Style(color='#e41a1c', zindex=9,
                                   label='National')),  # red
                ('province',
                 Style(color='#377eb8', zindex=8,
                       label='Provincial')),  # orange
                ('rural', Style(color='#4daf4a', zindex=7,
                                label='Rural')),  # blue
            ])

            for cat, geoms in road_geoms_by_category.items():
                cat_style = styles[cat]
                ax.add_geometries(geoms,
                                  crs=proj_lat_lon,
                                  linewidth=0,
                                  facecolor=cat_style.color,
                                  edgecolor='none',
                                  zorder=cat_style.zindex)

            x_l = -62.4
            x_r = x_l + 0.4
            base_y = -42.1
            y_step = 0.8
            y_text_nudge = 0.2
            x_text_nudge = 0.2

            ax.text(x_l,
                    base_y + y_step - y_text_nudge,
                    plot_set['legend_label'],
                    horizontalalignment='left',
                    transform=proj_lat_lon,
                    size=10)

            divisor = plot_set['divisor']
            significance_ndigits = plot_set['significance']
            max_sig = []
            for (i, ((nmin, nmax),
                     line_style)) in enumerate(width_by_range.items()):
                if round(nmin / divisor, significance_ndigits) < round(
                        nmax / divisor, significance_ndigits):
                    max_sig.append(significance_ndigits)
                elif round(nmin / divisor, significance_ndigits + 1) < round(
                        nmax / divisor, significance_ndigits + 1):
                    max_sig.append(significance_ndigits + 1)
                elif round(nmin / divisor, significance_ndigits + 2) < round(
                        nmax / divisor, significance_ndigits + 2):
                    max_sig.append(significance_ndigits + 2)
                else:
                    max_sig.append(significance_ndigits + 3)

            significance_ndigits = max(max_sig)

            for (i, ((nmin, nmax),
                     width)) in enumerate(width_by_range.items()):
                y = base_y - (i * y_step)
                line = LineString([(x_l, y), (x_r, y)]).buffer(width)
                ax.add_geometries([line],
                                  crs=proj_lat_lon,
                                  linewidth=0,
                                  edgecolor='#000000',
                                  facecolor='#000000',
                                  zorder=2)
                if nmin == max_weight:
                    value_template = '>{:.' + str(significance_ndigits) + 'f}'
                    label = value_template.format(
                        round(max_weight / divisor, significance_ndigits))
                else:
                    value_template = '{:.' + str(significance_ndigits) + \
                        'f}-{:.' + str(significance_ndigits) + 'f}'
                    label = value_template.format(
                        round(nmin / divisor, significance_ndigits),
                        round(nmax / divisor, significance_ndigits))

                ax.text(x_r + x_text_nudge,
                        y - y_text_nudge,
                        label,
                        horizontalalignment='left',
                        transform=proj_lat_lon,
                        size=10)

            plt.title('Max AADF - {}'.format(plot_set['title_cols'][c]),
                      fontsize=10)
            legend_from_style_spec(ax, styles)
            output_file = os.path.join(
                config['paths']['figures'],
                'road_flow-map-{}-{}-max-scale.png'.format(
                    plot_set['file_tag'], column))
            save_fig(output_file)
            plt.close()
# plt.ylabel("Count")
# plt.title("Uncertainties for AVISO (GMSL retained)")
# plt.savefig(plotdir+"AVISO_remGMSL0.png",dpi=150)

# # Plot Historgram, GMSL removed
# plt.figure()
# plt.hist(nogmsl)
# plt.xlabel(r"Uncertainty $%s"%uncertform)
# plt.ylabel("Count")
# plt.title("Uncertainties for AVISO (no GMSL)")
# plt.savefig(plotdir+"AVISO_remGMSL1.png",dpi=150)

vm = [-2, 2]
# Visualize uncertainty maps
fig, ax = plt.subplots(
    1, 1, subplot_kw={'projection': ccrs.PlateCarree(central_longitude=180)})
ax = slutil.add_coast_grid(ax)
pcm = plt.pcolormesh(lon5,
                     lat5,
                     gmsl,
                     vmin=vm[0],
                     vmax=vm[-1],
                     cmap='copper',
                     transform=ccrs.PlateCarree())
if takemedian:
    ax.set_title(
        r"Uncertainty (AVISO with GMSL) $(median(\sigma^{2}_{in,x})/median(\sigma^{2}_{out,x}))$"
    )
else:
    ax.set_title(
        r"Uncertainty (AVISO with GMSL) $(<\sigma^{2}_{in,x}>/<\sigma^{2}_{out,x}>)$"
Example #21
0
def drawing(ax,proj,MARKER):
# ======================================
  ''' Draw a 2D vector plot. Option of vectors or stream function'''

  __version__ = "1.0"
  __author__  = "Quim Ballabrerera"
  __date__    = "May 2018"

  if not MARKER.show.get():
    return

  west, east, south, north = ax.get_extent()
  
  xv = []
  yv = []
  lv = []
  for i in range(MARKER.n):
    if MARKER.lon[i] > west and MARKER.lon[i] < east and \
       MARKER.lat[i] > south and MARKER.lat[i] < north:
      xv.append(MARKER.lon[i])
      yv.append(MARKER.lat[i])
      lv.append(MARKER.label[i])
  nn = len(xv)
  
  lmrk = None

  xpad = MARKER.PLOT.XPAD.get()
  ypad = MARKER.PLOT.YPAD.get()

  if nn > 0:
    if MARKER.textmode.get():
      # Here, every marker is identified by its label
      for i in range(nn):
        ax.text(xpad+xv[i],ypad+yv[i],lv[i],
                 ha=MARKER.PLOT.HA.get(),
                 va=MARKER.PLOT.VA.get(),
                 wrap=MARKER.PLOT.WRAP.get(),
                 style=MARKER.PLOT.STYLE.get(),
                 weight=MARKER.PLOT.WEIGHT.get(),
                 color=MARKER.PLOT.TCOLOR.get(),
                 size=MARKER.PLOT.TSIZE.get(),
                 zorder=MARKER.PLOT.ZORDER.get(),
                 rotation=MARKER.PLOT.ANGLE.get(),
                 transform=ccrs.PlateCarree())
                 #transform=proj)
 
        if MARKER.PLOT.SHOW.get():
          lines = []
          labels = []
          lmrk, = ax.plot(xv[i],yv[i],linestyle='',
                  marker=marker_string(MARKER.PLOT.SYMBOL.get()),
                  ms=MARKER.PLOT.SIZE.get(),
                  label=MARKER.LABEL.get(),
                  alpha=MARKER.PLOT.ALPHA.get(),
                  color=MARKER.PLOT.COLOR.get(),
                  zorder=MARKER.PLOT.ZORDER.get(),
                  transform=ccrs.PlateCarree())
                  #transform=proj)
#          lines.append(lmrk)
#          legend = ax.legend(lines,['toto'])
                
    else:
      if MARKER.PLOT.SHOW.get():
        lmrk, = ax.plot(xv,yv,linestyle='',
                marker=marker_string(MARKER.PLOT.SYMBOL.get()),
                ms=MARKER.PLOT.SIZE.get(),
                visible=MARKER.PLOT.SHOW.get(),
                label=MARKER.LABEL.get(),
                alpha=MARKER.PLOT.ALPHA.get(),
                color=MARKER.PLOT.COLOR.get(),
                zorder=MARKER.PLOT.ZORDER.get(),
                transform=ccrs.PlateCarree())
                #transform=proj)

  return lmrk
def main(fname, plot_dir):

    ds = xr.open_dataset(fname, decode_times=False)

    lat = ds.latitude.values
    lon = ds.longitude.values
    bottom, top = lat[0], lat[-1]
    left, right = lon[0], lon[-1]

    fig = plt.figure(figsize=(20, 8))
    plt.rcParams['font.family'] = "sans-serif"
    plt.rcParams['font.size'] = "14"
    plt.rcParams['font.sans-serif'] = "Helvetica"

    cmap = plt.cm.RdYlBu
    projection = ccrs.PlateCarree()
    axes_class = (GeoAxes, dict(map_projection=projection))
    rows = 1
    cols = 3

    axgr = AxesGrid(fig,
                    111,
                    axes_class=axes_class,
                    nrows_ncols=(rows, cols),
                    axes_pad=0.2,
                    cbar_location='right',
                    cbar_mode='single',
                    cbar_pad=0.5,
                    cbar_size='5%',
                    label_mode='')  # note the empty label_mode

    ppt_count = 0

    for year in np.arange(1900, 2016):  # 1970-2019

        ppt_count += 1

    year = 2016
    for i, ax in enumerate(axgr):
        # add a subplot into the array of plots
        #ax = fig.add_subplot(rows, cols, i+1, projection=ccrs.PlateCarree())
        plims = plot_map(ax, ds.pr[ppt_count + i, :, :], year, cmap, i, top,
                         bottom, left, right)

        import cartopy.feature as cfeature
        states = cfeature.NaturalEarthFeature(
            category='cultural',
            name='admin_1_states_provinces_lines',
            scale='10m',
            facecolor='none')

        # plot state border
        SOURCE = 'Natural Earth'
        LICENSE = 'public domain'
        ax.add_feature(states, edgecolor='black', lw=0.5)

        year += 1

    #bounds = np.linspace(0, 100, 9)
    #bounds = np.append(bounds, bounds[-1]+1)
    #norm = colors.BoundaryNorm(bounds, cmap.N)
    #cbar = axgr.cbar_axes[0].colorbar(plims, norm=norm, boundaries=bounds, ticks=bounds)
    cbar = axgr.cbar_axes[0].colorbar(plims)
    cbar.ax.set_title("Percentile", fontsize=16, pad=10)

    #for i, cax in enumerate(axgr.cbar_axes):
    #    cax.set_yticks([0.5, 5, 15, 25, 50, 75, 85, 94.5, 99.5])
    #    cax.set_yticklabels(["0-1", "1-10", "10-20", "20-30", "30-70", "70-80", \
    #                         "80-90", "90-99", "99-100"])

    ofname = os.path.join(plot_dir, "AWAP_PPT_percentiles_2016_2018.png")
    fig.savefig(ofname, dpi=300, bbox_inches='tight', pad_inches=0.1)
    plt.show()
Example #23
0
lat = pyg.gausslat(40)
lon = pyg.regularlon(80, origin=-180)

x = pyg.sin(2*np.pi * lon / 180.) * pyg.exp(-(lat - 30)**2 / (2*10**2))
y = pyg.cos(4*np.pi * lon / 180.) * pyg.exp(-(lat - 40)**2 / (4*10**2))

pyl.ioff()

# Build CartopyAxis for a Lambert Conformal projection
prj = dict(central_longitude=-90., central_latitude = 39.)
ax = pyg.plot.CartopyAxes(projection = 'LambertConformal', prj_args = prj)
ax.size = [6., 5.1]

# Add ocean
ax.add_feature(cartopy.feature.OCEAN)

# Add quiver plot
pyg.vquiver(x, y, axes=ax, width = 0.005)

# Set plot title
ax.setp(title = 'Lambert Conformal')

# Set lat/lon grid
ax.gridlines(xlocs = range(0, 361, 20), ylocs = range(-80, 81, 20))

# Set map extent to region over North America
ax.set_extent([-140, -50, 10, 75], crs = ccrs.PlateCarree())

pyl.ion()
ax.render(2)
def plot_map(ax, var, year, cmap, i, top, bottom, left, right):
    vmin, vmax = 0.0, 100.0
    #top, bottom = 90, -90
    #left, right = -180, 180
    #top, bottom = -10, -44
    #left, right = 112, 154
    #print(np.nanmin(var), np.nanmax(var))

    #bounds = [0.5, 5, 15, 25, 75, 85, 94.5, 99.5]
    bounds = np.linspace(0, 100 + 10, 10)
    #bounds = np.append(bounds, bounds[-1]+1)
    norm = colors.BoundaryNorm(bounds, cmap.N)

    img = ax.imshow(var * 100.,
                    origin='lower',
                    transform=ccrs.PlateCarree(),
                    interpolation='nearest',
                    cmap=cmap,
                    norm=norm,
                    extent=(left, right, bottom, top),
                    vmin=vmin,
                    vmax=vmax)

    ax.coastlines(resolution='10m', linewidth=1.0, color='black')
    #ax.add_feature(cartopy.feature.OCEAN)
    ax.set_title("%d$-$%d" % (year, year + 1), fontsize=16)
    ax.set_xlim(140.7, 154)
    ax.set_ylim(-39.2, -28.1)

    if i == 0 or i >= 5:

        gl = ax.gridlines(crs=ccrs.PlateCarree(),
                          draw_labels=True,
                          linewidth=0.5,
                          color='black',
                          alpha=0.5,
                          linestyle='--')
    else:
        gl = ax.gridlines(crs=ccrs.PlateCarree(),
                          draw_labels=False,
                          linewidth=0.5,
                          color='black',
                          alpha=0.5,
                          linestyle='--')

    #if i < 5:
    gl.xlabels_bottom = True
    if i > 1:
        gl.ylabels_left = False

    gl.xlabels_top = False
    gl.ylabels_right = False
    gl.xlines = False
    gl.ylines = False
    gl.xformatter = LONGITUDE_FORMATTER
    gl.yformatter = LATITUDE_FORMATTER

    gl.xlocator = mticker.FixedLocator([141, 145, 149, 153])
    gl.ylocator = mticker.FixedLocator([-29, -32, -35, -38])

    #if i == 0 :
    #    ax.text(-0.2, 0.5, 'Latitude', va='bottom', ha='center',
    #            rotation='vertical', rotation_mode='anchor',
    #            transform=ax.transAxes, fontsize=16)
    #if i == 1:
    #    ax.text(0.5, -0.2, 'Longitude', va='bottom', ha='center',
    #            rotation='horizontal', rotation_mode='anchor',
    #            transform=ax.transAxes, fontsize=16)

    return img
def draw_Crosssection_Wind_Temp_RH(
                    cross_rh=None, cross_Temp=None, cross_u=None,
                    cross_v=None,cross_terrain=None,
                    gh=None,
                    h_pos=None,st_point=None,ed_point=None,lw_ratio=None,
                    levels=None,map_extent=(50, 150, 0, 65),model=None,
                    output_dir=None):

    plt.rcParams['font.sans-serif'] = ['SimHei'] # 步骤一(替换sans-serif字体)
    plt.rcParams['axes.unicode_minus'] = False  # 步骤二(解决坐标轴负数的负号显示问题)

    initTime = pd.to_datetime(
    str(cross_Temp['forecast_reference_time'].values)).replace(tzinfo=None).to_pydatetime()
    fcst_time=initTime+timedelta(hours=gh['forecast_period'].values[0])
    
    fig = plt.figure(1, figsize=(lw_ratio[0],lw_ratio[1]))
    ax = plt.axes()
    cross_rh['data'].values[cross_rh['data'].values > 100]=100

    # example 2: use the "fromList() method
    startcolor = '#1E90FF'   #蓝色
    midcolor = '#F1F1F1'     #白色
    endcolor = '#696969'     #灰色
    cmap2 = col.LinearSegmentedColormap.from_list('own2',['#1E90FF','#94D8F6','#F1F1F1','#BFBFBF','#696969'])
    # extra arguments are N=256, gamma=1.0
    cm.register_cmap(cmap=cmap2)
    
    # we can skip name here as it was already defined

    rh_contour = ax.contourf(cross_rh['lon'], cross_rh['level'], cross_rh['data'],
                            levels=np.arange(0, 101, 0.5), cmap=cm.get_cmap('own2'))
    rh_colorbar = fig.colorbar(rh_contour,ticks=[20,40,60,80,100])

    # Plot potential temperature using contour, with some custom labeling
    Temp_contour = ax.contour(cross_Temp['lon'], cross_Temp['level'],cross_Temp['data'].values,
                            levels=np.arange(-100, 100, 2), colors='#A0522D', linewidths=1)

    Temp_contour.clabel(np.arange(-100, 100, 2), fontsize=16, colors='#A0522D', inline=1,
                        inline_spacing=8, fmt='%i', rightside_up=True, use_clabeltext=True)

    Temp_zero_contour = ax.contour(cross_Temp['lon'], cross_Temp['level'],cross_Temp['data'].values,
                            levels=[0], colors='k', linewidths=3)

    try:
        Temp_zero_contour.clabel([0], fontsize=22, colors='k', inline=1,
                            inline_spacing=8, fmt='%i', rightside_up=True, use_clabeltext=True)
    except:
        print('No Zero Line')                            

    wind_slc_vert = list(range(0, len(levels), 1))
    wind_slc_horz = slice(5, 100, 5)
    ax.barbs(cross_u['lon'][wind_slc_horz], cross_u['level'][wind_slc_vert],
            cross_u['t_wind'][wind_slc_vert, wind_slc_horz]*2.5,    
            cross_v['n_wind'][wind_slc_vert, wind_slc_horz]*2.5, color='k')

    startcolor = '#8B4513'   #棕色
    endcolor='#DAC2AD' #绿 
    cmap2 = col.LinearSegmentedColormap.from_list('own3',[endcolor,startcolor])
    # extra arguments are N=256, gamma=1.0
    cm.register_cmap(cmap=cmap2)
    terrain_contour = ax.contourf(cross_terrain['lon'], cross_terrain['level'], cross_terrain.values,
                            levels=np.arange(0, 500, 1), cmap=cm.get_cmap('own3'),zorder=100)
    # Adjust the y-axis to be logarithmic
    ax.set_yscale('symlog')
    ax.set_yticklabels(np.arange(levels[0], levels[-1], -100))
    ax.set_ylim(levels[0], levels[-1])
    ax.set_yticks(np.arange(levels[0], levels[-1], -100))

    # Define the CRS and inset axes
    data_crs = ccrs.PlateCarree()
    ax_inset = fig.add_axes(h_pos, projection=data_crs)
    ax_inset.set_extent(map_extent, crs=data_crs)
    # Plot geopotential height at 500 hPa using xarray's contour wrapper
    ax_inset.contour(gh['lon'], gh['lat'], np.squeeze(gh['data']),
                    levels=np.arange(500, 600, 4), cmap='inferno')
    # Plot the path of the cross section
    endpoints = data_crs.transform_points(ccrs.Geodetic(),
                                        *np.vstack([st_point, ed_point]).transpose()[::-1])
    ax_inset.scatter(endpoints[:, 0], endpoints[:, 1], c='k', zorder=2)
    ax_inset.plot(cross_u['lon'], cross_u['lat'], c='k', zorder=2)
    # Add geographic features
    ax_inset.coastlines()
    utl.add_china_map_2cartopy_public(
            ax_inset, name='province', edgecolor='black', lw=0.8, zorder=105)
    # Set the titles and axes labels
    ax_inset.set_title('')

    ax.set_title('['+model+'] '+'温度, 相对湿度, 沿剖面风', loc='right', fontsize=25)
    ax.set_ylabel('Pressure (hPa)')
    ax.set_xlabel('Longitude')
    rh_colorbar.set_label('Relative Humidity (%)')

    if(sys.platform[0:3] == 'lin'):
        locale.setlocale(locale.LC_CTYPE, 'zh_CN.utf8')
    if(sys.platform[0:3] == 'win'):        
        locale.setlocale(locale.LC_CTYPE, 'chinese')
    bax=fig.add_axes([0.10,0.88,.25,.07],facecolor='#FFFFFFCC')
    bax.axis('off')
    #bax.set_yticks([])
    #bax.set_xticks([])
    bax.axis([0, 10, 0, 10])        
    plt.text(2.5, 7.5,'起报时间: '+initTime.strftime("%Y年%m月%d日%H时"),size=11)
    plt.text(2.5, 5,'预报时间: '+fcst_time.strftime("%Y年%m月%d日%H时"),size=11)
    plt.text(2.5, 2.5,'预报时效: '+str(int(gh['forecast_period'].values[0]))+'小时',size=11)
    plt.text(2.5, 0.5,'www.nmc.cn',size=11)

    utl.add_logo_extra_in_axes(pos=[0.1,0.88,.07,.07],which='nmc', size='Xlarge')

    # show figure
    if(output_dir != None):
        plt.savefig(output_dir+'温度_相对湿度_沿剖面风_预报_'+
        '起报时间_'+initTime.strftime("%Y年%m月%d日%H时")+
        '预报时效_'+str(int(gh['forecast_period'].values[0]))+'小时'+'.png', dpi=200,bbox_inches='tight')
        plt.close()
    
    if(output_dir == None):
        plt.show()                 
Example #26
0
        'lat': np.linspace(-89.5, 89.5, num=180),
        'lon': np.linspace(0.5, 359.5, num=360),
    },
)

print('Output netCDF4')
path_out = '../analysis/STDs/'
outstatsfile = path_out + 'SSS_omip1-omip2_stats.nc'
DS_stats.to_netcdf(path=outstatsfile, mode='w', format='NETCDF4')

#J 描画
print('Start drawing')
fig = plt.figure(figsize=(11, 8))
fig.suptitle(suptitle, fontsize=18)

proj = ccrs.PlateCarree(central_longitude=-140.)
lon_formatter = LongitudeFormatter(zero_direction_label=True)
lat_formatter = LatitudeFormatter()

bounds = [-0.4, -0.3, -0.2, -0.1, -0.06, -0.02, 0.02, 0.06, 0.1, 0.2, 0.3, 0.4]
ticks_bounds = bounds

cmap = 'RdBu_r'
item = 'omip2-1'

ax1 = plt.axes(projection=proj)

da = DS_stats["mean"]

da.plot(ax=ax1,
        cmap=cmap,
Example #27
0
def proj_to_cartopy(proj):
    """
    Converts a pyproj.Proj to a cartopy.crs.Projection

    (Code copied from https://github.com/fmaussion/salem)

    Parameters
    ----------
    proj: pyproj.Proj
        the projection to convert
    Returns
    -------
    a cartopy.crs.Projection object
    """

    import cartopy.crs as ccrs
    try:
        from osgeo import osr
        has_gdal = True
    except ImportError:
        has_gdal = False

    proj = check_crs(proj)

    if proj.is_latlong():
        return ccrs.PlateCarree()

    srs = proj.srs
    if has_gdal:
        # this is more robust, as srs could be anything (espg, etc.)
        s1 = osr.SpatialReference()
        s1.ImportFromProj4(proj.srs)
        srs = s1.ExportToProj4()

    km_proj = {'lon_0': 'central_longitude',
               'lat_0': 'central_latitude',
               'x_0': 'false_easting',
               'y_0': 'false_northing',
               'k': 'scale_factor',
               'zone': 'zone',
               }
    km_globe = {'a': 'semimajor_axis',
                'b': 'semiminor_axis',
                }
    km_std = {'lat_1': 'lat_1',
              'lat_2': 'lat_2',
              }
    kw_proj = dict()
    kw_globe = dict()
    kw_std = dict()
    for s in srs.split('+'):
        s = s.split('=')
        if len(s) != 2:
            continue
        k = s[0].strip()
        v = s[1].strip()
        try:
            v = float(v)
        except:
            pass
        if k == 'proj':
            if v == 'tmerc':
                cl = ccrs.TransverseMercator
            if v == 'lcc':
                cl = ccrs.LambertConformal
            if v == 'merc':
                cl = ccrs.Mercator
            if v == 'utm':
                cl = ccrs.UTM
        if k in km_proj:
            kw_proj[km_proj[k]] = v
        if k in km_globe:
            kw_globe[km_globe[k]] = v
        if k in km_std:
            kw_std[km_std[k]] = v

    globe = None
    if kw_globe:
        globe = ccrs.Globe(**kw_globe)
    if kw_std:
        kw_proj['standard_parallels'] = (kw_std['lat_1'], kw_std['lat_2'])

    # mercatoooor
    if cl.__name__ == 'Mercator':
        kw_proj.pop('false_easting', None)
        kw_proj.pop('false_northing', None)

    return cl(globe=globe, **kw_proj)
Example #28
0
def simple_plot(resource,
                variable='air',
                lat='lat',
                lon='lon',
                timestep=0,
                output=None):
    """
    Generates a nice and simple plot.
    """
    print("Plotting {}, timestep {} ...".format(resource, timestep))

    pl_data = Dataset(resource)

    pl_val = pl_data.variables[variable][timestep, :, :]
    pl_lat = pl_data.variables[lat][:]
    pl_lon = pl_data.variables[lon][:]

    fig = plt.figure()
    fig.set_size_inches(18.5, 10.5, forward=True)

    ax = plt.axes(projection=ccrs.PlateCarree())
    ax.coastlines(linewidth=0.8)
    ax.gridlines()

    vmin = np.min(pl_val)
    vmax = np.max(pl_val)

    levels = np.linspace(vmin, vmax, 30)

    cmap = get_cmap("RdBu_r")

    data_map = ax.contourf(pl_lon,
                           pl_lat,
                           pl_val,
                           levels=levels,
                           extend='both',
                           cmap=cmap,
                           projection=ccrs.PlateCarree())
    data_cbar = plt.colorbar(data_map, extend='both', shrink=0.6)
    data_cont = ax.contour(pl_lon,
                           pl_lat,
                           pl_val,
                           levels=levels,
                           linewidths=0.5,
                           colors="white",
                           linestyles='dashed',
                           projection=ccrs.PlateCarree())

    plt.clabel(data_cont, inline=1, fmt='%1.0f')
    title = 'Simple plot for %s' % (variable)
    plt.title(title)
    plt.tight_layout()

    if not output:
        output = 'myplot_%s.png' % (uuid.uuid1())

    plt.savefig(output)
    fig.clf()
    plt.close(fig)

    print("Plot written to {}".format(output))
    return output
Example #29
0
    def process(self, sites, orography, land_mask):
        """
        Using the constraints provided, find the nearest grid point neighbours
        to the given spot sites for the model/grid given by the input cubes.
        Returned is a cube that contains the defining characteristics of the
        spot sites (e.g. x coordinate, y coordinate, altitude) and the indices
        of the selected grid point neighbour.

        Args:
            sites (list of dict):
                A list of dictionaries defining the spot sites for which
                neighbours are to be found. e.g.:

                   [{'altitude': 11.0, 'latitude': 57.867000579833984,
                    'longitude': -5.632999897003174, 'wmo_id': 3034}]

            orography (iris.cube.Cube):
                A cube of orography, used to obtain the grid point altitudes.
            land_mask (iris.cube.Cube):
                A land mask cube for the model/grid from which grid point
                neighbours are being selected, with land points set to one and
                sea points set to zero.
        Returns:
            iris.cube.Cube:
                A cube containing both the spot site information and for each
                the grid point indices of its nearest neighbour as per the
                imposed constraints.
        """
        # Check if we are dealing with a global grid.
        self.global_coordinate_system = orography.coord(axis="x").circular

        # Exclude regional grids with spatial dimensions other than metres.
        if not self.global_coordinate_system:
            if not orography.coord(axis="x").units == "metres":
                msg = ("Cube spatial coordinates for regional grids must be"
                       "in metres to match the defined search_radius.")
                raise ValueError(msg)

        # Ensure land_mask and orography are on the same grid.
        if not orography.dim_coords == land_mask.dim_coords:
            msg = "Orography and land_mask cubes are not on the same " "grid."
            raise ValueError(msg)

        # Enforce x-y coordinate order for input cubes.
        enforce_coordinate_ordering(
            orography,
            [
                orography.coord(axis="x").name(),
                orography.coord(axis="y").name()
            ],
        )
        enforce_coordinate_ordering(
            land_mask,
            [
                land_mask.coord(axis="x").name(),
                land_mask.coord(axis="y").name()
            ],
        )

        # Remap site coordinates on to coordinate system of the model grid.
        site_x_coords = np.array(
            [site[self.site_x_coordinate] for site in sites])
        site_y_coords = np.array(
            [site[self.site_y_coordinate] for site in sites])
        site_coords = self._transform_sites_coordinate_system(
            site_x_coords, site_y_coords,
            orography.coord_system().as_cartopy_crs())

        # Exclude any sites falling outside the domain given by the cube and
        # notify the user.
        (
            sites,
            site_coords,
            site_x_coords,
            site_y_coords,
        ) = self.check_sites_are_within_domain(sites, site_coords,
                                               site_x_coords, site_y_coords,
                                               orography)

        # Find nearest neighbour point using quick iris method.
        nearest_indices = self.get_nearest_indices(site_coords, orography)

        # Create an array containing site altitudes, using the nearest point
        # orography height for any that are unset.
        site_altitudes = np.array(
            [site.get(self.site_altitude, None) for site in sites])
        site_altitudes = np.where(
            np.isnan(site_altitudes.astype(float)),
            orography.data[tuple(nearest_indices.T)],
            site_altitudes,
        )

        # If further constraints are being applied, build a KD Tree which
        # includes points filtered by constraint.
        if self.land_constraint or self.minimum_dz:
            # Build the KDTree, an internal test for the land_constraint checks
            # whether to exclude sea points from the tree.
            tree, index_nodes = self.build_KDTree(land_mask)

            # Site coordinates made cartesian for global coordinate system
            if self.global_coordinate_system:
                site_coords = self.geocentric_cartesian(
                    orography, site_coords[:, 0], site_coords[:, 1])

            if not self.minimum_dz:
                # Query the tree for the nearest neighbour, in this case a land
                # neighbour is returned along with the distance to it.
                distances, node_indices = tree.query([site_coords])
                # Look up the grid coordinates that correspond to the tree node
                (land_neighbour_indices, ) = index_nodes[node_indices]
                # Use the found land neighbour if it is within the
                # search_radius, otherwise use the nearest neighbour.
                distances = np.array([distances[0], distances[0]]).T
                nearest_indices = np.where(
                    distances < self.search_radius,
                    land_neighbour_indices,
                    nearest_indices,
                )
            else:
                # Query the tree for self.node_limit nearby neighbours.
                distances, node_indices = tree.query(
                    [site_coords],
                    distance_upper_bound=self.search_radius,
                    k=self.node_limit,
                )
                # Loop over the sites and for each choose the returned
                # neighbour with the minimum vertical displacement.
                for index, (distance, indices) in enumerate(
                        zip(distances[0], node_indices[0])):
                    grid_point = self.select_minimum_dz(
                        orography, site_altitudes[index], index_nodes,
                        distance, indices)
                    # None is returned if the tree query returned no neighbours
                    # within the search radius.
                    if grid_point is not None:
                        nearest_indices[index] = grid_point

        # Calculate the vertical displacements between the chosen grid point
        # and the spot site.
        vertical_displacements = (site_altitudes -
                                  orography.data[tuple(nearest_indices.T)])

        # Create a list of WMO IDs if available. These are stored as strings
        # to accommodate the use of 'None' for unset IDs.
        wmo_ids = [str(site.get("wmo_id", None)) for site in sites]

        # Construct a name to describe the neighbour finding method employed
        method_name = self.neighbour_finding_method_name()

        # Create an array of indices and displacements to return
        data = np.stack(
            (nearest_indices[:, 0], nearest_indices[:, 1],
             vertical_displacements),
            axis=0,
        )
        data = np.expand_dims(data, 0).astype(np.float32)

        # Regardless of input sitelist coordinate system, the site coordinates
        # are stored as latitudes and longitudes in the neighbour cube.
        if self.site_coordinate_system != ccrs.PlateCarree():
            lon_lats = self._transform_sites_coordinate_system(
                site_x_coords, site_y_coords, ccrs.PlateCarree())
            longitudes = lon_lats[:, 0]
            latitudes = lon_lats[:, 1]
        else:
            longitudes = site_x_coords
            latitudes = site_y_coords

        # Create a cube of neighbours
        neighbour_cube = build_spotdata_cube(
            data,
            "grid_neighbours",
            1,
            site_altitudes.astype(np.float32),
            latitudes.astype(np.float32),
            longitudes.astype(np.float32),
            wmo_ids,
            neighbour_methods=[method_name],
            grid_attributes=["x_index", "y_index", "vertical_displacement"],
        )

        # Add a hash attribute based on the model grid to ensure the neighbour
        # cube is only used with a compatible grid.
        grid_hash = create_coordinate_hash(orography)
        neighbour_cube.attributes["model_grid_hash"] = grid_hash

        return neighbour_cube
Example #30
0
                  crs=projection)
    '''zero_direction_label=True 有度的标识,False则去掉'''
    lon_formatter = LongitudeFormatter(zero_direction_label=True)
    lat_formatter = LatitudeFormatter()
    ax.xaxis.set_major_formatter(lon_formatter)
    ax.yaxis.set_major_formatter(lat_formatter)
    '''添加网格线'''
    #gl = ax.gridlines()
    #ax.grid()
    return ax


#==============================================================================

# 设置常量
projection = ccrs.PlateCarree()
resolution = '110m'
lonstart = 60
lonstop = 360
latstart = -30
latstop = 90
box = np.array([lonstart, lonstop, latstart, latstop])
# x,y轴标签个数
xnum = 6
ynum = 5
#
nrows = 2
ncols = 1
# prob_level
levels_prob = [0., 0.95, 1.0]
subtitles = ['a) EAWIM', 'b) EAWMIres']