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()
def main(): # Specify which files and variable to compare path = datadir + 'deterministic/sppt_off/' variable = 'Temperature' level = 500. days = [2, 4, 10, 20] # Load the double precision and reduced precision model runs filename = 'rp_physics.nc' cs = iris.Constraint(name=variable, pressure=level, precision=52) cube_fp = iris.load_cube(path + filename, cs) cs = iris.Constraint(name=variable, pressure=level, precision=23) cube_rp = iris.load_cube(path + filename, cs) diff = cube_rp - cube_fp # 2x2 figure. 1 plot for each stage of error growth fig, axes = plt.subplots(nrows=2, ncols=2, figsize=[16, 10]) limit = 0. for n in days: row, col = get_row_and_column_index(days.index(n), ncols=2) plt.axes(axes[row, col]) limit = get_cscale_limit(diff[n].data, limit) plot.pcolormesh(diff[n], vmin=-limit, vmax=limit, cmap='coolwarm') plt.title(str(n) + ' days') plt.show() return
def main(): # Specify which files and variable to compare path = datadir + 'stochastic/ensembles/' variable = 'Temperature' level = 500. days = [2, 4, 10, 20] filename = 'rp_physics_52b.nc' cs = iris.Constraint(name=variable, pressure=level) cube_fp = iris.load_cube(path + filename, cs) spread = cube_fp.collapsed('ensemble_member', STD_DEV) fig, axes = plt.subplots(nrows=2, ncols=2, figsize=[16, 10]) limit = 0. for n in days: row, col = get_row_and_column_index(days.index(n), ncols=2) print(row, col) plt.axes(axes[row, col]) limit = get_cscale_limit(spread[n].data, limit) plot.pcolormesh(spread[n], vmin=0, vmax=limit, cmap='cubehelix_r') plt.title(str(n) + ' days') plt.show() return
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
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()
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()
def wind_speed(u, v, w, vmin=0, vmax=70, cmap='BuPu', factor=20): wind_speed = (u**2 + v**2 + w**2)**0.5 plot.pcolormesh(wind_speed[0], vmin=vmin, vmax=vmax, cmap=cmap) ny, nx = u.shape[1:] plot.overlay_winds(u[0], v[0], int(nx / factor), int(ny / factor)) plt.title('Wind Speed') return
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
def generate_overview(cubes, info, path="./"): for field in info["single_level_fields"]: name = field.pop("name") cube = convert.calc(name, cubes) plot.pcolormesh(cube, **field) plt.savefig("{}{}.png".format(path, name)) plt.clf() for levels in info["vertical_coordinates"]: for field in info["multi_level_fields"]: make_plots(field.copy(), cubes, levels, path) for field in info["vertical_coordinates"]: if field["name"] != levels["name"]: make_plots(field.copy(), cubes, levels, path)
def make_plot(rp, fp, **kwargs): # Show the full-precision tendencies plot.pcolormesh(fp, **kwargs) # Find locations of activated and deactivated gridpoints activated = np.logical_and(rp.data != 0, fp.data == 0) deactivated = np.logical_and(rp.data == 0, fp.data != 0) # Overlay activated and deactivated gridpoints x = fp.coord('longitude').points y = fp.coord('latitude').points mark_locations(activated, x, y, 'kX') mark_locations(deactivated, x, y, 'ko') return
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
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
def main(cubes, p_level): # Load data theta = convert.calc('air_potential_temperature', cubes, levels=('air_pressure', [p_level]))[0] # Calculate the fronts loc = fronts.main(theta) loc = theta.copy(data=loc) # Plot the output plot.pcolormesh(theta, vmin=280, vmax=320, cmap='plasma') plt.title(r'$\theta$ at ' + str(p_level) + ' Pa') iplt.contour(loc, [0], colors='k') plt.show()
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')
def main(): # Specify which files and variable to compare path = datadir + 'deterministic/sppt_off/' variable = 'Temperature' level = 500. filename = 'rp_physics.nc' cs = iris.Constraint(name=variable, pressure=level, precision=52) cube_fp = iris.load_cube(path + filename, cs) cs = iris.Constraint(name=variable, pressure=level, precision=51) cube_rp = iris.load_cube(path + filename, cs) diff = cube_rp - cube_fp rmse = rms_diff(cube_rp, cube_fp) t = rmse.coord('forecast_period').points limit = 0. for n in range(rmse.shape[0]): # Create a one by two grid with shared x and y axes along rows and columns fig, axes = plt.subplots(nrows=1, ncols=2, figsize=[16, 5]) plt.axes(axes[0]) iplt.plot(rmse) plt.plot(t[n], rmse.data[n], 'kx') plt.axes(axes[1]) new_limit = np.abs(diff[n].data).max() print(new_limit) if new_limit > 0: # Round to one decimal place but always up order_of_magnitude = 10**math.floor(np.log10(new_limit)) print(order_of_magnitude) new_limit = math.ceil( new_limit / order_of_magnitude) * order_of_magnitude limit = max(limit, new_limit) print(limit) plot.pcolormesh(diff[n], vmin=-limit, vmax=limit, cmap='coolwarm') plt.savefig(plotdir + 'detailed_error_growth_51_52_' + str(n).zfill(4) + '.png') plt.close() return
def main(cubes, theta_value, **kwargs): """Plot PV on theta and the equivalent latitude circle Args: cubes (iris.cube.CubeList): Contains variables to calculate PV and potential temperature """ pv = convert.calc('ertel_potential_vorticity', cubes, levels=('air_potential_temperature', [theta_value]))[0] # Add equivalent latitude lon, lat = grid.true_coords(pv) lat = pv.copy(data=lat) time = grid.get_datetime(pv)[0] time = PDT(month=time.month, day=time.day, hour=time.hour) eqlat = rossby_waves.equivalent_latitude(time, theta_value, 2) # Plot PV on theta plot.pcolormesh(pv, pv=pv, **kwargs) iplt.contour(lat, [eqlat.data], colors='r', linewidths=2) plt.title('') plt.show()
def make_plot(theta_adv, pv, points, **kwargs): plot.pcolormesh(theta_adv, **kwargs) iplt.contour(pv, [2], colors='k', linewidths=2) plt.scatter(points[:, 0], points[:, 1]) return
def make_plots(field, cubes, name, values): cube = convert.calc(field, cubes, levels=(name, values)) for n, level in enumerate(values): plot.pcolormesh(cube[n], vmin=-2, vmax=2, cmap='coolwarm') plt.savefig(directory + name + '/' + field + '_' + str(level) + '.png') plt.clf()
def main(cubes, **kwargs): theta = convert.calc('air_potential_temperature', cubes, levels=('ertel_potential_vorticity', [2])) plot.pcolormesh(theta[0], **kwargs) plt.show()
def plot_summary(cube, vmin=250, vmax=400, cmap='plasma', **kwargs): """Plot background theta on 2PVU vs latitude for full period """ plot.pcolormesh(cube, vmin=vmin, vmax=vmax, cmap=cmap, **kwargs) return
def make_plot(cubes, job, name, levels, theta_level, cluster, **kwargs): plt.figure(figsize=(12, 10)) plotname = plotdir + job + '_' + name + '_map' # Plot a map at verification time pv = convert.calc('ertel_potential_vorticity', cubes, levels=levels)[0] dtheta = convert.calc('total_minus_advection_only_theta', cubes, levels=levels)[0] mslp = convert.calc('air_pressure_at_sea_level', cubes) mslp.convert_units('hPa') plot.pcolormesh(dtheta, vmin=-20, vmax=20, cmap='coolwarm', pv=pv) cs = iplt.contour(mslp, range(950, 1050, 5), colors='k', linewidths=1) plt.clabel(cs, fmt='%1.0f') # Load the trajectories filename = datadir + job + '/' + name + '.pkl' trajectories = trajectory.load(filename) print(len(trajectories)) # Only plot trajectories that stay in the domain trajectories = trajectories.select('air_pressure', '>', 0) print(len(trajectories)) # Select individual clusters of trajectories if cluster is not None: path = datadir + job + '/' + name select_cluster(cluster, trajectories, path) plotname += '_cluster' + str(cluster) if theta_level is not None: plotname += '_' + str(theta_level) + 'K' dt = timedelta(hours=48) trajectories = trajectories.select('air_potential_temperature', '>', theta_level - 2.5, time=[dt]) trajectories = trajectories.select('air_potential_temperature', '<=', theta_level + 2.5, time=[dt]) print(len(trajectories)) x = trajectories.x - 360 y = trajectories.y c = trajectories['altitude'] # Plot each individual trajectory for n in range(len(trajectories)): plot.colored_line_plot(x[n], y[n], c[n], **kwargs) # Mark the start and end point of trajectories plt.scatter(x[:, 0], y[:, 0], c=c[:, 0], linewidths=0.1, zorder=5, **kwargs) plt.scatter(x[:, -1], y[:, -1], c=c[:, -1], linewidths=0.1, zorder=5, **kwargs) plt.colorbar() plt.savefig(plotname + '.png') return