Пример #1
0
def main(cubes):
    # Load the data
    res = convert.calc('residual_pv', cubes)
    pv = convert.calc('ertel_potential_vorticity', cubes)
    expected_pv = pv - res

    stats = []
    # Calculation correlation on each model level
    for n in range(pv.shape[0]):
        stats.append(
            linregress(pv[n].data.flatten(), expected_pv[n].data.flatten()))

    stats = np.array(stats)
    print(stats.shape)

    fig = plt.figure(figsize=(18, 20))
    ax = plt.subplot2grid((2, 2), (0, 0))
    plt.plot(stats[:, 2])
    plt.title('Correlation Coefficient')

    ax = plt.subplot2grid((2, 2), (1, 0))
    plt.plot(stats[:, 0])
    plt.title('Gradient')

    ax = plt.subplot2grid((2, 2), (1, 1))
    plt.plot(stats[:, 1])
    plt.title('Intercept')

    plt.show()
Пример #2
0
def pv(forecast, analysis, variable, levels, **kwargs):
    pv_f = convert.calc(variable, forecast, levels=levels)[0]
    pv_a = convert.calc(variable, analysis, levels=levels)[0]

    err = pv_f - pv_a
    axes = []

    # Initialise the plot
    fig = plt.figure(figsize=(18, 20))

    axes.append(plt.subplot2grid((25, 4), (0, 0), colspan=2, rowspan=10))
    im = make_pv_plot(pv_f, **kwargs)
    plt.title('Forecast')

    axes.append(plt.subplot2grid((25, 4), (0, 2), colspan=2, rowspan=10))
    im = make_pv_plot(pv_a, **kwargs)
    plt.title('Analysis')

    ax = plt.subplot2grid((25, 4), (10, 1), colspan=2, rowspan=1)
    cbar = plt.colorbar(im, cax=ax, orientation='horizontal')

    axes.append(plt.subplot2grid((25, 4), (13, 1), colspan=2, rowspan=10))
    im = iplt.pcolormesh(err, vmin=-5, vmax=5, cmap='coolwarm')
    iplt.contour(pv_f, [2], colors='k', linewidths=2)
    iplt.contour(pv_a, [2], colors='k', linewidths=2, linestyles='--')
    add_map()
    plt.title('Forecast Minus Analysis')

    ax = plt.subplot2grid((25, 4), (23, 1), colspan=2, rowspan=1)
    cbar = plt.colorbar(im, cax=ax, orientation='horizontal')

    for n, ax in enumerate(axes):
        ax.set_title(ascii_lowercase[n].ljust(20))
    plt.show()
Пример #3
0
def main(cubes):
    theta = convert.calc('equivalent_potential_temperature', cubes)
    P = convert.calc('air_pressure', cubes)
    P.convert_units('hPa')
    mass = convert.calc('mass', cubes)

    lon, lat = grid.true_coords(theta)
    lonmask = np.logical_or(lon < -15, lon > 5)
    latmask = np.logical_or(lat < 47.5, lat > 62.5)
    areamask = np.logical_or(lonmask, latmask)

    masks = [
        np.logical_or(theta.data < theta_front, areamask),
        np.logical_or(theta.data > theta_front, areamask)
    ]

    #overview(cubes, areamask)
    #plt.savefig(plotdir + 'composite_iop8_24h_overview_750hpa.pdf')
    # plt.show()

    z_cold, z_warm = bl_heights(cubes, theta, areamask)

    # Initialise the plot
    fig = plt.figure(figsize=(18, 12))

    diags = convert.calc(names, cubes)
    masses = []
    # Rows are different masks
    for n, mask in enumerate(masks):
        means = diagnostics.averaged_over(diags, levels, P, mass, mask)
        masses.append(convert.calc('mass', means))
        # Columns are for different mappings
        for m, mapping in enumerate(mappings):
            ax = plt.subplot2grid((2, ncol), (n, m))
            composite(means, ax, mapping, mass, P)
            add_trimmings(ax, n, m)
            if m == 0:
                ax.set_xlim(0.1, 1.3)
            elif m == 1:
                ax.set_xlim(-0.6, 0.6)
            else:
                ax.set_xlim(-1, 1)

            multilabel(ax, 3 * n + m, yreversed=True, fontsize=25)

            if n == 0:
                plt.axhline(z_cold, color='k', linestyle='--')
            elif n == 1:
                plt.axhline(z_warm, color='k', linestyle='--')
    add_figlabels(fig)
    fig.savefig(plotdir + 'composite_iop5_24h.pdf')

    plt.figure()
    for mass in masses:
        qplt.plot(mass, mass.coord('air_pressure'))
        ax.set_ylim(950, 500)

    plt.show()

    return
Пример #4
0
def main(cubes, **kwargs):
    """Calculate and plot the distance from the tropopause to cloud
    """
    pv = convert.calc('ertel_potential_vorticity', cubes)
    cl = convert.calc('mass_fraction_of_cloud', cubes)

    # Get altitude as a cube
    z = grid.make_cube(pv, 'altitude')

    # Add pv and cloud as coordinates to the altitude cube
    pv = grid.make_coord(pv)
    z.add_aux_coord(pv, [0, 1, 2])
    cl = grid.make_coord(cl)
    z.add_aux_coord(cl, [0, 1, 2])

    # Calculate the height of the cloud top
    z_cloud = interpolate.to_level(z, mass_fraction_of_cloud=[1e-5])[0]

    # Calculate the height of the tropopause
    z_pv2 = interpolate.to_level(z, ertel_potential_vorticity=[2])[0]

    # Calculate the distance from tropopause to cloud
    dz = z_pv2.data - z_cloud.data
    dz = z_pv2.copy(data=dz)

    # Plot
    plot.pcolormesh(dz, **kwargs)
    plt.show()
Пример #5
0
def get_startpoints(cubes):
    """Find all points within 1km of the tropopause that have a negative PV
    anomaly
    """
    # Find the tropopause height
    pv = convert.calc('ertel_potential_vorticity', cubes)
    grid.add_hybrid_height(pv)
    z = grid.make_cube(pv, 'altitude').data
    zpv2 = get_tropopause_height(pv).data * np.ones_like(z)

    # Find point below the tropopause
    tropopause_relative = np.logical_and(z < zpv2, z > zpv2 - 2000)

    # Find negative pv anomalies
    diff = convert.calc('total_minus_advection_only_pv', cubes)
    negative_pv = diff.data < -1

    # Combine criteria
    criteria = np.logical_and(negative_pv, tropopause_relative)

    # Get indices where criterion is met
    indices = np.where(criteria)

    # Convert to lon, lat, z
    longitude = pv.coord('grid_longitude').points
    lons = np.array([longitude[idx] for idx in indices[2]])
    latitude = pv.coord('grid_latitude').points
    lats = np.array([latitude[idx] for idx in indices[1]])
    height = pv.coord('level_height').points
    altitude = np.array([height[idx] for idx in indices[0]])

    # Make start points array
    start_points = np.array([lons, lats, altitude]).transpose()

    return start_points
Пример #6
0
def make_plot(forecast, analysis, variable, levels, units, errlevs, clevs,
              cmap='coolwarm', mask=None):
    # Extract data and errors
    f = convert.calc(variable, forecast, levels=levels)[0]
    a = convert.calc(variable, analysis, levels=levels)[0]
    err = f - a

    for cube in [f, a, err]:
        cube.convert_units(units)

    if mask is not None:
        for cube in [f, a]:
            cube.data = np.ma.masked_where(mask, cube.data)

    # Plot error
    iplt.contourf(err, errlevs, cmap=cmap, extend='both')
    add_map()
    cbar = plt.colorbar(orientation='horizontal', spacing='proportional')
    errlevs.append(0)
    cbar.set_ticks(errlevs)
    cbar.set_label(units)

    # Overlay forecast and analysis
    cs = iplt.contour(f, clevs, colors='k', linewidths=2)
    iplt.contour(a, clevs, colors='k', linewidths=2, linestyles='--')
    plt.clabel(cs, fmt='%1.0f', colors='k')

    return
Пример #7
0
def main():
    # Load the variables
    cubes = forecast.set_lead_time(hours=18)
    x = convert.calc(names, cubes)
    surface = convert.calc('boundary_layer_height', cubes)

    # Mask points within 100 gridpoints of land
    z = convert.calc('altitude', cubes)
    zm = filters.maximum_filter(z[0].data, 100)
    mask = zm > 20

    # Interpolate relative to boundary layer height
    output = diagnostics.profile(x, surface, dz, mask=mask)

    # Plot the variables
    for cube in output:
        c = second_analysis.all_diagnostics[cube.name()]
        iplt.plot(cube,
                  cube.coord('distance_from_boundary_layer_height'),
                  color=c.color,
                  linestyle=c.linestyle,
                  label=c.symbol)

    plt.axvline(color='k')
    plt.axhline(color='k')
    legend(key=second_analysis.get_idx, loc='best', ncol=2)

    plt.show()

    return
Пример #8
0
def height(cubes):
    # Calculate the tropopause height
    pv = convert.calc('ertel_potential_vorticity', cubes)
    q = convert.calc('specific_humidity', cubes)
    trop, fold_t, fold_b = tropopause.dynamical(pv, q)

    return trop, fold_t, fold_b
Пример #9
0
def main(cubes):
    lon, lat = grid.true_coords(cubes[0])
    z300 = convert.calc('altitude',
                        cubes,
                        levels=('equivalent_potential_temperature', [300]))[0]
    z300.convert_units('km')
    mslp = convert.calc('air_pressure_at_sea_level', cubes)
    mslp.convert_units('hPa')

    # Plot overview
    plot.contourf(z300, np.linspace(0, 10, 11))
    cs = iplt.contour(mslp, np.linspace(950, 1050, 11), colors='k')
    plt.clabel(cs, fmt='%1.0f')

    # Warm Sector
    warm_sector = z300.data.mask
    plim = mslp.data < 1000
    loc = np.logical_and(lon > -10, lon < 5)
    ws_mask = np.logical_and(np.logical_and(warm_sector, loc), plim)
    ws_mask = mslp.copy(data=ws_mask)
    iplt.contour(ws_mask, linestyles='--', colors='r')

    # Cold Sector
    cold_sector = z300.data < 5
    loc = np.logical_and(loc, lat < 65)
    cs_mask = np.logical_and(np.logical_and(cold_sector, loc), plim)
    cs_mask = mslp.copy(data=cs_mask)
    iplt.contour(cs_mask, linestyles='--', colors='b')

    plt.title(r'$z(\theta_e = 300)$')

    return
Пример #10
0
def pv_tracer(cubes, name, vmin=-2, vmax=2, cmap='coolwarm'):
    cube = convert.calc(name, cubes)
    epv = convert.calc('ertel_potential_vorticity', cubes)
    adv = convert.calc('advection_only_pv', cubes)

    plot.pcolormesh(cube, pv=epv, vmin=vmin, vmax=vmax, cmap=cmap)

    adv.data = np.abs(adv.data)
    iplt.contour(adv, [2], colors='k', linestyle='--')

    return
Пример #11
0
def mass_integrals(cubes, x, y, glat, gridpoints, theta_level, dtheta):
    """

    Args:
        cubes (iris.cube.CubeList):
        x (np.Array): Circuit longitudes
        y (np.Array): Circuit latitudes
        glat (np.array): Grid latitudes
        gridpoints(np.Array): Array of gridpoint longitudes and latitudes of
            shape (ngp, 2)
        theta_level:
        dtheta (int): Isentrope spacing used to calculate volume integrals

    Returns:

    """
    # Include points within circuit boundary
    points = np.array([x, y]).transpose()
    pth = Path(points)

    # Mask all points that are not contained in the circuit
    mask = np.logical_not(pth.contains_points(gridpoints).reshape(glat.shape))

    # Area = r**2 cos(phi) dlambda dphi
    levels = ('air_potential_temperature',
              [theta_level - dtheta / 2.0, theta_level,
               theta_level + dtheta / 2.0])
    zth = convert.calc('altitude', cubes, levels=levels)
    area = (a + zth[1]) ** 2 * np.cos(np.deg2rad(glat)) * np.deg2rad(0.11) ** 2
    area.units = 'm^2'
    area.rename('area')
    total_area = integrate(area, mask)

    # Volume = area * dz
    volume = area * (zth[2] - zth[0])
    volume.rename('volume')
    total_volume = integrate(volume, mask)

    # Mass = density * volume
    levels = ('air_potential_temperature', [theta_level])
    density = convert.calc('air_density', cubes, levels=levels)[0]
    mass = density * volume
    mass.rename('mass')
    total_mass = integrate(mass, mask)

    # Circulation = \int rho.pv.dv / dtheta
    pv = convert.calc('ertel_potential_vorticity', cubes, levels=levels)[0]
    pv.convert_units('m^2 K s-1 kg-1')
    pv_substance = pv * mass
    circulation = integrate(pv_substance, mask) / dtheta

    circulation.rename('mass_integrated_circulation')

    return total_area, total_volume, total_mass, circulation
Пример #12
0
def make_plots(forecast, analysis, variable, levels, units, errlevs, clevs,
               cmap1='plasma', cmap='coolwarm', mask=None):
    # Extract data and errors
    f = convert.calc(variable, forecast, levels=levels)[0]
    a = convert.calc(variable, analysis, levels=levels)[0]
    err = f - a

    for cube in [f, a, err]:
        cube.convert_units(units)

    if mask is not None:
        for cube in [f, a]:
            cube.data = np.ma.masked_where(mask, cube.data)

    # Initialise the plot
    plt.figure(figsize=(18, 15))

    # Plot absolute values
    plt.subplot2grid((25, 4), (0, 0), colspan=2, rowspan=10)
    im = iplt.contourf(f, clevs, extend='both', cmap=cmap1)
    #iplt.contour(f, [2], colors='k')
    plt.title('(a)'.ljust(28) + 'Forecast'.ljust(35))
    add_map()

    plt.subplot2grid((25, 4), (0, 2), colspan=2, rowspan=10)
    im = iplt.contourf(a, clevs, extend='both', cmap=cmap1)
    #iplt.contour(a, [2], colors='k', linestyles='--')
    plt.title('(b)'.ljust(28) + 'Analysis'.ljust(35))
    add_map()

    ax = plt.subplot2grid((25, 4), (10, 1), colspan=2, rowspan=1)
    cbar = plt.colorbar(im, cax=ax, orientation='horizontal')
    cbar.set_label(units)
    # cbar.set_ticks(range(11))

    # Plot error
    plt.subplot2grid((25, 4), (13, 1), colspan=2, rowspan=10)
    im = iplt.contourf(err, errlevs, cmap=cmap, extend='both')
    #iplt.contour(f, [2], colors='k')
    #iplt.contour(a, [2], colors='k', linestyles='--')
    plt.title('(c)'.ljust(20) + 'Forecast Minus Analysis.'.ljust(38))
    add_map()

    ax = plt.subplot2grid((25, 4), (23, 1), colspan=2, rowspan=1)
    cbar = plt.colorbar(im, cax=ax, orientation='horizontal',
                        spacing='proportional')
    errlevs.append(0)
    cbar.set_ticks(errlevs)
    cbar.set_label(units)

    return
Пример #13
0
def main(cubes):
    pv = convert.calc('air_potential_temperature',
                      cubes,
                      levels=('ertel_potential_vorticity', [2]))[0]

    theta = convert.calc('air_potential_temperature',
                         cubes,
                         levels=('air_pressure', [85000]))[0]

    plot.pcolormesh(theta, vmin=250, vmax=300)
    iplt.contour(pv, [300, 320], colors='k')

    plt.show()

    return
Пример #14
0
def main(cubes):
    mass = convert.calc('mass', cubes)
    water = convert.calc('mass_fraction_of_water', cubes)
    total_water = mass * water
    tcw = total_water.collapsed('atmosphere_hybrid_height_coordinate', SUM)

    mslp = convert.calc('air_pressure_at_sea_level', cubes)
    mslp.convert_units('hPa')

    plot.pcolormesh(tcw, vmin=0, vmax=5e9, cmap='Greys_r')
    iplt.contour(mslp, np.linspace(950, 1050, 11), colors='k', linewidths=2)

    plt.show()

    return
Пример #15
0
def forward_trajectories(forecast):
    """Calculate 48 hour forward trajectories from low levels

    Start trajectories from all points below 2km
    """
    cubes = forecast.set_lead_time(hours=48)

    z = convert.calc('altitude', cubes)
    theta = convert.calc('air_potential_temperature', cubes)
    theta_adv = convert.calc('advection_only_theta', cubes)
    pv = convert.calc('ertel_potential_vorticity', cubes)
    lon, lat = grid.true_coords(pv)
    glon, glat = grid.get_xy_grids(pv)
    time = grid.get_datetime(pv)
    nz, ny, nx = pv.shape

    eqlats = rossby_waves.eqlats
    cs = iris.Constraint(time=time)
    with iris.FUTURE.context(cell_datetime_objects=True):
        eqlat = eqlats.extract(cs)[0]

    # Interpolate to the theta and PV surfaces
    eqlat = interpolate.main(eqlat, ertel_potential_vorticity=2)
    eqlat = interpolate.main(eqlat,
                             potential_temperature=theta.data.flatten())

    # Define the start points
    trainp = []
    for k in range(nz):
        print(k)
        for j in range(ny):
            for i in range(nx):
                if (theta_adv.data[k, j, i] < 300 < theta.data[k, j, i] and
                        pv.data[k, j, i] < 2 and
                        lat[j, i] > eqlat.data[k * ny * nx + j * nx + i]):
                    trainp.append([glon[j, i], glat[j, i], z.data[k, j, i]])
    trainp = np.array(trainp)

    plot.pcolormesh(pv[33], vmin=0, vmax=10, cmap='cubehelix_r', pv=pv[33])
    plt.scatter(trainp[:, 0], trainp[:, 1])
    plt.show()

    # Calculate the trajectories
    tracers = ['air_potential_temperature', 'air_pressure']
    traout = caltra.caltra(trainp, mapping, fbflag=-1, tracers=tracers)

    # Save the trajectories
    traout.save(datadir + 'backward_trajectories.pkl')
Пример #16
0
def main(cubes, levels, *args, **kwargs):
    # Initialise the plot
    fig = plt.figure(figsize=(18, 20))

    for n, name in enumerate(names):
        row = n / ncols
        col = n - row * ncols
        print(row, col)
        ax = plt.subplot2grid((nrows, ncols), (row, col))

        cube = convert.calc(name, cubes, levels=levels)[0]
        im = iplt.pcolormesh(cube, *args, **kwargs)
        add_map()
        plt.title(second_analysis.all_diagnostics[name].symbol, fontsize=30)

    for n, ax in enumerate(fig.axes):
        multilabel(ax, n, fontsize=25)

    cbar = plt.colorbar(im, ax=fig.axes, orientation='horizontal',
                        fraction=0.05, spacing='proportional')
    cbar.set_label('PVU')
    # cbar.set_ticks(np.array(levels)[::2])

    plt.savefig(plotdir + '../../iop8_bl_map.png')
    # plt.show()

    return
Пример #17
0
def create_startf(cubes, theta_level, output_file):
    """Creates a startfile for lagranto for the whole grid on a single
    isentropic surface

    Reference date 20111129_2300 / Time range       0 min

      time      lon     lat     p     level
    ---------------------------------------

       0.00   -10.000   50.000   258   320.000

    """
    # Find pressure on theta level
    P = convert.calc('air_pressure',
                     cubes,
                     levels=('air_potential_temperature', theta_level))[0].data

    # Get longitude and latitude
    lon, lat = grid.true_coords(P)

    # Create startfile
    with open(output_file, 'w') as output:
        output.write('Reference date 20111129_2300 / Time range       0 min\n')
        output.write('\n')
        output.write('  time      lon     lat     p     level\n')
        output.write('---------------------------------------\n')
        output.write('\n')
        ny, nx = P.shape
        for j in xrange(ny):
            for i in xrange(nx):
                output.write('   0.00   ' + str(round(lon[j, i], 3)) + '   ' +
                             str(round(lat[j, i], 3)) + '   ' +
                             str(round(P[j, i] / 100.0, 0)) + '   ' +
                             str(theta_level) + '\n\n')
Пример #18
0
def create_startpoints(cubes, coordinate, values):
    """Create an array of startpoints

    Output array has shape Nx3 where N is the number of startpoints and the 3
    indices are for longitude, latitude and altitude.

    Args:
        cubes (iris.cube.CubeList)

    Returns:
        train (np.array): The input array to trajectory calculations
    """
    # Get the values of altitude at the given coordinate
    P = convert.calc(coordinate, cubes)
    z = grid.make_cube(P, 'altitude')
    z.add_aux_coord(grid.make_coord(P), [0, 1, 2])
    z500 = interpolate.to_level(z, **{coordinate: values})[0].data

    lon, lat = grid.get_xy_grids(P)

    # Convert the 2d arrays to an Nx3 array
    train = np.array([lon.flatten(),
                      lat.flatten(),
                      z500.flatten()]).transpose()

    return train
Пример #19
0
def ridges_troughs(cubes):
    thetapv2 = convert.calc('air_potential_temperature', cubes,
                            levels=('ertel_potential_vorticity', [2]))[0]

    ridges, troughs = rossby_waves.make_nae_mask(thetapv2, year=2009)

    return ridges, troughs
Пример #20
0
def create_startpoints(cubes, levels, stride=1):
    """Create an array of startpoints

    Output array has shape Nx3 where N is the number of startpoints and the 3
    indices are for longitude, latitude and altitude.

    Args:
        cubes (iris.cube.CubeList)

    Returns:
        train (np.array): The input array to trajectory calculations
    """
    # Get the values of altitude at the given coordinate
    z = convert.calc('altitude', cubes, levels=levels)

    # Get the grid latitude and longitude as 2d arrays
    lon, lat = grid.get_xy_grids(z)

    # Convert the 2d arrays to an Nx3 array
    nz = z.shape[0]
    lon = np.tile(lon[::stride, ::stride].flatten(), nz)
    lat = np.tile(lat[::stride, ::stride].flatten(), nz)
    z = z.data[:, ::stride, ::stride].flatten()

    train = np.array([lon, lat, z]).transpose()

    return train
Пример #21
0
def main(cubes):
    """Find all points within 1km of the tropopause that have a negative PV
    anomaly
    """
    # Find negative pv anomalies
    diff = convert.calc('total_minus_advection_only_pv', cubes)
    negative_pv = diff.data < -1

    # Find the tropopause height
    ztrop, fold_t, fold_b = tropopause.height(cubes)

    # Find point below the tropopause
    z = diff.coord('altitude').points
    tropopause_relative = np.logical_and(z < ztrop, z > ztrop - 2000)

    # Combine criteria
    criteria = np.logical_and(negative_pv, tropopause_relative)

    # Get indices where criterion is met
    indices = np.where(criteria)

    # Convert to lon, lat, z
    longitude = diff.coord('grid_longitude').points
    lons = np.array([longitude[idx] for idx in indices[2]])
    latitude = diff.coord('grid_latitude').points
    lats = np.array([latitude[idx] for idx in indices[1]])
    height = grid.extract_dim_coord(diff, 'z').points
    altitude = np.array([height[idx] for idx in indices[0]])

    # Scatterplot the locations
    fig = plt.figure()
    ax = fig.add_subplot(111, projection='3d')
    ax.scatter(lons, lats, altitude)
    plt.show()
Пример #22
0
def main(cubes, dz, name, **kwargs):
    """Produces cross section plots above and below the tropopause
    """
    # Extract cube to be plotted
    cube = convert.calc(name, cubes)

    # Find the height of the tropopause
    ztrop, fold_t, fold_b = tropopause.height(cubes)

    # Produce a new co-ordinate above and below the tropopause
    ny, nx = ztrop.shape
    new_coord = np.zeros([3, ny, nx])
    new_coord[0, :, :] = ztrop.data - dz
    new_coord[1, :, :] = ztrop.data
    new_coord[2, :, :] = ztrop.data + dz

    # Interpolate the cubes to be plotted to the coordinate above and below the
    # tropopause
    plotcube = interpolate.to_level(cube, altitude=new_coord)

    # Plot the cross sections
    for n in xrange(3):
        plt.figure()
        plot.pcolormesh(plotcube[n], **kwargs)
    plt.show()
Пример #23
0
def make_plot(cubes, rings, wcb, theta_level, n):
    # Plot a map at verification time
    levels = ('air_potential_temperature', [theta_level])
    pv = convert.calc('ertel_potential_vorticity', cubes, levels=levels)[0]
    plot.pcolormesh(pv, vmin=-2, vmax=2, cmap='coolwarm')
    iplt.contour(pv, [0, 2], colors='k', linewidths=2)
    add_map()

    # Load the trajectories
    x = wcb['grid_longitude'] - 360
    y = wcb['grid_latitude']
    c = wcb['air_potential_temperature']

    # Plot the 3d trajectory positions
    plt.scatter(x[:, -n],
                y[:, -n],
                c=c[:, -n],
                vmin=300,
                vmax=340,
                cmap='coolwarm')

    # Plot the isentropic boundary
    x = rings['grid_longitude'] - 360
    y = rings['grid_latitude']
    plt.plot(x[:, -n], y[:, -n], color='r', linewidth=3)

    return
Пример #24
0
def main():
    forecasts = [case_studies.iop5b.copy(), case_studies.iop8.copy()]

    fig = plt.figure(figsize=(18, 8))
    for n, forecast in enumerate(forecasts):
        ax = plt.subplot2grid((1, 2), (0, n))

        cubes = forecast.set_lead_time(hours=24)
        theta = convert.calc('air_potential_temperature', cubes)
        bl_type = convert.calc('boundary_layer_type', cubes)
        for m in range(4):
            mask = np.logical_not(
                np.logical_or(bl_type.data == 2 * m,
                              bl_type.data == 2 * m + 1))
            mask = mask * np.ones_like(theta.data)
            mean = theta_profile(theta, mask)
            mean = mean - mean[0]
            iplt.plot(mean,
                      mean.coord('atmosphere_hybrid_height_coordinate'),
                      style[m],
                      label=label[m])

        #mask = np.logical_not(mask)
        #mean = theta_profile(theta, mask)
        # iplt.plot(mean, mean.coord('atmosphere_hybrid_height_coordinate'),
        #          '-kx')

        ax.set_xlim(-0.25, 4.5)
        ax.set_xlabel(r'$\theta$')
        ax.set_ylim(0, 1000)
        if n == 0:
            ax.set_ylabel('Height (m)')
            ax.set_title('IOP5')
        else:
            ax.get_yaxis().set_ticklabels([])
            ax.set_title('IOP8')

        plt.axvline(color='k')
        multilabel(ax, n)

    legend(ax, loc='upper left', ncol=2, bbox_to_anchor=(-0.6, -0.2))
    fig.subplots_adjust(bottom=0.4)

    fig.savefig(plotdir + 'theta_profiles.pdf')
    plt.show()

    return
Пример #25
0
def make_plots(field, cubes, levels, path):
    name = field.pop("name")
    cube = convert.calc(name, cubes, levels=(levels["name"], levels["values"]))
    for n, level in enumerate(levels["values"]):
        plot.pcolormesh(cube[n], **field)
        plt.savefig("{}{}_{}_{}.png".format(path, name, levels["name"],
                                            levels["values"][n]))
        plt.clf()
Пример #26
0
def main(cubes):
    pv = convert.calc('ertel_potential_vorticity', cubes, levels=levels)[0]
    adv = convert.calc('advection_only_pv', cubes, levels=levels)[0]
    for n, name in enumerate([
            'sum_of_physics_pv_tracers', 'epsilon',
            'dynamics_tracer_inconsistency', 'residual_pv'
    ]):
        cube = convert.calc(name, cubes, levels=levels)[0]

        m = n / 2
        ax = plt.subplot2grid((2, 2), (n - 2 * m, m))
        iplt.contourf(cube, clevs, cmap=cmap)
        add_map()
        iplt.contour(pv, [2], colors='k', linestyles='-')
        iplt.contour(adv, [2], colors='k', linestyles='-')

    plt.show()
Пример #27
0
def main():
    lead_time = 48
    levels = ('air_potential_temperature', [320])

    forecast = case_studies.iop5_extended.copy()
    cubes = forecast.set_lead_time(hours=lead_time)
    dtheta = convert.calc('total_minus_advection_only_theta',
                          cubes,
                          levels=levels)[0]
    pv = convert.calc('ertel_potential_vorticity', cubes, levels=levels)[0]

    closed_loop, points = get_points(dtheta.copy(), pv.copy())
    closed_loop = increase_circuit_resolution(closed_loop, 25000)

    make_plot(dtheta, pv, closed_loop, vmin=-20, vmax=20, cmap='coolwarm')

    return
Пример #28
0
def main(cubes, levels, *args, **kwargs):
    # Initialise the plot
    fig = plt.figure(figsize=(18, 20))

    pv = convert.calc('ertel_potential_vorticity', cubes, levels=levels)[0]
    theta = convert.calc('equivalent_potential_temperature', cubes,
                         levels=levels)[0][slices]

    rh = convert.calc('relative_humidity', cubes, levels=levels)[0][slices]

    lon, lat = grid.true_coords(theta)
    lonmask = np.logical_or(lon < -15, lon > 5)
    latmask = np.logical_or(lat < 47.5, lat > 62.5)
    areamask = np.logical_or(lonmask, latmask)
    mask = theta.copy(data=areamask.astype(int))

    for n, name in enumerate(names):
        row = n / ncols
        col = n - row * ncols
        print(row, col)
        ax = plt.subplot2grid((nrows, ncols), (row, col))

        cube = convert.calc(name, cubes, levels=levels)[0]  # [slices]
        im = iplt.contourf(cube, *args, **kwargs)
        #iplt.contour(pv, [2], colors='k', linewidths=2)
        iplt.contour(mask, [0.5], colors='k', linestyles='--')
        add_map()
        plt.title(second_analysis.all_diagnostics[name].symbol)

        iplt.contour(theta, [300], colors='k', linewidths=2)
        iplt.contour(rh, [0.8], colors='w', linewidths=2)
        iplt.contourf(rh, [0.8, 2], colors='None', hatches=['.'])

    for n, ax in enumerate(fig.axes):
        multilabel(ax, n)

    cbar = plt.colorbar(im, ax=fig.axes, orientation='horizontal',
                        fraction=0.05, spacing='proportional')
    cbar.set_label('PVU')
    cbar.set_ticks(np.linspace(-2, 2, 17)[::2])

    plt.savefig(plotdir + 'iop5_pv_tracers_24h_' +
                str(levels[1][0])[0:3] + 'hpa.pdf')
    # plt.show()

    return
Пример #29
0
def compare_pv(cubes, rdf_pv, p_level, *args, **kwargs):
    # Calculate required variables
    pv = convert.calc('ertel_potential_vorticity', cubes,
                      levels=('air_pressure', [p_level]))[0]
    adv = convert.calc('advection_only_pv', cubes,
                       levels=('air_pressure', [p_level]))[0]
    qsum = convert.calc('sum_of_physics_pv_tracers', cubes,
                        levels=('air_pressure', [p_level]))[0]

    diff = pv - qsum
    diff.rename('pv_minus_physics_pv_tracers')

    # Plot both figures
    for cube in [diff, adv, rdf_pv]:
        plt.figure()
        plot.contourf(cube, *args, **kwargs)

    return
Пример #30
0
def _single_fit(coord, subdomain, dz, function, **kwargs):
    cubes = second_analysis.get_data(coord, subdomain)
    pv = convert.calc(variable, cubes)
    x, y, dy = function(pv, coord, dz)
    popt, pcov, rmse = fit_curve(x, y, dy)
    print(popt, rmse)
    plot_fit(x, y, dy, popt, **kwargs)

    return popt, rmse