Example #1
0
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]))
Example #2
0
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)
Example #3
0
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)
Example #4
0
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)
Example #5
0
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)