Ejemplo n.º 1
0
def plot_map(ax, cast, grid_B, xlims, ylims):
    """ Plot the location of cast lon/lat on a map.

    :arg ax: axis for plotting
    :type ax: axis object

    :arg cast: the observed cast
    :type cast: pandas DataFrame-like object

    :arg grid_B: model bathymetry
    :type grid_B: netCDF4 object

    :arg xlims: min/max longitudes, eg [-124,-123]
    :type xlims: 2-tuple

    :arg ylims: min/max latitudes, eg [48,49]
    :type ylims: 2-tuple

    """
    cast.plot(x='Longitude Corrected (deg)',
              y='Latitude Corrected (deg)',
              kind='scatter',
              ax=ax)
    viz_tools.plot_coastline(ax, grid_B, coords='map')
    ax.set_xlim(xlims)
    ax.set_ylim(ylims)
    ax.set_title(cast.day.min().strftime('%Y-%m-%d'))
Ejemplo n.º 2
0
def _plot_vel_surface(ax, plot_data, bathy, sections=None):

    ax.quiver(
        plot_data.gridX[::5],
        plot_data.gridY[::5],
        plot_data.U_surface[::5, ::5],
        plot_data.V_surface[::5, ::5],
        scale=20,
    )
    if sections is not None:
        for section in zip(*sections):
            ax.plot(section[1][:2], (section[0], section[0]),
                    "r--",
                    linewidth=2)
    viz_tools.plot_land_mask(ax, bathy, color="burlywood")
    viz_tools.plot_coastline(ax, bathy)
Ejemplo n.º 3
0
 def test_plot_coastline_isobath(self):
     axes, bathy = Mock(), Mock()
     bathy.variables = {'Bathymetry': Mock()}
     contour_lines = viz_tools.plot_coastline(axes, bathy, isobath=42.42)
     axes.contour.assert_called_once_with(bathy.variables['Bathymetry'],
                                          [42.42],
                                          colors='black')
     assert contour_lines == axes.contour()
Ejemplo n.º 4
0
 def test_plot_coastline_color_arg(self):
     axes, bathy = Mock(), Mock()
     bathy.variables = {'Bathymetry': Mock()}
     contour_lines = viz_tools.plot_coastline(axes, bathy, color='red')
     axes.contour.assert_called_once_with(bathy.variables['Bathymetry'],
                                          [0],
                                          colors='red')
     assert contour_lines == axes.contour()
Ejemplo n.º 5
0
def _plot_ssh_map(ax_map, plot_data, place, theme):
    contour_intervals = [
        -1,
        -0.5,
        0.5,
        1,
        1.5,
        1.6,
        1.7,
        1.8,
        1.9,
        2,
        2.1,
        2.2,
        2.4,
        2.6,
    ]
    mesh = ax_map.contourf(
        plot_data.max_ssh_field,
        contour_intervals,
        cmap="YlOrRd",
        extend="both",
        alpha=0.6,
    )
    ax_map.contour(plot_data.max_ssh_field,
                   contour_intervals,
                   colors="black",
                   linestyles="--")
    cbar = plt.colorbar(mesh, ax=ax_map)
    j, i = PLACES[place]["NEMO grid ji"]
    ax_map.plot(
        i,
        j,
        marker="o",
        markersize=10,
        markeredgewidth=3,
        markerfacecolor=theme.COLOURS["marker"]["place"]["facecolor"],
        markeredgecolor=theme.COLOURS["marker"]["place"]["edgecolor"],
    )
    viz_tools.plot_coastline(ax_map, plot_data.bathy)
    viz_tools.plot_land_mask(ax_map,
                             plot_data.bathy,
                             color=theme.COLOURS["land"])
    _ssh_map_axis_labels(ax_map, place, plot_data, theme)
    _ssh_map_cbar_labels(cbar, contour_intervals, theme)
def _plot_ssh_map(ax, plot_data, place, theme):
    contour_intervals = [
        -1, -0.5, 0.5, 1, 1.5, 1.6, 1.7, 1.8, 1.9, 2, 2.1, 2.2, 2.4, 2.6
    ]
    mesh = ax.contourf(plot_data.ssh_max_field,
                       contour_intervals,
                       cmap='nipy_spectral',
                       extend='both',
                       alpha=0.6)
    ax.contour(plot_data.ssh_max_field,
               contour_intervals,
               colors='black',
               linestyles='--')
    cbar = plt.colorbar(mesh, ax=ax)
    viz_tools.plot_coastline(ax, plot_data.bathy)
    viz_tools.plot_land_mask(ax, plot_data.bathy, color=theme.COLOURS['land'])
    _ssh_map_axis_labels(ax, place, plot_data, theme)
    _ssh_map_cbar_labels(cbar, contour_intervals, theme)
Ejemplo n.º 7
0
def monthly_means(lighthouse, grid_B, smin=28, smax=33, tmin=6, tmax=12):
    """Plot the monthly mean temperature and salinity at a lighthouse

    :arg lighthouse: the lighthouse name
    :type lighthouse: string

    :arg grid_B: NEMO bathymetry grid
    :type grid_B: netCDF4 handle

    :arg smin: minumum salinity for axis limits
    :type smin: float

    :arg smax: maximium salinity for axis limits
    :type smax: float

    :arg tmin: minumum temperature for axis limits
    :type tmin: float

    :arg tmax: maximium temperature for axis limits
    :type tmax: float

    :returns: fig, a figure object
    """
    data, lat, lon = load_lighthouse(LIGHTHOUSES[lighthouse])
    fig, axs = plt.subplots(1, 3, figsize=(15, 5))
    grouped = data.groupby(['Month'])
    mean = grouped.apply(np.mean)
    ax = axs[0]
    mean.plot(y='Salinity(psu)', ax=ax)
    ax.set_ylim([smin, smax])
    ax.set_title('{} Monthly Mean Observed Salinity'.format(lighthouse))
    ax2 = axs[1]
    mean.plot(y='Temperature(C)', ax=ax2)
    ax2.set_ylim([tmin, tmax])
    ax2.set_title('{} Monthly Mean Observed Temperature'.format(lighthouse))
    # plot map
    axm = axs[2]
    axm.plot(lon, lat, 'o')
    viz_tools.plot_coastline(axm, grid_B, coords='map')

    return fig
Ejemplo n.º 8
0
def plot_CODAR_ellipse(ax,
                       lons,
                       lats,
                       const,
                       datastruc,
                       depths,
                       grid,
                       step=3,
                       scale=0.08,
                       baroclinic=False,
                       depth_level=0,
                       barotropic=False,
                       isobaths=[5, 20]):
    """Plot ellipses over the CODAR region"""
    major, minor, pha, inc = get_constituent(const, datastruc)
    if baroclinic:
        major = major[:, :, depth_level]
        minor = minor[:, :, depth_level]
        inc = inc[:, :, depth_level]
        title_str = 'baroclinic {0:.3g} m'.format(depths[depth_level][0])
    elif barotropic:
        title_str = 'barotropic'
    else:
        title_str = 'surface'
    for i in np.arange(0, lons.shape[0], step):
        for j in np.arange(0, lats.shape[-1], step):
            if major[i, j]:
                plot_ellipse(lons[i, j], lats[i, j], inc[i, j], major[i, j],
                             minor[i, j], ax, scale)

    ax.set_title('{} {} tidal ellipses'.format(const, title_str))

    ax.set_ylabel('Latitude (degrees N)')
    ax.set_xlabel('Longitude (degrees W)')

    viz_tools.plot_land_mask(ax, grid, coords='map')
    for isobath in isobaths:
        viz_tools.plot_coastline(ax, grid, coords='map', isobath=isobath)
Ejemplo n.º 9
0
 def test_plot_coastline_map_coords(self):
     axes, bathy = Mock(), Mock()
     bathy.variables = {
         'Bathymetry': Mock(),
         'nav_lat': Mock(),
         'nav_lon': Mock(),
     }
     contour_lines = viz_tools.plot_coastline(axes, bathy, coords='map')
     axes.contour.assert_called_once_with(bathy.variables['nav_lon'],
                                          bathy.variables['nav_lat'],
                                          bathy.variables['Bathymetry'],
                                          [0],
                                          colors='black')
     assert contour_lines == axes.contour()
Ejemplo n.º 10
0
 def test_plot_coastline_grid_coords_slice(self):
     axes, bathy = Mock(), Mock()
     bathy.variables = {'Bathymetry': MagicMock(spec=nc.Variable)}
     xslice = np.arange(250, 370)
     yslice = np.arange(200, 320)
     contour_lines = viz_tools.plot_coastline(axes,
                                              bathy,
                                              xslice=xslice,
                                              yslice=yslice)
     axes.contour.assert_called_once_with(
         xslice,
         yslice,
         bathy.variables['Bathymetry'][yslice, xslice].data, [0],
         colors='black')
     assert contour_lines == axes.contour()
Ejemplo n.º 11
0
def compare_cast_hourly(month,
                        model_year,
                        field,
                        data_obs,
                        model_path,
                        xmin=-124,
                        xmax=-122,
                        ymin=48,
                        ymax=50,
                        zmin=0,
                        zmax=300,
                        vmin=10,
                        vmax=32):
    """Comparison between model and observations at every cast in a given month
    Model daily average is compared witth houlry std errors
    """
    # Load model grid
    grid = '/data/nsoontie/MEOPAR/NEMO-forcing/grid/bathy_meter_SalishSea2.nc'
    f = nc.Dataset(grid)
    bathy = f.variables['Bathymetry'][:]
    X = f.variables['nav_lon'][:]
    Y = f.variables['nav_lat'][:]
    mesh = '/data/nsoontie/MEOPAR/NEMO-forcing/grid/mesh_mask_SalishSea2.nc'
    g = nc.Dataset(mesh)
    depth_mod = g.variables['gdept_0'][0, :]

    # Model variables
    if field == 'Salinity':
        model_field = 'vosaline'
    elif field == 'Temperature':
        model_field = 'votemper'

    # plot obs and model
    data_m = data_obs[data_obs['Month'] == month]
    num_casts = len(data_m.index)
    fig, axs = plt.subplots(num_casts, 2, figsize=(10, 3.5 * num_casts))
    cast = 0
    for dep_obs, var_obs, lon, lat, day, year in zip(
            data_m['Depth'], data_m[field], data_m['Longitude'],
            data_m['Latitude'], data_m['Day'], data_m['Year']):
        # model grid points
        try:
            ax = axs[cast, 0]
            axm = axs[cast, 1]
        except IndexError:
            ax = axs[0]
            axm = axs[1]
        j, i = tidetools.find_closest_model_point(lon, lat, X, Y, bathy)
        date = datetime.datetime(year, month, day)
        if date >= FIRST_NOWCAST:
            hourly_grid = get_hourly_grid(date, model_path)
            depth_mod = hourly_grid.variables['deptht'][:]
            max_h, min_h, var_plot = calculate_hourly_ext(
                model_field, hourly_grid, j, i)
        else:
            var_model = early_model_data(date, j, i, '1h', 'grid_T',
                                         model_field, model_path)
            var_plot = np.mean(var_model, axis=0)
            min_h = np.min(var_model, axis=0)
            max_h = np.max(var_model, axis=0)

        # plot model
        ax.plot(var_plot, depth_mod, '-b', label='daily mean', alpha=0.5)
        ax.plot(max_h, depth_mod, 'k--', label='daily max')
        ax.plot(min_h, depth_mod, 'k:', label='daily min')
        # plot observations and location on map
        ax.plot(var_obs, dep_obs, '-*r', label='obs')
        axm.plot(lon, lat, '*r')
        # Set plot axis and labels
        ax.set_ylim([zmax, zmin])
        ax.set_xlim([vmin, vmax])
        ax.set_ylabel('Depth [m]')
        ax.set_xlabel(field)
        # plot mode coastline
        viz_tools.plot_coastline(axm, f, coords='map')
        axm.set_ylim([ymin, ymax])
        axm.set_xlim([xmin, xmax])
        axm.set_title('{}-{}-{}'.format(year, month, day))
        # legend
        ax.legend(loc=0)
        cast = cast + 1

    return fig
Ejemplo n.º 12
0
def compare_cast_model(month,
                       model_year,
                       field,
                       data_obs,
                       model_path,
                       xmin=-124,
                       xmax=-122,
                       ymin=48,
                       ymax=50,
                       zmin=0,
                       zmax=300,
                       vmin=10,
                       vmax=32,
                       x=7):
    """Comparison between model and observations at every cast in a given month
    Model is compared x days before and after cast date
    """
    # Load model grid
    grid = '/data/nsoontie/MEOPAR/NEMO-forcing/grid/bathy_meter_SalishSea2.nc'
    f = nc.Dataset(grid)
    bathy = f.variables['Bathymetry'][:]
    X = f.variables['nav_lon'][:]
    Y = f.variables['nav_lat'][:]

    # date ranges based on month and model_year
    date = datetime.datetime(model_year, month, 1)
    sdt = date - datetime.timedelta(days=31)
    edt = date + datetime.timedelta(days=60)

    # Model variables and nowcast/spinup?
    if field == 'Salinity':
        model_field = 'vosaline'
    elif field == 'Temperatute':
        model_field = 'votemper'
    # Is this a nowcast?
    if model_year == 2014 or model_year == 2015:
        nowcast_flag = True
    else:
        nowcast_flag = False

    # load model variables
    depth_mod, var_mod, dates_mod = load_model(model_path,
                                               sdt,
                                               edt,
                                               model_field,
                                               nowcast_flag=nowcast_flag)
    # plot obs and model
    data_m = data_obs[data_obs['Month'] == month]
    num_casts = len(data_m.index)
    fig, axs = plt.subplots(num_casts, 2, figsize=(10, 3.5 * num_casts))
    cast = 0
    for dep_obs, var_obs, lon, lat, day, year in zip(
            data_m['Depth'], data_m[field], data_m['Longitude'],
            data_m['Latitude'], data_m['Day'], data_m['Year']):
        # model grid points
        try:
            ax = axs[cast, 0]
            axm = axs[cast, 1]
        except IndexError:
            ax = axs[0]
            axm = axs[1]
        [j, i] = tidetools.find_closest_model_point(lon, lat, X, Y, bathy)
        # model time index
        t_ind = []
        for count, date in enumerate(dates_mod):
            if date.day == day:
                if date.month == month:
                    t_ind.append(count)
                    t_ind.append(count - x)  # x days earlier
                    t_ind.append(count + x)  # x days later
        labels = [
            'same day', '{} days earlier'.format(x), '{} days later'.format(x)
        ]
        colors = ['b', 'g', 'k']
        for ii, t in enumerate(t_ind):
            try:
                var_plot = var_mod[t, :, j, i]
                var_plot = np.ma.masked_values(var_plot, 0)
                if j:
                    ax.plot(var_plot,
                            depth_mod,
                            '-b',
                            color=colors[ii],
                            label=labels[ii],
                            alpha=0.5)
            except IndexError:
                print('No model data for {}/{}, '
                      '{}'.format(day, month, labels[ii]))
        # plot observations and location on map
        ax.plot(var_obs, dep_obs, '-*r', label='obs')
        axm.plot(lon, lat, '*r')
        # Set plot axis and labels
        ax.set_ylim([zmax, zmin])
        ax.set_xlim([vmin, vmax])
        ax.set_ylabel('Depth [m]')
        ax.set_xlabel(field)

        # plot mode coastline
        viz_tools.plot_coastline(axm, f, coords='map')
        axm.set_ylim([ymin, ymax])
        axm.set_xlim([xmin, xmax])
        axm.set_title('{}-{}-{}'.format(year, month, day))

        # legend
        ax.legend(loc=0)
        cast = cast + 1

    return fig
Ejemplo n.º 13
0
def compare_model_obs(month,
                      model_year,
                      field,
                      data_obs,
                      model_path,
                      xmin=-124,
                      xmax=-122,
                      ymin=48,
                      ymax=50,
                      zmin=0,
                      zmax=300,
                      vmin=10,
                      vmax=32):
    """Compares the observations from WOD with model output on the same day
    and at a close grid point.
    Comparisons are during single month.
    field is compared ('Temperature' or 'Salinity' )
    Observations stored in data_obs (DataFrame)
    Model_path defines where the model data is stored(can be nowcast or spinup)
    """
    # Load model grid
    grid = '/data/nsoontie/MEOPAR/NEMO-forcing/grid/bathy_meter_SalishSea2.nc'
    f = nc.Dataset(grid)
    bathy = f.variables['Bathymetry'][:]
    X = f.variables['nav_lon'][:]
    Y = f.variables['nav_lat'][:]

    fig, [ax, axm] = plt.subplots(1, 2, figsize=(10, 3))

    # date ranges based on month and model_year
    sdt = datetime.datetime(model_year, month, 1)
    edt = sdt + datetime.timedelta(days=31)

    # Model variables and nowcast/spinup?
    if field == 'Salinity':
        model_field = 'vosaline'
    elif field == 'Temperatute':
        model_field = 'votemper'
    # Is this a nowcast?
    if model_year == 2014 or model_year == 2015:
        nowcast_flag = True
        title = 'Nowcast'
    else:
        nowcast_flag = False
        title = 'Spinup'

    # load model variables
    depth_mod, var_mod, dates_mod = load_model(model_path,
                                               sdt,
                                               edt,
                                               model_field,
                                               nowcast_flag=nowcast_flag)

    # plot obs and model
    data_m = data_obs[data_obs['Month'] == month]
    for dep_obs, var_obs, lon, lat, day in zip(data_m['Depth'], data_m[field],
                                               data_m['Longitude'],
                                               data_m['Latitude'],
                                               data_m['Day']):
        # model grid points
        [j, i] = tidetools.find_closest_model_point(lon, lat, X, Y, bathy)
        # model time index
        t_ind = []
        for count, date in enumerate(dates_mod):
            if date.month == month:
                if date.day == day:
                    t_ind = count
        var_plot = var_mod[t_ind, :, j, i]
        var_plot = np.ma.masked_values(var_plot, 0)

        ax.plot(var_obs, dep_obs, '-*r', label='obs', alpha=0.5)
        if j:
            try:
                ax.plot(var_plot, depth_mod, '-ob', label='model', alpha=0.5)
            except ValueError:
                print('No model data for {}/{}'.format(day, month))
        # plot location on map
        axm.plot(lon, lat, '*r')

    # Set plot axis and labels
    ax.set_ylim([zmax, zmin])
    ax.set_xlim([vmin, vmax])
    ax.set_title(title)
    ax.set_ylabel('Depth [m]')
    ax.set_xlabel(field)

    # plot mode coastline
    viz_tools.plot_coastline(axm, f, coords='map')
    axm.set_ylim([ymin, ymax])
    axm.set_xlim([xmin, xmax])
    axm.set_title('Month {}'.format(month))

    # fake the legend
    simObs, = ax.plot(-1, 0, 'r*')
    simMod, = ax.plot(-1, 0, 'bo')
    ax.legend([simObs, simMod], ['obs', 'model'], loc=0)

    return fig
Ejemplo n.º 14
0
def VENUS_location(grid_B, figsize=(10, 10)):
    """Plots the location of the VENUS Central, East and DDL nodes as well as
    Vancouver as a reference on a bathymetry map.

    :arg grid_B: Bathymetry dataset for the Salish Sea NEMO model.
    :type grid_B: :class:`netCDF4.Dataset`

    :arg figsize: Figure size (width, height) in inches.
    :type figsize: 2-tuple

    :returns: matplotlib figure object instance (fig).
    """

    lats = grid_B.variables["nav_lat"][:]
    lons = grid_B.variables["nav_lon"][:]
    bathy = grid_B.variables["Bathymetry"][:]
    levels = np.arange(0, 470, 50)

    fig, ax = plt.subplots(1, 1, figsize=figsize)
    fig.patch.set_facecolor("#2B3E50")
    cmap = plt.get_cmap("winter_r")
    cmap.set_bad("burlywood")
    mesh = ax.contourf(lons, lats, bathy, levels, cmap=cmap, extend="both")
    cbar = fig.colorbar(mesh)
    viz_tools.plot_land_mask(ax, grid_B, coords="map", color="burlywood")
    viz_tools.plot_coastline(ax, grid_B, coords="map")
    viz_tools.set_aspect(ax)

    lon_c = SITES["VENUS"]["Central"]["lon"]
    lat_c = SITES["VENUS"]["Central"]["lat"]
    lon_e = SITES["VENUS"]["East"]["lon"]
    lat_e = SITES["VENUS"]["East"]["lat"]
    lon_d = SITES["VENUS"]["ddl"]["lon"]
    lat_d = SITES["VENUS"]["ddl"]["lat"]
    lon_v = SITES["Vancouver"]["lon"]
    lat_v = SITES["Vancouver"]["lat"]

    ax.plot(lon_c,
            lat_c,
            marker="D",
            color="Black",
            markersize=10,
            markeredgewidth=2)
    bbox_args = dict(boxstyle="square", facecolor="white", alpha=0.8)
    ax.annotate(
        "Central",
        (lon_c - 0.11, lat_c + 0.04),
        fontsize=15,
        color="black",
        bbox=bbox_args,
    )

    ax.plot(lon_e,
            lat_e,
            marker="D",
            color="Black",
            markersize=10,
            markeredgewidth=2)
    bbox_args = dict(boxstyle="square", facecolor="white", alpha=0.8)
    ax.annotate("East", (lon_e + 0.04, lat_e + 0.01),
                fontsize=15,
                color="black",
                bbox=bbox_args)

    ax.plot(lon_d,
            lat_d,
            marker="D",
            color="Black",
            markersize=10,
            markeredgewidth=2)
    bbox_args = dict(boxstyle="square", facecolor="white", alpha=0.8)
    ax.annotate("DDL", (lon_d + 0.01, lat_d + 0.05),
                fontsize=15,
                color="black",
                bbox=bbox_args)

    ax.plot(lon_v,
            lat_v,
            marker="D",
            color="DarkMagenta",
            markersize=10,
            markeredgewidth=2)
    bbox_args = dict(boxstyle="square", facecolor="white", alpha=0.8)
    ax.annotate(
        "Vancouver",
        (lon_v - 0.15, lat_v + 0.04),
        fontsize=15,
        color="black",
        bbox=bbox_args,
    )

    ax.set_xlim([-124.02, -123.02])
    ax.set_ylim([48.5, 49.6])
    plt.setp(plt.getp(cbar.ax.axes, "yticklabels"), color="w")
    axis_colors(ax, "white")
    ax.set_xlabel("Longitude", **axis_font)
    ax.set_ylabel("Latitude", **axis_font)
    ax.set_title("VENUS Node Locations", **title_font)
    cbar.set_label("Depth [m]", **axis_font)

    return fig
Ejemplo n.º 15
0
def compare_ONC_model(csvfilename,
                      sdt,
                      edt,
                      grid_B,
                      results_home,
                      period='1h',
                      interp=False,
                      smin=30,
                      smax=35,
                      tmin=8,
                      tmax=12,
                      teos_to_psu=False):
    """Comparison between ONC mooring data in a date range and model results.

    :arg csvfilename: The file with the ONC data
    :type csvfilename: string

    :arg sdt: the start date of the date range
    :type sdt: datetime object

    :arg edt: the end date of the date range
    :type edt: datetime object

    :arg grid_B: the model bathymetry
    :type grid_B: netCDF handle

    :arg results_home: the path to the model results
    :type results_home: string

    :arg interp: a flag to specify if model should be interpolated to depth
     or just use closest model grid point
    :type interp: boolean

    :arg smin: minimum salinity for axis
    :type smin: float

    :arg smax: maximum salinity for axis
    :type smax: float

    :arg tmin: minimum temperature for axis
    :type tmin: float

    :arg tmax: maximum salinity for axis
    :type tmax: float

    :arg teos_to_psu: flag to convert model TEOS-10 'reference' salinity
                      practical salinity
    :type teos_to_psu: boolean

    :returns: figmap, fig - figure objects for the map and comaprisons plots
    """

    # Observations
    data, lat, lon, depth = load_mooring_csv(csvfilename)
    # resample observations and isolate date range
    data = isolate_dates(data, sdt, edt)
    data = resample_obs(data, period)
    # Model files
    sal, times, mdepths = load_model_data(sdt, edt, grid_B, results_home,
                                          period, 'vosaline', lat, lon)
    temp, times, mdepths = load_model_data(sdt, edt, grid_B, results_home,
                                           period, 'votemper', lat, lon)
    # Align model vertically
    sal, temp, text = model_vertical_postion(sal, temp, mdepths, depth, interp)
    if teos_to_psu:
        sal = teos_tools.teos_psu(sal)

    # Plotting
    fig, axs = plt.subplots(2, 1, figsize=(10, 7))
    # Salinity
    ax = axs[0]
    ax.plot(times, sal, label='model')
    qc_data = isolate_qc_data(data, 'Practical Salinity QC Flag  ')
    obs_sal = qc_data['Practical Salinity (psu)']
    ax.plot(qc_data['time'], obs_sal, label='observations')
    ax.plot([sdt, edt], [sal.mean(), sal.mean()], 'b--', label='model mean')
    ax.plot([sdt, edt], [obs_sal.mean(), obs_sal.mean()],
            'g--',
            label='observed mean')
    ax.set_ylabel('Practical Salinity [psu]')
    # Temperature
    ax = axs[1]
    ax.plot(times, temp, label='model')
    qc_data = isolate_qc_data(data, 'Temperature QC Flag  ')
    obs_temp = qc_data['Temperature (C)']
    ax.plot(qc_data['time'], obs_temp, label='observations')
    ax.plot([sdt, edt], [temp.mean(), temp.mean()], 'b--', label='model mean')
    ax.plot([sdt, edt], [obs_temp.mean(), obs_temp.mean()],
            'g--',
            label='observed mean')
    ax.set_ylabel('Temperature [C]')

    # Format figure
    title = '{} average - '.format(period) + text
    for ax, lims in zip(axs, [[smin, smax], [tmin, tmax]]):
        ax.set_xlim([sdt, edt])
        ax.set_ylim(lims)
        ax.legend(loc=0)
        ax.grid()
        ax.set_title(title)
    # Plot map
    figmap, ax = plt.subplots(1, 1)
    viz_tools.plot_coastline(ax, grid_B, coords='map')
    ax.plot(lon, lat, 'o')

    return figmap, fig
Ejemplo n.º 16
0
def _makeTiles(
    t_index,
    dsU,
    dsV,
    dsCoord,
    dsMask,
    dsBathy,
    theme,
    tile_coords_dic,
    expansion_factor,
):
    """
    Produce surface current tile figures for each tile at time index t_index
    """
    units = dsU.variables["time_counter"].units
    calendar = dsU.variables["time_counter"].calendar
    maskU, maskV = _prepareVelocity(t_index, dsU, dsV, dsCoord, dsMask)
    coord_xt, coord_yt = _prepareCoordinates(dsCoord)

    k = 3

    tiles = []
    figs = []
    for tile, values in tile_coords_dic.items():

        x1, x2, y1, y2 = values[0], values[1], values[2], values[3]
        sec = dsU.variables["time_counter"][t_index]

        if theme is None:
            fig = Figure(figsize=(8.5, 11), facecolor="white")
        else:
            fig = Figure(
                figsize=(11, 9), facecolor=theme.COLOURS["figure"]["facecolor"]
            )

        ax = fig.add_subplot(111)

        X, Y = coord_xt[::k, ::k].flatten(), coord_yt[::k, ::k].flatten()
        U, V = maskU[::k, ::k].flatten(), maskV[::k, ::k].flatten()

        i = numpy.logical_not(U.mask)
        XC, YC, UC, VC = X[i], Y[i], U[i].data, V[i].data

        # Add some vectors in the middle of the Atlantic to ensure we get at least one for each arrow size
        tempU = numpy.linspace(0, 5, 50)
        zeros = numpy.zeros(tempU.shape)
        XC = numpy.concatenate([XC, zeros])
        YC = numpy.concatenate([YC, zeros])
        UC = numpy.concatenate([UC, tempU])
        VC = numpy.concatenate([VC, zeros])
        SC = numpy.sqrt(UC ** 2 + VC ** 2)
        i = SC < 0.05
        if numpy.any(i):
            UCC, VCC, XCC, YCC = _cut(UC, VC, XC, YC, i)
            ax.scatter(XCC, YCC, s=2, c="k")

        # Arrow parameters: list of tuples of (speed_min, speed_max, arrow_width, arrow_head_width)
        arrowparamslist = [
            (0.05, 0.25, 0.003, 3.00),
            (0.25, 0.50, 0.005, 2.75),
            (0.50, 1.00, 0.007, 2.25),
            (1.00, 1.50, 0.009, 2.00),
            (1.50, 2.00, 0.011, 1.50),
            (2.00, 2.50, 0.013, 1.25),
            (2.50, 3.00, 0.015, 1.00),
            (3.00, 4.00, 0.017, 0.75),
            (4.00, 100, 0.020, 2.00),
        ]

        if theme is None:
            # Quiver key positions (x,y) relative to axes that spans [0,1]x[0,1]
            positionslist = [
                (0.55, 1.14),
                (0.55, 1.10),
                (0.55, 1.06),
                (0.55, 1.02),
                (0.80, 1.18),
                (0.80, 1.14),
                (0.80, 1.10),
                (0.80, 1.06),
                (0.80, 1.02),
            ]
            FP = None
            ax.text(0.53, 1.17, r"$\bullet$    < 0.05 m/s", transform=ax.transAxes)

        else:
            # Quiver key positions (x,y) relative to axes that spans [0,1]x[0,1]
            positionslist = [
                (1.05, 0.95),
                (1.05, 0.90),
                (1.05, 0.85),
                (1.05, 0.80),
                (1.05, 0.75),
                (1.05, 0.70),
                (1.05, 0.65),
                (1.05, 0.60),
                (1.05, 0.55),
            ]

            FP = theme.FONTS["axis"]
            fontsize = FP.get_size() - 4
            ax.text(
                1.03,
                0.98,
                r"$\bullet$    < 0.05 m/s",
                color=theme.COLOURS["text"]["axis"],
                fontsize=fontsize,
                transform=ax.transAxes,
            )

        # Draw each arrow
        for arrowparams, positions in zip(arrowparamslist, positionslist):
            _drawArrows(arrowparams, positions, UC, VC, XC, YC, SC, ax, theme, FP)

        ax.grid(True)

        # Use expansion factor to set axes limits
        dx = (x2 - x1) * expansion_factor
        dy = (y2 - y1) * expansion_factor
        ax.set_xlim([x1 - dx, x2 + dx])
        ax.set_ylim([y1 - dy, y2 + dy])

        # Decorations
        title = _createTileTitle(sec, units, calendar) + "\n" + tile
        x_label = "Longitude"
        y_label = "Latitude"

        if theme is None:
            title_notheme = "SalishSeaCast Surface Currents\n" + title + "\n"
            ax.set_title(title_notheme, fontsize=12, loc="left")
            ax.set_xlabel(x_label)
            ax.set_ylabel(y_label)
        else:
            ax.set_title(
                title,
                fontsize=10,
                color=theme.COLOURS["text"]["axis"],
                fontproperties=FP,
            )
            ax.set_xlabel(
                x_label,
                fontsize=8,
                color=theme.COLOURS["text"]["axis"],
                fontproperties=FP,
            )
            ax.set_ylabel(
                y_label, color=theme.COLOURS["text"]["axis"], fontproperties=FP
            )
            theme.set_axis_colors(
                ax
            )  # Makes the x and y numbers and axis lines into near-white

        x_tick_loc = ax.get_xticks()
        x_tick_label = ["{:.1f}".format(q) for q in x_tick_loc]
        ax.set_xticklabels(x_tick_label, rotation=45)

        viz_tools.plot_land_mask(
            ax, dsBathy, coords="map", color="burlywood", zorder=-9
        )
        ax.set_rasterization_zorder(-1)
        viz_tools.plot_coastline(ax, dsBathy, coords="map")
        viz_tools.set_aspect(ax, coords="map", lats=coord_yt)

        tiles += [tile]
        figs += [fig]
    return figs, tiles
Ejemplo n.º 17
0
def VENUS_location(grid_B, figsize=(10, 10)):
    """Plots the location of the VENUS Central, East and DDL nodes as well as
    Vancouver as a reference on a bathymetry map.

    :arg grid_B: Bathymetry dataset for the Salish Sea NEMO model.
    :type grid_B: :class:`netCDF4.Dataset`

    :arg figsize: Figure size (width, height) in inches.
    :type figsize: 2-tuple

    :returns: matplotlib figure object instance (fig).
    """

    lats = grid_B.variables['nav_lat'][:]
    lons = grid_B.variables['nav_lon'][:]
    bathy = grid_B.variables['Bathymetry'][:]
    levels = np.arange(0, 470, 50)

    fig, ax = plt.subplots(1, 1, figsize=figsize)
    fig.patch.set_facecolor('#2B3E50')
    cmap = plt.get_cmap('winter_r')
    cmap.set_bad('burlywood')
    mesh = ax.contourf(lons, lats, bathy, levels, cmap=cmap, extend='both')
    cbar = fig.colorbar(mesh)
    viz_tools.plot_land_mask(ax, grid_B, coords='map', color='burlywood')
    viz_tools.plot_coastline(ax, grid_B, coords='map')
    viz_tools.set_aspect(ax)

    lon_c = SITES['VENUS']['Central']['lon']
    lat_c = SITES['VENUS']['Central']['lat']
    lon_e = SITES['VENUS']['East']['lon']
    lat_e = SITES['VENUS']['East']['lat']
    lon_d = SITES['VENUS']['ddl']['lon']
    lat_d = SITES['VENUS']['ddl']['lat']
    lon_v = SITES['Vancouver']['lon']
    lat_v = SITES['Vancouver']['lat']

    ax.plot(
        lon_c,
        lat_c,
        marker='D',
        color='Black',
        markersize=10,
        markeredgewidth=2)
    bbox_args = dict(boxstyle='square', facecolor='white', alpha=0.8)
    ax.annotate(
        'Central',
        (lon_c - 0.11, lat_c + 0.04),
        fontsize=15,
        color='black',
        bbox=bbox_args)

    ax.plot(
        lon_e,
        lat_e,
        marker='D',
        color='Black',
        markersize=10,
        markeredgewidth=2)
    bbox_args = dict(boxstyle='square', facecolor='white', alpha=0.8)
    ax.annotate(
        'East',
        (lon_e + 0.04, lat_e + 0.01),
        fontsize=15,
        color='black',
        bbox=bbox_args)

    ax.plot(
        lon_d,
        lat_d,
        marker='D',
        color='Black',
        markersize=10,
        markeredgewidth=2)
    bbox_args = dict(boxstyle='square', facecolor='white', alpha=0.8)
    ax.annotate(
        'DDL',
        (lon_d + 0.01, lat_d + 0.05),
        fontsize=15,
        color='black',
        bbox=bbox_args)

    ax.plot(
        lon_v,
        lat_v,
        marker='D',
        color='DarkMagenta',
        markersize=10,
        markeredgewidth=2)
    bbox_args = dict(boxstyle='square', facecolor='white', alpha=0.8)
    ax.annotate(
        'Vancouver',
        (lon_v - 0.15, lat_v + 0.04),
        fontsize=15,
        color='black',
        bbox=bbox_args)

    ax.set_xlim([-124.02, -123.02])
    ax.set_ylim([48.5, 49.6])
    plt.setp(plt.getp(cbar.ax.axes, 'yticklabels'), color='w')
    figures.axis_colors(ax, 'white')
    ax.set_xlabel('Longitude', **axis_font)
    ax.set_ylabel('Latitude', **axis_font)
    ax.set_title('VENUS Node Locations', **title_font)
    cbar.set_label('Depth [m]', **axis_font)

    return fig
Ejemplo n.º 18
0
 def test_plot_coastline_defaults_bathy_netCDF_obj(self, m_dataset):
     axes, bathy = Mock(), Mock()
     bathy.variables = {'Bathymetry': Mock()}
     viz_tools.plot_coastline(axes, bathy)
     assert not m_dataset.called
     assert not m_dataset.close.called
Ejemplo n.º 19
0
 def test_plot_coastline_defaults_bathy_file(self, m_dataset):
     axes = Mock()
     viz_tools.plot_coastline(axes, 'bathyfile')
     m_dataset.assert_called_once_with('bathyfile')
     m_dataset().close.assert_called_once_with()
Ejemplo n.º 20
0
 def test_plot_coastline_no_yslice(self):
     axes, bathy = Mock(), Mock()
     bathy.variables = {'Bathymetry': Mock()}
     with pytest.raises(ValueError):
         viz_tools.plot_coastline(axes, bathy, xslice=np.arange(250, 370))
Ejemplo n.º 21
0
def compare_JEMS_model(stn, sdt, edt, grid_B, results_home,
                       smin=5, smax=31, tmin=8, tmax=12):
    """Comparison between all JEMS T+S data in a date range and model nowcasts.

    :arg stn: The JEMS station name
    :type stn: string

    :arg sdt: the start date of the date range
    :type sdt: datetime object

    :arg edt: the end date of the date range
    :type edt: datetime object

    :arg grid_B: the model bathymetry
    :type grid_B: netCDF handle

    :arg results_home: the path to the model results
    :type results_home: string

    :arg smin: minimum salinity for axis
    :type smin: float

    :arg smax: maximum salinity for axis
    :type smax: float

    :arg tmin: minimum temperature for axis
    :type tmin: float

    :arg tmax: maximum salinity for axis
    :type tmax: float

    :returns: figmap, fig - figure objects for the map and comaprisons plots
    """

    # Observations
    lat = SITES[stn]['lat']
    lon = SITES[stn]['lon']
    data = load_JEMS_csv(stn)
    data = isolate_dates(data, sdt, edt)
    data = data.groupby('date')

    # Model grid
    X = grid_B.variables['nav_lon'][:]
    Y = grid_B.variables['nav_lat'][:]
    bathy = grid_B.variables['Bathymetry'][:]
    [j, i] = tidetools.find_closest_model_point(lon, lat, X, Y, bathy)

    # Set up loop and figure
    num = data.ngroups
    fig, axs = plt.subplots(num, 2, figsize=(10, 4*num))
    try:
        for day, axS, axT in zip(data.groups, axs[:, 0], axs[:, 1]):
            plot_comparisons(day, axS, axT, results_home, data, stn, j, i)
            axS.set_xlim([smin, smax])
            axS.set_ylim([SITES[stn]['depth'], 0])
            axT.set_xlim([tmin, tmax])
            axT.set_ylim([SITES[stn]['depth'], 0])
        axS.set_xlabel('Salinity (psu)')
        axT.set_xlabel('Temperature (deg C)')
    except IndexError:
        day = data.groups.keys()[0]
        axS = axs[0]
        axT = axs[1]
        plot_comparisons(day, axS, axT, results_home, data, stn, j, i)
        axS.set_xlim([smin, smax])
        axS.set_ylim([SITES[stn]['depth'], 0])
        axT.set_xlim([tmin, tmax])
        axT.set_ylim([SITES[stn]['depth'], 0])
        axS.set_xlabel('Salinity (psu)')
        axT.set_xlabel('Temperature (deg C)')

    # map
    figmap, ax = plt.subplots(1, 1)
    viz_tools.plot_coastline(ax, grid_B, coords='map')
    ax.plot(lon, lat, 'o')
    ax.set_title(stn)

    return figmap, fig
Ejemplo n.º 22
0
def _make_figure_domain(coordf, bathyf, theme):
    """
    Create surface currents tiled domain figure showing the boundary and labels of each tile.

    :param coordf: Path to Salish Sea NEMO model coordinates file.
    :type coordf: :py:class:`pathlib.Path`

    :param bathyf: Path to Salish Sea NEMO model bathymetry file.
    :type bathyf: :py:class:`pathlib.Path`

    :param theme: Module-like object that defines the style elements for the
                figure. See :py:mod:`nowcast.figures.website_theme` for an
                example.

    :returns: :py:class:`matplotlib.figure.Figure` and plot axes.
    """

    if theme is None:
        fig = Figure(figsize=(8.5, 11), facecolor="white")
    else:
        fig = Figure(figsize=(5, 6),
                     dpi=100,
                     facecolor=theme.COLOURS["figure"]["facecolor"])

    ax = fig.add_subplot(111)
    ax.grid(True)

    # Decorations
    title = "Salish Sea"
    x_label = "Longitude"
    y_label = "Latitude"

    if theme is None:
        ax.set_title(title, fontsize=10)
        ax.set_xlabel(x_label)
        ax.set_ylabel(y_label)
    else:
        ax.set_title(
            title,
            fontsize=10,
            color=theme.COLOURS["text"]["axis"],
            fontproperties=theme.FONTS["axis"],
        )
        ax.set_xlabel(
            x_label,
            color=theme.COLOURS["text"]["axis"],
            fontproperties=theme.FONTS["axis"],
        )
        ax.set_ylabel(
            y_label,
            color=theme.COLOURS["text"]["axis"],
            fontproperties=theme.FONTS["axis"],
        )
        theme.set_axis_colors(
            ax)  # Makes the x and y numbers and axis lines into near-white

    with netCDF4.Dataset(bathyf) as _dsBathy:
        viz_tools.plot_land_mask(ax,
                                 _dsBathy,
                                 coords="map",
                                 color="burlywood",
                                 zorder=-9)
        ax.set_rasterization_zorder(-1)
        viz_tools.plot_coastline(ax, _dsBathy, coords="map")

    with netCDF4.Dataset(coordf) as _dsCoord:
        coord_yt = _dsCoord.variables["gphit"][0, :, :]
        viz_tools.set_aspect(ax, coords="map", lats=coord_yt)

    _drawTile(tile_coords_dic, ax)

    return fig, ax