Пример #1
0
def plottimeavADCP(grid_m, grid_o, day, station):
    """ This function plots a comparison of the time averaged velocities of the
    model and the observations.

    :arg grid_m: The model grid
    :type grid_m: neCDF4 dataset.

    :arg grid_o: The observational grid
    :type grid_o: dictionary

    :arg day: day of interest
    :type day: datetime object

    :arg station: Station of interest. Either 'Central' or 'East' or 'ddl'
    :type station: string

    :return: fig
    """
    if station == 'Central':
        profile = [0, 290]
    elif station == 'East':
        profile = [0, 150]
    else:
        profile = [0, 150]

    # Get grids into unstaggered and masked velocities at the chose depths
    u_E, v_N, dep_t = load_vel(day, grid_m, 'model', station, profile)
    u, v, dep = load_vel(day, grid_o, 'observation', station, profile)

    # Begin figure
    fig, ([ax1, ax2]) = plt.subplots(1, 2, figsize=(8, 10), sharex=True)
    fig.patch.set_facecolor('#2B3E50')

    # Setting the date for title
    date = day.strftime('%d%b%y')

    velocities = [u_E[:, :-1], v_N[:, :-1]]
    vellast = [u_E[:, -2:], v_N[:, -2:]]
    veloobs = [u, v]
    axes = [ax1, ax2]
    direction = ['E/W', 'N/S']

    for ax, vel, velo, lastvel, direc in zip(
            axes, velocities, veloobs, vellast, direction):
        ax.plot(np.nanmean(vel, axis=0), dep_t[:-1],  label='Model')
        ax.plot(np.nanmean(velo, axis=1), dep[:], label='Observations')
        ax.plot(np.nanmean(
            lastvel, axis=0), dep_t[-2:], '--b', label='Bottom grid cell')
        ax.set_xlabel('Daily averaged velocity [m/s]', **axis_font)
        ax.set_ylabel('Depth [m]', **axis_font)
        figures.axis_colors(ax, 'gray')
        ax.set_title(f'{direc} velocities at VENUS {station}', **title_font)
        ax.grid()
        ax.set_ylim(profile)
        ax.set_xlim([-0.5, 0.5])
        ax.invert_yaxis()
    ax1.legend(loc=0)

    return fig
Пример #2
0
def plotdepavADCP(grid_m, grid_o, day, station):
    """ This function plots a comparison of the depth averaged velocities of
    the model and the observations.

    :arg grid_m: The model grid
    :type grid_m: netCDF4 dataset.

    :arg grid_o: The observational grid
    :type grid_o: dictionary

    :arg day: day of interest
    :type day: datetime object

    :arg station: Station of interest. Either 'Central' or 'East' or 'ddl'
    :type station: string

    :return: fig
    """
    if station == 'Central':
        profile = [40, 270]
    elif station == 'East':
        profile = [30, 150]
    else:
        profile = [25, 130]

    # Get grids into unstaggered and masked velocities at the chose depths
    u_E, v_N, dep_t = load_vel(day, grid_m, 'model', station, profile)
    u, v, dep = load_vel(day, grid_o, 'observation', station, profile)

    # Depth averaging center of water column
    uE_av = analyze.depth_average(u_E, dep_t, 1)
    vN_av = analyze.depth_average(v_N, dep_t, 1)
    u_av = analyze.depth_average(u, dep[::-1], 0)
    v_av = analyze.depth_average(v, dep[::-1], 0)

    # Begin figure
    fig, ([ax1, ax2]) = plt.subplots(2, 1, figsize=(15, 10), sharex=True)
    fig.patch.set_facecolor('#2B3E50')

    # Setting the date for title
    date = day.strftime('%d%b%y')

    timestep = 0.5
    velocities = [uE_av, vN_av]
    veloobs = [u_av, v_av]
    axes = [ax1, ax2]
    direction = ['East/West', 'North/South']

    for ax, vel, velo, direc in zip(axes, velocities, veloobs, direction):
        ax.plot(np.arange(0, 24, timestep/2), vel, label='Model')
        ax.plot(np.arange(0.25, 24, timestep), velo, label='Observations')
        ax.set_xlim([0, 24])
        ax.set_ylabel('Velocity [m/s]', **axis_font)
        figures.axis_colors(ax, 'gray')
        ax.set_title(
            f'Depth Averaged ({profile[0]}-{profile[1]}m) {direc} velocities '
            f'at VENUS {station} -{date}',
            **title_font)
        ax.grid()
        ax.set_ylim([-0.6, 0.6])
    ax1.legend(loc=0)
    ax2.set_xlabel('Hour [UTC]')

    return fig
Пример #3
0
def plotADCP(grid_m, grid_o, day, station, profile):
    """ This function will plots the velocities on a colour map with depth of the
    model and observational values.
    data over a whole day at a particular station.

    :arg grid_m: The model grid
    :type grid_m: neCDF4 dataset.

    :arg grid_o: The observational grid
    :type grid_o: dictionary

    :arg day: day of interest
    :type day: datetime object

    :arg station: Station of interest. Either 'Central' or 'East' or 'ddl'.
    :type station: string

    :arg profile: the range of depths that will be looked at in meters.
        (ex. [min, max])
    :type profile: list

    :return: fig
    """
    # Get grids into unstaggered and masked velocities at the chose depths
    u_E, v_N, dep_t = load_vel(day, grid_m, 'model', station, profile)
    u, v, dep = load_vel(day, grid_o, 'observation', station, profile)

    # Begin figure
    fig, ([axmu, axou], [axmv, axov]) = plt.subplots(
        2, 2,
        figsize=(20, 10),
        sharex=True)
    fig.patch.set_facecolor('#2B3E50')

    # Find the absolute maximum value between the model and observational
    # velocities to set the colorbar
    max_v = np.nanmax(abs(v))
    max_u = np.nanmax(abs(u))
    max_vm = np.nanmax(abs(v_N))
    max_um = np.nanmax(abs(u_E))
    max_speed = np.amax([max_v, max_u, max_vm, max_um])
    vmax = np.ceil(max_speed*10)/10.0
    vmin = - vmax
    step = 0.05
    cs = np.arange(vmin, vmax + step, step)

    cmap = plt.get_cmap('bwr')

    # Setting the date for title
    date = day.strftime('%d%b%y')

    # Plotting the comparison between the model and the obs velocities
    increment = [0.25, 0.5, 0.25, 0.5]
    velocities = [u_E.transpose(), u, v_N.transpose(), v]
    axes = [axmu, axou, axmv, axov]
    depths = [dep_t, dep, dep_t, dep]
    names = ['Model', 'Observations', 'Model', 'Observations']
    direction = ['East/West', 'East/West', 'North/South', 'North/South']

    for ax, vel, timestep, depth, name, direc in zip(
            axes,
            velocities,
            increment,
            depths,
            names,
            direction):
        ax.invert_yaxis()
        mesh = ax.contourf(
            # The range below adjusts for the observations starting at 00:15
            # and being in 30 minutes increments.
            np.arange(timestep-0.25, 24+timestep-0.25, timestep),
            depth[:],
            vel,
            cs, cmap=cmap)
        ax.set_ylim([profile[1], profile[0]])
        ax.set_xlim([0.25, 23])
        ax.set_ylabel('Depth [m]', **axis_font)

        figures.axis_colors(ax, 'gray')
        ax.set_title(
            f'{direc} {name} Velocities at VENUS {station} - {date}',
            **title_font)

    cbar_ax = fig.add_axes([0.95, 0.2, 0.03, 0.6])
    cbar = fig.colorbar(mesh, cax=cbar_ax)
    plt.setp(plt.getp(cbar.ax.axes, 'yticklabels'), color='w')
    cbar.set_label('[m/s]', **axis_font)
    axmv.set_xlabel('Hour [UTC]', **axis_font)
    axov.set_xlabel('Hour [UTC]', **axis_font)

    return fig
Пример #4
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
Пример #5
0
def plot_vel_NE_gridded(station, grid, figsize=(14, 10)):
    """Plots the hourly averaged North/South and East/West velocities at a chosen
    VENUS node station using data that is calculated every 15 minutes.

    :arg station: Name of the station ('East' or 'Central')
    :type station: string

    :arg grid: Quarter-hourly velocity and tracer results dataset from NEMO.
    :type grid: :class:`netCDF4.Dataset`

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

    :returns: matplotlib figure object instance (fig).
    """
    u_u = grid.variables['vozocrtx']
    v_v = grid.variables['vomecrty']
    w_w = grid.variables['vovecrtz']
    dep_t = grid.variables['depthv']
    dep_w = grid.variables['depthw']
    t = grid.variables['time_counter']
    dt = (t[1]-t[0])/3600.
    maxt = dt*t.shape[0]
    t_axis = np.arange(0, maxt, dt)

    u_E, v_N = unstag_rot(u_u, v_v)
    u_E = u_E[..., 0, 0]
    v_N = v_N[..., 0, 0]

    fig, (axu, axv, axw) = plt.subplots(3, 1, figsize=figsize, sharex=True)
    fig.patch.set_facecolor('#2B3E50')

    max_array = np.maximum(abs(v_N), abs(u_E))
    max_speed = np.amax(max_array)
    vmax = max_speed
    vmin = - max_speed
    step = 0.03

    # viz_tools.set_aspect(axu)
    timestamp = nc_tools.timestamp(grid, 0)
    cmap = plt.get_cmap('jet')
    dep_s = SITES['VENUS'][station]['depth']

    axu.invert_yaxis()
    mesh = axu.contourf(
        t_axis,
        dep_t[:],
        u_E.transpose(),
        np.arange(vmin, vmax, step), cmap=cmap)
    cbar = fig.colorbar(mesh, ax=axu)
    axu.set_ylim([dep_s, 0])
    axu.set_xlim([0, maxt])
    axu.set_ylabel('Depth [m]', **axis_font)
    figures.axis_colors(axu, 'white')
    axu.set_title(
        f'East/West Velocities at VENUS {station} on '
        f'{timestamp.format("DD-MMM-YYYY")}', **title_font)
    plt.setp(plt.getp(cbar.ax.axes, 'yticklabels'), color='w')
    cbar.set_label('[m/s]', **axis_font)

    axv.invert_yaxis()
    mesh = axv.contourf(
        t_axis,
        dep_t[:],
        v_N.transpose(),
        np.arange(vmin, vmax, step),
        cmap=cmap)
    cbar = fig.colorbar(mesh, ax=axv)
    axv.set_ylim([dep_s, 0])
    axv.set_xlim([0, maxt])
    axv.set_ylabel('Depth [m]', **axis_font)
    figures.axis_colors(axv, 'white')
    axv.set_title(
        f'North/South Velocities at VENUS {station} on '
        f'{timestamp.format("DD-MMM-YYYY")}', **title_font)
    plt.setp(plt.getp(cbar.ax.axes, 'yticklabels'), color='w')
    cbar.set_label('[m/s]', **axis_font)

    axw.invert_yaxis()
    mesh = axw.contourf(
        t_axis, dep_w[:],
        w_w[:, :, 1, 1].transpose(),
        np.arange(vmin/70, vmax/70, step/80),
        cmap=cmap)
    cbar = fig.colorbar(mesh, ax=axw)
    axw.set_ylim([dep_s, 0])
    axw.set_xlim([0, maxt])
    axw.set_xlabel('Time [h]', **axis_font)
    axw.set_ylabel('Depth [m]', **axis_font)
    figures.axis_colors(axw, 'white')
    axw.set_title(
        f'Vertical Velocities at VENUS {station} on '
        f'{timestamp.format("DD-MMM-YYYY")}', **title_font)
    plt.setp(plt.getp(cbar.ax.axes, 'yticklabels'), color='w')
    cbar.set_label('[m/s]', **axis_font)

    return fig
Пример #6
0
def compare_VENUS(station, grid_T, grid_B, figsize=(6, 10)):
    """Compares the model's temperature and salinity with observations from
    VENUS station.

    :arg station: Name of the station ('East' or 'Central')
    :type station: string

    :arg grid_T: Hourly tracer results dataset from NEMO.
    :type grid_T: :class:`netCDF4.Dataset`

    :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).
    """

    # Time range
    t_orig, t_end, t = figures.get_model_time_variables(grid_T)

    # Bathymetry
    bathy, X, Y = tt.get_bathy_data(grid_B)

    # VENUS data
    fig, (ax_sal, ax_temp) = plt.subplots(2, 1, figsize=figsize, sharex=True)
    fig.patch.set_facecolor('#2B3E50')
    fig.autofmt_xdate()
    lon = SITES['VENUS'][station]['lon']
    lat = SITES['VENUS'][station]['lat']
    depth = SITES['VENUS'][station]['depth']

    # Plotting observations
    plot_VENUS(ax_sal, ax_temp, station, t_orig, t_end)

    # Grid point of VENUS station
    [j, i] = geo_tools.find_closest_model_point(
        lon, lat, X, Y)

    # Model data
    sal = grid_T.variables['vosaline'][:, :, j, i]
    temp = grid_T.variables['votemper'][:, :, j, i]
    ds = grid_T.variables['deptht']

    # Interpolating data
    salc = []
    tempc = []
    for ind in np.arange(0, sal.shape[0]):
        salc.append(figures.interpolate_depth(sal[ind, :], ds, depth))
        tempc.append(figures.interpolate_depth(temp[ind, :], ds, depth))

    # Plot model data
    ax_sal.plot(t, salc, '-b', label='Model')
    ax_temp.plot(t, tempc, '-b', label='Model')

    # Axis
    ax_sal.set_title(f'VENUS {station} - {t[0].strftime("%d-%b-%Y")}')
    ax_sal.set_ylim([29, 32])
    ax_sal.set_ylabel('Practical Salinity [psu]', **axis_font)
    ax_sal.legend(loc=0)
    ax_temp.set_ylim([7, 13])
    ax_temp.set_xlabel('Time [UTC]', **axis_font)
    ax_temp.set_ylabel('Temperature [deg C]', **axis_font)
    figures.axis_colors(ax_sal, 'gray')
    figures.axis_colors(ax_temp, 'gray')

    # Text box
    ax_temp.text(0.25, -0.3, 'Observations from Ocean Networks Canada',
                 transform=ax_temp.transAxes, color='white')

    return fig
Пример #7
0
def salinity_ferry_route(
        ferry_data_dir,
        grid_T_hr,
        bathy,
        route_name,
        dmy,
        figsize=(20, 7.5),
):
    """Plot daily salinity comparisons between ferry observations and model
    results as well as ferry route with model salinity distribution.

    :arg str ferry_data_dir: storage file location for ONC ferry data.

    :arg grid_T_hr: Hourly tracer results dataset from NEMO.
    :type grid_T_hr: :class:`netCDF4.Dataset

    :arg bathy: model bathymetry
    :type bathy: numpy array

    :arg str route_name: route name of these three ferry routes respectively

    :arg str dmy: date in form ddmonyy

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

    :returns: matplotlib figure object instance (fig).
    """
    # Grid region to plot
    si, ei = 200, 610
    sj, ej = 20, 370
    lons = grid_T_hr.variables['nav_lon'][si:ei, sj:ej]
    lats = grid_T_hr.variables['nav_lat'][si:ei, sj:ej]
    # Salinity calculated by NEMO and observed by ONC ferry package
    model_depth_level = 1  # 1.5 m
    ## TODO: model time step for salinity contour map should be calculated from
    ##       ferry route time
    model_time_step = 3  # 02:30 UTC
    sal_hr = grid_T_hr.variables['vosaline']
    ## TODO: Use mesh mask instead of 0 for masking
    sal_masked = np.ma.masked_values(
        sal_hr[model_time_step, model_depth_level, si:ei, sj:ej], 0)
    sal_t = teos_tools.psu_teos(sal_masked)
    sal_obs = ferry_salinity(ferry_data_dir, route_name, dmy)
    nemo_a, nemo_b = nemo_sal_route(grid_T_hr, bathy, route_name, sal_obs)

    fig, axs = plt.subplots(1, 2, figsize=figsize)
    axs[1].set_axis_bgcolor("burlywood")
    viz_tools.set_aspect(axs[1], coords='map', lats=lats)
    cmap = plt.get_cmap('plasma')
    axs[1].set_xlim(-124.5, -122.5)
    axs[1].set_ylim(48.3, 49.6)

    # Plot model salinity
    mesh = axs[1].contourf(lons, lats, sal_t, 20, cmap=cmap)
    cbar = plt.colorbar(mesh, ax=axs[1])
    cbar.ax.axes.tick_params(labelcolor='w')
    cbar.set_label('Absolute Salinity [g/kg]', color='white', **axis_font)
    axs[1].set_title('Ferry Route: 3am[UTC] 1.5m model result ', **title_font)
    axs[1].set_xlabel('Longitude [°E]', **axis_font)
    axs[1].set_ylabel('Latitude [°N]', **axis_font)

    # Plot ferry route.
    axs[1].plot(sal_obs[1], sal_obs[2], 'black', linewidth=4)
    figures.axis_colors(axs[1], 'grey')

    # Add locations and markers on plot for orientation
    bbox_args = dict(boxstyle='square', facecolor='white', alpha=0.7)
    places = [
        FERRY_ROUTES[route_name]['start']['terminal'],
        FERRY_ROUTES[route_name]['end']['terminal'], 'Vancouver'
    ]
    label_offsets = [0.04, -0.4, 0.09]
    for stn, loc in zip(places, label_offsets):
        axs[1].plot(*PLACES[stn]['lon lat'],
                    marker='D',
                    color='white',
                    markersize=10,
                    markeredgewidth=2)
        axs[1].annotate(
            stn, (PLACES[stn]['lon lat'][0] + loc, PLACES[stn]['lon lat'][1]),
            fontsize=15,
            color='black',
            bbox=bbox_args)

    # Set up model part of salinity comparison plot
    axs[0].plot(sal_obs[1],
                nemo_a,
                'DodgerBlue',
                linewidth=2,
                label=f'{FERRY_ROUTES[route_name]["start"]["hour"]} am [UTC]')
    axs[0].plot(
        sal_obs[1],
        nemo_b,
        'MediumBlue',
        linewidth=2,
        label=f'{FERRY_ROUTES[route_name]["start"]["hour"]+1} am [UTC]')

    # Observational component of salinity comparisons plot
    axs[0].plot(sal_obs[1],
                sal_obs[3],
                'DarkGreen',
                linewidth=2,
                label="Observed")
    axs[0].text(0.25,
                -0.1,
                'Observations from Ocean Networks Canada',
                transform=axs[0].transAxes,
                color='white')

    axs[0].set_xlim(-124, -123)
    axs[0].set_ylim(10, 32)
    axs[0].set_title('Surface Salinity: ' + dmy, **title_font)
    axs[0].set_xlabel('Longitude', **axis_font)
    axs[0].set_ylabel('Absolute Salinity [g/kg]', **axis_font)
    axs[0].legend(loc=3)
    axs[0].grid(axis='both')

    fig.patch.set_facecolor('#2B3E50')
    figures.axis_colors(axs[0], 'grey')

    return fig