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 bottom_level(tracers, mslp, fig, **kwargs): # Plot each cube separately for n, cube in enumerate(tracers): row = n / ncols col = n - row * ncols ax = plt.subplot2grid((nrows, ncols), (row, col)) # Make the plot im = iplt.pcolormesh(cube[0], **kwargs) mslp.convert_units('hPa') cs = iplt.contour(mslp, plevs, colors='k', linewidths=2) plt.clabel(cs, fmt='%1.0f') add_map() plt.title(second_analysis.all_diagnostics[cube.name()].symbol) # Label the cross section points if n == 0: plt.plot([xs, xf], [ys, yf], '-kx') plt.text(xs, ys, 'A', fontsize=20) plt.text(xf, yf, 'B', fontsize=20) # Add letter labels to panels for n, ax in enumerate(fig.axes): multilabel(ax, n) # Add colorbar at bottom of figure cbar = plt.colorbar(im, ax=fig.axes, orientation='horizontal', fraction=0.05) cbar.set_label('PVU') return
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
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
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()
def make_plot(cubes, name, mass, mask, **kwargs): pv = convert.calc(name, cubes) pv.data = np.ma.masked_where(mask, pv.data) z = grid.extract_dim_coord(pv, 'z') pv_ave = pv.collapsed(z.name(), MEAN, weights=mass.data) im = iplt.pcolormesh(pv_ave, **kwargs) add_map() return im
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()
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
def plot_overview(mslp, pv): iplt.contourf(pv, even_cscale(2), cmap='coolwarm', spacing='proportional', extend='both') add_map() cbar = plt.colorbar(orientation='horizontal', fraction=0.05, spacing='proportional') cbar.set_label('PVU') cbar.set_ticks(np.linspace(-2, 2, 9)) cs = iplt.contour(mslp, plevs, colors='k', linewidths=1) plt.clabel(cs, fmt='%1.0f', colors='k') plt.plot(track[:, 0], track[:, 1], '-y') plt.plot(track[time, 0], track[time, 1], 'yx', markersize=15) return
def main(forecast, name, levels, *args, **kwargs): nt = len(forecast) rows = (nt / columns) + 1 fig = plt.figure(figsize=(18, 10 * float(rows) / columns)) for n, cubes in enumerate(forecast): row = n / columns column = n - row * columns print(row, column) ax = plt.subplot2grid((rows, columns), (row, column)) cube = convert.calc(name, cubes, levels=levels)[0] im = iplt.pcolormesh(cube, *args, **kwargs) add_map() ax = plt.subplot2grid((rows, columns), (row, column + 1)) cbar = plt.colorbar(im, cax=ax, orientation='horizontal') plt.savefig(plotdir + name + '_' + str(levels[0]) + '_' + str(levels[1][0]) + '.png') return
def bl_categories(): # Initialise the plot fig = plt.figure(figsize=(18, 10)) for n, forecast in enumerate(forecasts): cubes = forecast.set_lead_time(hours=24) ax = plt.subplot2grid((1, 2), (0, n)) if n == 0: plt.title('IOP5') elif n == 1: plt.title('IOP8') multilabel(ax, n + 2) bl_type = convert.calc('boundary_layer_type', cubes) cmap = mpl.colors.ListedColormap([t[1] for t in types]) iplt.pcolormesh(bl_type, cmap=cmap) overlay_pressure(cubes) add_map() # Add category map legend handles = [] for bl_type, colour in types: handles.append(mpatches.Patch(color=colour, label=bl_type)) ax = fig.axes[1] ax.legend(handles=handles, ncol=2, loc='upper_right', bbox_to_anchor=(0.95, -0.1)) fig.subplots_adjust(bottom=0.5) plt.savefig(plotdir + 'bl_categories') return
def wind_speed(cubes, levs, cubes_a=None, **kwargs): u = convert.calc('x_wind', cubes, levels=levels)[0] v = convert.calc('y_wind', cubes, levels=levels)[0] w = convert.calc('upward_air_velocity', cubes, levels=levels)[0] wind = (u.data**2 + v.data**2 + w.data**2)**0.5 wind = u.copy(data=wind) if cubes_a is not None: u_a = convert.calc('x_wind', cubes_a, levels=levels)[0] v_a = convert.calc('y_wind', cubes_a, levels=levels)[0] w_a = convert.calc('upward_air_velocity', cubes_a, levels=levels)[0] wind_a = (u_a.data**2 + v_a.data**2 + w_a.data**2)**0.5 wind.data -= wind_a u -= u_a v -= v_a w -= w_a print(wind.data.max(), wind.data.min()) im = iplt.contourf(wind, levs, **kwargs) add_map() plot.overlay_winds(u, v, 33, 57, scale=1500) return im
def bl_heights(**kwargs): # Initialise the plot fig = plt.figure(figsize=(18, 10)) for n, forecast in enumerate(forecasts): cubes = forecast.set_lead_time(hours=24) ax = plt.subplot2grid((1, 2), (0, n)) z_bl = convert.calc('atmosphere_boundary_layer_thickness', cubes) z_bl.convert_units('km') im = iplt.pcolormesh(z_bl, **kwargs) cs = overlay_pressure(cubes) plt.clabel(cs, fmt='%1.0f') add_map() if n == 0: plt.title('IOP5') elif n == 1: plt.title('IOP8') multilabel(ax, n) # Add BL Height colourscale cbar = plt.colorbar(im, ax=fig.axes, fraction=0.05, orientation='horizontal', extend='max') cbar.set_label('Boundary layer thickness (km)') cbar.set_ticks(np.linspace(0, 3, 7)) plt.savefig(plotdir + 'bl_heights') return
def plot_overview(fp, rp, **kwargs): plt.figure(figsize=(12, 9)) row_title = 2 row_fig = 8 col_fig = 8 row_cbar = 3 col_cbar = 6 nrows = row_title + 2 * (row_fig + row_cbar) ncols = 2 * col_fig row_fig1 = row_title row_cbar1 = row_fig1 + row_fig row_fig2 = row_cbar1 + row_cbar row_cbar2 = row_fig2 + row_fig col_fig1 = 0 col_fig2 = col_fig1 + col_fig col_fig3 = col_fig1 + int(col_fig / 2) col_cbars = int((ncols - col_fig1 - col_cbar) / 2) plt.subplot2grid((nrows, ncols), (row_fig1, col_fig1), rowspan=row_fig, colspan=col_fig) im = iplt.pcolormesh(fp, **kwargs) plt.title('Full Precision') add_map() plt.subplot2grid((nrows, ncols), (row_fig1, col_fig2), rowspan=row_fig, colspan=col_fig) im = iplt.pcolormesh(rp, **kwargs) plt.title('Reduced Precision') add_map() ax = plt.subplot2grid((nrows, ncols), (row_cbar1, col_cbars), rowspan=row_cbar, colspan=col_cbar) cbar = plt.colorbar(im, cax=ax, orientation='horizontal') plt.subplot2grid((nrows, ncols), (row_fig2, col_fig3), rowspan=row_fig, colspan=col_fig) vmax = 0.1 * max(abs(kwargs['vmin']), abs(kwargs['vmax'])) im = iplt.pcolormesh(rp - fp, vmin=-vmax, vmax=vmax, cmap='bwr') plt.title('Difference') add_map() ax = plt.subplot2grid((nrows, ncols), (row_cbar2, col_cbars), rowspan=row_cbar, colspan=col_cbar) cbar = plt.colorbar(im, cax=ax, orientation='horizontal') return
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
def main(cubes, **kwargs): # Pre-calculate parameters on every plot mslp = convert.calc('air_pressure_at_sea_level', cubes) mslp.convert_units('hPa') theta = convert.calc('equivalent_potential_temperature', cubes, levels=levels)[0] rh = convert.calc('relative_humidity', cubes) fig = plt.figure(figsize=(18, 15)) 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) # Plot overview ax1 = plt.subplot2grid((2, 2), (0, 0)) iplt.contourf(theta, theta_levs, cmap='coolwarm', extend='both') add_map() cs = iplt.contour(mslp, plevs, colors='k', linewidths=2) plt.clabel(cs, fmt='%1.0f') mask = theta.copy(data=areamask.astype(int)) iplt.contour(mask, [0.5], colors='k', linestyles='--') count = 0 for n, (xs, xf, ys, yf) in enumerate(points, start=1): # Label the cross section points plt.plot([xs, xf], [ys, yf], '-kx') plt.text(xs, ys, ascii_uppercase[count], color='k', fontsize=20) count += 1 plt.text(xf, yf, ascii_uppercase[count], color='k', fontsize=20) count += 1 multilabel(plt.gca(), 0) theta = convert.calc('equivalent_potential_temperature', cubes) # Plot cross sections titles = ['AB', 'CD', 'EF'] coords = ['grid_longitude', 'altitude'] for n, (xs, xf, ys, yf) in enumerate(points, start=1): row = n / ncols col = n - row * ncols ax = plt.subplot2grid((nrows, ncols), (row, col)) theta_cs = cs_cube(theta, xs, xf, ys, yf) rh_cs = cs_cube(rh, xs, xf, ys, yf) im = iplt.contourf(theta_cs, theta_levs, coords=coords, cmap='coolwarm', extend='both') iplt.contour(rh_cs, rh_levs, coords=coords, colors='w') iplt.contourf(rh_cs, [0.8, 2], coords=coords, colors='None', hatches=['.']) ax.set_ylim(0, 7) if xs > xf: ax.invert_xaxis() multilabel(ax, n, xreversed=True) else: multilabel(ax, n) ax.set_title(titles[n - 1]) ax.set_ylabel('Height (km)') ax.set_xlabel('Grid Longitude') # Add colorbar at bottom of figure cbar = plt.colorbar(im, ax=fig.axes, orientation='horizontal', fraction=0.05, spacing='proportional') cbar.set_label('PVU') fig.savefig(filename) plt.show()
def make_pv_plot(pv, **kwargs): im = iplt.pcolormesh(pv, **kwargs) iplt.contour(pv, [2], colors='k', linewidths=2) add_map() return im