def plot_ave( ave, lat_e, lon_e, xticks=np.arange(-180.0, 180.1, 60.0), yticks=np.arange(-90.0, 90.1, 30.0), region_limit=[-90.0, -180.0, 90.0, 180.0], vmin=None, vmax=None, units='', ): """ plot average (ywang, 04/12/20) Parameters ---------- ave : 2D array PCA modes lat_e : shape (n_lat+1, n_lon+1) Latitude edges lon_e : shape (n_lat+1, n_lon+1) Longitude edges """ # begin plot nrow = 2 ncol = 1 figsize = (8, 6) projPos = [0] layout_dict = multiFigure(nrow, ncol, figsize=figsize, projPos=projPos) fig = layout_dict['fig'] axes = layout_dict['axes'] # plot average pout = cartopy_plot(lon_e, lat_e, ave, ax=axes[0], vmin=vmin, vmax=vmax, cmap=deepcopy(WhGrYlRd_map), cbar=True) pout['cb'].set_label(units) states_provinces = cfeature.NaturalEarthFeature( category='cultural', name='admin_1_states_provinces_lines', scale='50m', facecolor='none') panel_tick_label(axes[0:1], ncol, xticks=xticks, yticks=yticks) axes[0].add_feature(cfeature.BORDERS) axes[0].add_feature(states_provinces, edgecolor='k', linewidth=0.5) axes[0].add_feature(cfeature.COASTLINE, zorder=200) axes[0].set_xlim((region_limit[1], region_limit[3])) axes[0].set_ylim((region_limit[0], region_limit[2]))
def plot_comparison( var1, var2, lat_e, lon_e, figsize=(6, 7), vmin=None, vmax=None, diff_vmin=None, diff_vmax=None, cb_diff_ticks=None, left=0.25, right=0.75, top=0.95, bottom=0.1, hspace=None, wspace=None, cl_color='k', lw=None, region_limit=None, xticks=np.arange(-180, 180.0, 60), yticks=np.arange(-90, 90.1, 30), title_dict={}, cmap=deepcopy(WhGrYlRd_map), diff_cmap=deepcopy(gbcwpry_map), units='', cb_ratio=0.03, cb_y_off=-0.05, mask_ocean=False, ): """ Plot var1, var2 and var2 - var1. (Yi Wang, 09/02/2020) Parameters ---------- var1 : 2-D numpy array The first variable. var2 : 2-D numpy array The second variable. lat_e : 2-D numpy array Latitude edges. lon_e : 2-D numpy array Longitude edge. figsize : 2-element tuple Figure size vmin : float or None Minimum to be plotted for var1 and var2. If vmin is None, it will be set as the valid minimum of var1 or var2, which is smaller. vmax : float or None Similar to vmin, but of maximum diff_vmin : float or None Minimum to be plotted for var2 - var1. diff_vmax : float or None Maximum to be plotted for var2 = var1. Returns ------- """ # define figure nrow = 3 ncol = 1 projPos = list(range(nrow * ncol)) layout_dict = multiFigure(nrow, ncol, left=left, right=right, top=top, bottom=bottom, wspace=wspace, hspace=hspace, figsize=figsize, projPos=projPos, countries=True, states=True, coastlines=True, mask_ocean=mask_ocean) fig = layout_dict['fig'] axes = layout_dict['axes'] # get min and max for var1 and var2 if vmin is None: vmin = min(np.min(var1), np.min(var2)) if vmax is None: vmax = max(np.max(var1), np.max(var2)) # plot var1 and var2 var_list = [var1, var2] varname_list = ['var1', 'var2'] for i in range(len(var_list)): ax = axes[i] var = var_list[i] title = title_dict.get(varname_list[i], None) pout = cartopy_plot(lon_e, lat_e, var, ax=ax, title=title, cbar=False, vmin=vmin, vmax=vmax, cmap=deepcopy(cmap)) # plot var2 - var1 diff = var2 - var1 ax = axes[2] title = title_dict.get('diff', None) diff_pout = cartopy_plot(lon_e, lat_e, diff, ax=ax, title=title, cbar=False, vmin=diff_vmin, vmax=diff_vmax, cmap=deepcopy(diff_cmap)) # ticks panel_tick_label(axes, ncol, xticks=xticks, yticks=yticks) # set limit for ax in axes: if region_limit is not None: ax.set_xlim((region_limit[1], region_limit[3])) ax.set_ylim((region_limit[0], region_limit[2])) # colorbar for var1 and var2 cax1 = h_1_ax(fig, axes[1], ratio=cb_ratio, y_off=cb_y_off) cb1 = plt.colorbar(pout['mesh'], cax=cax1, orientation='horizontal') right_center_label(cax1, units) # colorbar for diff cax2 = h_1_ax(fig, axes[2], ratio=cb_ratio, y_off=cb_y_off) cb2 = plt.colorbar(diff_pout['mesh'], cax=cax2, orientation='horizontal') if cb_diff_ticks is not None: cb2.set_ticks(cb_diff_ticks) right_center_label(cax2, units)
def plot_scatter_comparison_2( var1, var2, lat_e, lon_e, figsize=(8, 6), vmin=None, vmax=None, diff_vmin=None, diff_vmax=None, rel_pct_vmin=None, rel_pct_vmax=None, cb_diff_ticks=None, cb_rel_pct_ticks=None, extend='neither', diff_extend='neither', rel_pct_extend='neither', left=0.08, right=0.80, top=0.95, bottom=0.1, hspace=None, wspace=None, cl_color='k', lw=None, region_limit=None, xticks=np.arange(-180, 180.0, 60), yticks=np.arange(-90, 90.1, 30), title_dict={}, cmap=deepcopy(WhGrYlRd_map), diff_cmap=deepcopy(gbcwpry_map), rel_pct_cmap=deepcopy(gbcwpry_map), units='', diff_units='', cb_ratio=0.06, cb_y_off_t=-0.04, cb_y_off_b=-0.07, mask_ocean=False, ): """ Plot var1, var2 and var2 - var1. (Yi Wang, 10/21/2020) Parameters ---------- var1 : 2-D numpy array The first variable. var2 : 2-D numpy array The second variable. lat_e : 2-D numpy array Latitude edges. lon_e : 2-D numpy array Longitude edge. figsize : 2-element tuple Figure size vmin : float or None Minimum to be plotted for var1 and var2. If vmin is None, it will be set as the valid minimum of var1 or var2, which is smaller. vmax : float or None Similar to vmin, but of maximum diff_vmin : float or None Minimum to be plotted for var2 - var1. diff_vmax : float or None Maximum to be plotted for var2 = var1. rel_pct_vmin : float or None Minimum to be plotted for (var2 - var1) / var1 * 100 rel_pct_vmax : float or None Maximum to be plotted for (var2 - var1) / var1 * 100 Returns ------- """ # define figure nrow = 2 ncol = 2 projPos = list(range(nrow * ncol)) layout_dict = multiFigure(nrow, ncol, left=left, right=right, top=top, bottom=bottom, wspace=wspace, hspace=hspace, figsize=figsize, projPos=projPos, countries=True, states=True, coastlines=True, mask_ocean=mask_ocean) fig = layout_dict['fig'] axes = layout_dict['axes'] # get min and max for var1 and var2 if vmin is None: vmin = min(np.nanmin(var1), np.nanmin(var2)) if vmax is None: vmax = max(np.nanmax(var1), np.nanmax(var2)) # plot var1 and var2 var_list = [var1, var2] varname_list = ['var1', 'var2'] for i in range(len(var_list)): ax = axes[i] var = var_list[i] title = title_dict.get(varname_list[i], None) pout = cartopy_plot_scatter(lon_e, lat_e, c=var, ax=ax, title=title, cbar=False, vmin=vmin, vmax=vmax, cmap=deepcopy(cmap)) # plot (var2 - var1) / var1 * 100 rel_pct = (var2 - var1) / var1 * 100 if (rel_pct_vmin is None) and (rel_pct_vmax is None): rel_pct_vmax = np.nanmax(np.absolute(rel_pct)) rel_pct_vmin = -rel_pct_vmax ax = axes[2] title = title_dict.get('relative_diff', None) rel_pct_pout = cartopy_plot_scatter(lon_e, lat_e, c=rel_pct, ax=ax, title=title, cbar=False, vmin=rel_pct_vmin, vmax=rel_pct_vmax, cmap=deepcopy(rel_pct_cmap)) # plot var2 - var1 diff = var2 - var1 if (diff_vmin is None) and (diff_vmax is None): diff_vmax = np.nanmax(np.absolute(diff)) diff_vmin = -diff_vmax ax = axes[3] title = title_dict.get('diff', None) diff_pout = cartopy_plot_scatter(lon_e, lat_e, c=diff, ax=ax, title=title, cbar=False, vmin=diff_vmin, vmax=diff_vmax, cmap=deepcopy(diff_cmap)) # ticks panel_tick_label(axes, ncol, xticks=xticks, yticks=yticks) # set limit for ax in axes: if region_limit is not None: ax.set_xlim((region_limit[1], region_limit[3])) ax.set_ylim((region_limit[0], region_limit[2])) # colorbar for var1 and var2 cax1 = h_2_ax(fig, axes[0], axes[1], ratio=cb_ratio, y_off=cb_y_off_t) cb1 = plt.colorbar(pout['paths'], cax=cax1, orientation='horizontal', extend=extend) right_center_label(cax1, units) # colorbar for (var2 - var1) / var1 * 100 cax2 = h_1_ax(fig, axes[2], ratio=cb_ratio, y_off=cb_y_off_b) cb2 = plt.colorbar(rel_pct_pout['paths'], cax=cax2, orientation='horizontal', extend=rel_pct_extend) if cb_rel_pct_ticks is not None: cb2.set_ticks(cb_rel_pct_ticks) right_center_label(cax2, '[%]') # colorbar for diff cax3 = h_1_ax(fig, axes[3], ratio=cb_ratio, y_off=cb_y_off_b) cb3 = plt.colorbar(diff_pout['paths'], cax=cax3, orientation='horizontal', extend=diff_extend) if cb_diff_ticks is not None: cb3.set_ticks(cb_diff_ticks) right_center_label(cax3, diff_units)
def plot_2D_components_and_coeffs( components, lat_e, lon_e, coeffs, explained_variance_ratio, fig_dir, name='', n_components=5, xticks=np.arange(-180.0, 180.1, 60.0), yticks=np.arange(-90.0, 90.1, 30.0), region_limit=[-90.0, -180.0, 90.0, 180.0], time_ticks=None, rotation=30.0, reverse=[], ): """ plot 2D PCA spatial pattern (ywang, 04/12/20) Parameters ---------- components : shape (n_lat, n_lon, n_components) PCA modes lat_e : shape (n_lat+1, n_lon+1) Latitude edges lon_e : shape (n_lat+1, n_lon+1) Longitude edges coeffs : shape (n_samples, n_components) PCA coefficients explained_variance_ratio : shape (n_components, ) Explained variance ratio fig_dir : str Directory to save figures n_components : int The first *n_component* modes and coeffs will be plotted. time_ticks : tuple The first element is tick positions, and the second element is tick labels. reverse : list Mode and time series to be reversed. 1-based """ # directory if fig_dir[-1] != '/': fig_dir = fig_dir + '/' # n_components n_components = min([n_components, components.shape[2], coeffs.shape[1]]) for ic in range(n_components): # begin plot nrow = 2 ncol = 1 figsize = (8, 6) projPos = [0] layout_dict = multiFigure(nrow, ncol, figsize=figsize, projPos=projPos) fig = layout_dict['fig'] axes = layout_dict['axes'] # reverse if (ic + 1) in reverse: sign = -1 else: sign = 1 # plot mode mode = components[:, :, ic] * sign vmax = np.max(np.absolute(mode)) vmin = -vmax pout = cartopy_plot(lon_e, lat_e, mode, ax=axes[0], vmin=vmin, vmax=vmax, cmap=deepcopy(gbcwpry_map), cbar=True) states_provinces = cfeature.NaturalEarthFeature( category='cultural', name='admin_1_states_provinces_lines', scale='50m', facecolor='none') axes[0].add_feature(cfeature.BORDERS) axes[0].add_feature(states_provinces, edgecolor='k', linewidth=0.5) axes[0].add_feature(cfeature.COASTLINE, zorder=200) axes[0].set_xlim((region_limit[1], region_limit[3])) axes[0].set_ylim((region_limit[0], region_limit[2])) # add title y_p = 1.03 left_title = 'Mode {}'.format(ic + 1) axes[0].text(0, y_p, left_title, ha='left', va='bottom', transform=axes[0].transAxes) right_title = '{:.1f}%'.format(explained_variance_ratio[ic] * 100) axes[0].text(1, y_p, right_title, ha='right', va='bottom', transform=axes[0].transAxes) # ticks panel_tick_label(axes[0:1], ncol, xticks=xticks, yticks=yticks) # plot coeff coeff = coeffs[:, ic] * sign x = range(len(coeff)) axes[1].plot(x, coeff, '-o', markersize=3) axes[1].set_xlabel('Month') if time_ticks is not None: axes[1].set_xticks(time_ticks[0]) axes[1].set_xticklabels(time_ticks[1], rotation=rotation) # save figure if (name != ''): figname = fig_dir + name + '_mode{}'.format(ic + 1) + '.png' else: figname = fig_dir + 'mode{}'.format(ic + 1) + '.png' plt.savefig(figname, format='png', dpi=300)
def plot_monthly_anomaly_for_6yrs(dir_mean, dir_month, start_year, end_year, year_list, month, verbose=False, region_limit=[-90.0, -180.0, 90.0, 180.0], left=0.05, right=0.98, top=0.9, bottom=0.1, wspace=0.05, hspace=0.05, y_off=-0.06, dir_fig=None, vmin_ano=-0.1, vmax_ano=0.1, xticks=np.arange(-180.0, 180.1, 20.0), yticks=np.arange(-90.0, 90.1, 10.0), name='', vmin_ano_per=-50.0, vmax_ano_per=50.0): """ Plot monhtly anomaly for 6 years """ # used to convert unit toDU = 2.69e16 # read monthly data NO2_month_dict = {} for year in year_list: file_month = dir_month + 'OMI_NO2_' + year + '-' + month \ + '_monthly.nc' NO2_month = io.read_month_OMI_NO2_L3(file_month, verbose=verbose) NO2_month = NO2_month / toDU NO2_month_dict[year] = NO2_month # read mutli-year mean of monthly NO2 NO2_mean = io.read_multi_year_month_OMI_NO2_L3(dir_mean, start_year, end_year, month, verbose=verbose) NO2_mean = NO2_mean / toDU # NO2 anomaly and relative anoamly NO2_ano_dict = {} NO2_ano_percent_dict = {} for year in year_list: # anomaly NO2_ano = NO2_month_dict[year] - NO2_mean NO2_ano_dict[year] = NO2_ano # relative anomaly NO2_ano_percent = NO2_ano / NO2_mean * 100.0 NO2_ano_percent_dict[year] = NO2_ano_percent # generate grid nlat_c, nlon_c = 720, 1440 lat_e, lon_e, lat_c, lon_c = generate_grid(nlat_c, nlon_c) # get region data i1 = get_center_index(lat_e, region_limit[0]) i2 = get_center_index(lat_e, region_limit[2]) j1 = get_center_index(lon_e, region_limit[1]) j2 = get_center_index(lon_e, region_limit[3]) lat_e = lat_e[i1:i2 + 2] lon_e = lon_e[j1:j2 + 2] # begin plot nrow = 3 ncol = 4 figsize = (12, 6) projPos = list(range(nrow * ncol)) layout_dict = multiFigure(nrow, ncol, left=left, right=right, top=top, bottom=bottom, wspace=wspace, hspace=hspace, figsize=figsize, projPos=projPos) fig = layout_dict['fig'] axes = layout_dict['axes'] ano_ax_ind = [0, 1, 4, 5, 8, 9] ano_per_ax_ind = [2, 3, 6, 7, 10, 11] pout1_list = [] pout2_list = [] for iyr in range(len(year_list)): year = year_list[iyr] # anomaly NO2_ano = NO2_ano_dict[year][i1:i2 + 1, j1:j2 + 1] pout1 = cartopy_plot(lon_e, lat_e, NO2_ano, ax=axes[ano_ax_ind[iyr]], \ vmin=vmin_ano, vmax=vmax_ano, cbar=False, \ title=year+month, cmap=plt.get_cmap('seismic')) pout1_list.append(pout1) # relative anomaly NO2_ano_percent = NO2_ano_percent_dict[year][i1:i2 + 1, j1:j2 + 1] pout2 = cartopy_plot(lon_e, lat_e, NO2_ano_percent, \ ax=axes[ano_per_ax_ind[iyr]], cbar=False, \ vmin=vmin_ano_per, vmax=vmax_ano_per, \ title=year+month, cmap=plt.get_cmap('seismic')) pout2_list.append(pout2) states_provinces = cfeature.NaturalEarthFeature( category='cultural', name='admin_1_states_provinces_lines', scale='50m', facecolor='none') # ticks panel_tick_label(axes, ncol, xticks=xticks, yticks=yticks) # set limit for ax in axes: ax.set_xlim([lon_e[0], lon_e[-1]]) ax.set_ylim([lat_e[0], lat_e[-1]]) ax.add_feature(cfeature.BORDERS) ax.add_feature(states_provinces, edgecolor='k', linewidth=0.5) ax.add_feature(cfeature.COASTLINE, zorder=200) ax.add_feature(cfeature.OCEAN, color='w', zorder=100) # anomaly colorbar cax1 = h_2_ax(fig, pout1_list[4]['ax'], pout1_list[5]['ax'], y_off=y_off) cb1 = plt.colorbar(pout1_list[4]['mesh'], cax=cax1, \ orientation='horizontal', extend='both') cb1.set_label('OMI NO2 anomaly [DU]') # relative anomaly colorbar cax2 = h_2_ax(fig, pout2_list[4]['ax'], pout2_list[5]['ax'], y_off=y_off) cb2 = plt.colorbar(pout2_list[4]['mesh'], cax=cax2, \ orientation='horizontal', extend='both') cb2.set_label('OMI NO2 relative anomaly [%]') # save figure if dir_fig is not None: figname = dir_fig + name + 'NO2_anomaly_6yrs_' + month \ + '_from_' + start_year + '-' + end_year + '.png' plt.savefig(figname, format='png', dpi=300)