Пример #1
0
def get_diff_levels(key_to_data, ncolors=20, varname=""):
    """
    get nice levels for the contourf plot
    :param field:
    :type key_to_data: dict
    """

    locator = MaxNLocator(nbins=ncolors, symmetric=True)
    if varname in [
            "TT",
    ]:
        return locator.tick_values(-7, 7)
    elif varname in [
            "PR",
    ]:
        return locator.tick_values(-3, 3)

    delta = -1
    for k, field in key_to_data.items():
        if hasattr(field, "mask"):
            good_data = field[~field.mask]
        else:
            good_data = field.flatten()

        delta = max(np.round(np.percentile(np.abs(good_data), 95)), delta)

    return locator.tick_values(-delta, delta)
Пример #2
0
 def set_xticks(self, ticks=None):
     if ticks:
         super(Radialplot, self).set_xticks(ticks)
     else:
         if self.transform == "linear":
             loc = MaxNLocator(5)
             ticks = loc.tick_values(0., self.max_x)
             ticks2 = loc.tick_values(min(self.sez), max(self.sez))
             ticks2 = ticks2[::-1]
             ticks2[-1] = min(self.sez)
             super(Radialplot, self).set_xticks(1.0 / ticks2)
             labels = [str(int(val * 1e-6)) for val in ticks2]
             self.xaxis.set_ticklabels(labels)
             self.spines["bottom"].set_bounds(0., 1. / ticks2[-1])
             self.set_xlabel(r'$\sigma$ (Myr)')
         elif self.transform == "logarithmic":
             loc = MaxNLocator(5)
             ticks = loc.tick_values(0., self.max_x)
             super(Radialplot, self).set_xticks(ticks)
             self.spines["bottom"].set_bounds(ticks[0], ticks[-1])
             self.set_xlabel(r'$t / \sigma$')
             self._second_axis()
         elif self.transform == "arcsine":
             loc = MaxNLocator(5)
             ticks = loc.tick_values(0., self.max_x)
             super(Radialplot, self).set_xticks(ticks)
             labels = [str(int(val**2 / 4.0)) for val in ticks]
             self.xaxis.set_ticklabels(labels)
             self.spines["bottom"].set_bounds(ticks[0], ticks[-1])
             self.set_xlabel("Ns + Ni")
Пример #3
0
    def _second_axis(self):
        def tick_function(x):
            with np.errstate(divide='ignore'):
                v = 1. / x
            return [
                "{0}%".format(int(val * 100)) if val != np.inf else ""
                for val in v
            ]

        twin_axis = self.twiny()
        twin_axis.set_xlim(self.get_xlim())

        loc = MaxNLocator(5)
        ticks = loc.tick_values(0, self.max_x)
        twin_axis.spines["bottom"].set_bounds(ticks[0], ticks[-1])

        twin_axis.xaxis.set_ticks_position("bottom")
        twin_axis.xaxis.set_label_position("bottom")
        twin_axis.tick_params(axis="x", direction="in", pad=-15)
        twin_axis.spines["bottom"].set_position(("axes", 0.))
        twin_axis.set_frame_on(True)
        twin_axis.patch.set_visible(False)
        for key, sp in twin_axis.spines.items():
            sp.set_visible(False)
        twin_axis.spines["bottom"].set_visible(True)

        twin_axis.set_xticks(ticks)
        twin_axis.set_xticklabels(tick_function(ticks))
        twin_axis.set_xlabel(r'$\sigma / t$', labelpad=-30)

        self.taxis = twin_axis
        return
Пример #4
0
 def ticks_locator(self, ticks=None):
     if not ticks:
         ages = self.ax._z2t(self.ax.z)
         start, end = np.int(np.rint(min(ages))), np.int(np.rint(max(ages)))
         loc = MaxNLocator()
         ticks = loc.tick_values(start, end)
     return ticks
Пример #5
0
    def plot_comparisons_of_seasonal_sst_with_homa_obs(self, start_year=None, end_year=None, season_to_months=None,
                                                       exp_label=""):

        model_data = self.get_seasonal_mean_lst(season_to_months=season_to_months,
                                                start_year=start_year, end_year=end_year)

        obs_sst_path = os.path.expanduser("~/skynet3_rech1/nemo_obs_for_validation/GreatLakes_2003_5km-2/sst-glk.nc")

        obs_data = self.read_and_interpolate_homa_data(path=obs_sst_path, start_year=start_year, end_year=end_year,
                                                       season_to_months=season_to_months)

        plot_utils.apply_plot_params(font_size=10, width_pt=None, width_cm=20, height_cm=10)
        # calculate climatologic differences
        diff = {}
        for season in list(season_to_months.keys()):
            diff[season] = np.mean(
                [model_data[y][season] - obs_data[y][season] for y in range(start_year, end_year + 1)], axis=0)
            diff[season] = np.ma.masked_where(~self.lake_mask, diff[season])
            the_field = diff[season]
            print("diff stats({}): min={}; max={}; avg={}".format(
                season, the_field.min(), the_field.max(), the_field.mean()))


        # plot seasonal biases
        xx, yy = self.basemap(self.lons.copy(), self.lats.copy())


        # calculate difference ranges
        diff_max = 0
        for season, the_diff in diff.items():
            diff_max = max(np.percentile(np.abs(the_diff[~the_diff.mask]), 90), diff_max)
        diff_max = 5

        locator = MaxNLocator(nbins=12, symmetric=True)
        bounds = locator.tick_values(-diff_max, diff_max)
        bn = BoundaryNorm(bounds, len(bounds) - 1)
        cmap = cm.get_cmap("RdBu_r", len(bounds) - 1)

        im = None
        fig = plt.figure()
        ncols = 2
        # fig.suptitle(r"LST $\left({\rm ^\circ C}\right)$", font_properties=FontProperties(weight="bold"))
        gs = GridSpec(len(season_to_months) // ncols, ncols + 1, width_ratios=[1.0, ] * ncols + [0.05, ])
        for i, season in enumerate(season_to_months.keys()):
            ax = fig.add_subplot(gs[i // ncols, i % ncols])
            im = self.basemap.pcolormesh(xx, yy, diff[season][:], ax=ax, cmap=cmap, norm=bn)
            ax.set_title(season)
            self.basemap.drawcoastlines(ax=ax, linewidth=0.5)
            if not i:
                ax.set_ylabel("NEMO - Obs")

        cb = plt.colorbar(im, ticks=locator, cax=fig.add_subplot(gs[:, -1]), extend="both")

        nemo_img_dir = "nemo"
        if not os.path.isdir(nemo_img_dir):
            os.mkdir(nemo_img_dir)

        plt.tight_layout()
        fig.savefig(os.path.join(nemo_img_dir, "sst_homa_validation_{}.pdf".format(exp_label)))
        plt.show()
Пример #6
0
def get_boundary_norm(vmin,
                      vmax,
                      ncolors,
                      exclude_zero=False,
                      varname=None,
                      difference=False):

    bounds = None

    # custom variable norms
    if difference:
        pass
    else:
        if varname == "TRAF":
            bounds = [0, 0.1, 0.5] + list(range(1, ncolors - 3)) + [
                vmax,
            ]

    # temperature

    # Do not do anything if bounds were already calculated
    if bounds is None:
        if vmin * vmax >= 0:
            locator = MaxNLocator(ncolors)
            bounds = np.asarray(locator.tick_values(vmin, vmax))
        elif exclude_zero:
            # implies that this is the case for difference
            delta = max(abs(vmax), abs(vmin))
            assert ncolors % 2 == 1
            d = 2.0 * delta / float(ncolors)
            print(d, np.log10(d))
            ndec = -int(np.floor(np.log10(d)))
            print(ndec)
            d = np.round(d, decimals=ndec)

            assert d > 0
            print("ncolors = {0}".format(ncolors))

            negats = [-d / 2.0 - d * i for i in range((ncolors - 1) / 2)]
            bounds = negats[::-1] + [-the_bound for the_bound in negats]
            assert 0 not in bounds
            assert bounds[0] == -bounds[-1]
        else:
            locator = MaxNLocator(nbins=ncolors, symmetric=True)
            bounds = np.asarray(locator.tick_values(vmin, vmax))

    return BoundaryNorm(bounds, ncolors=ncolors), bounds, bounds[0], bounds[-1]
Пример #7
0
def get_boundary_norm(vmin, vmax, ncolors, exclude_zero=False, varname = None, difference = False):

    bounds = None


    # custom variable norms
    if difference:
        pass
    else:
        if varname == "TRAF":
            bounds = [0, 0.1, 0.5] + list(range(1, ncolors - 3)) + [vmax, ]

    # temperature


    # Do not do anything if bounds were already calculated
    if bounds is None:
        if vmin * vmax >= 0:
            locator = MaxNLocator(ncolors)
            bounds = np.asarray(locator.tick_values(vmin, vmax))
        elif exclude_zero:
            # implies that this is the case for difference
            delta = max(abs(vmax), abs(vmin))
            assert ncolors % 2 == 1
            d = 2.0 * delta / float(ncolors)
            print(d, np.log10(d))
            ndec = -int(np.floor(np.log10(d)))
            print(ndec)
            d = np.round(d, decimals=ndec)

            assert d > 0
            print("ncolors = {0}".format(ncolors))

            negats = [-d / 2.0 - d * i for i in range((ncolors - 1) / 2)]
            bounds = negats[::-1] + [-the_bound for the_bound in negats]
            assert 0 not in bounds
            assert bounds[0] == -bounds[-1]
        else:
            locator = MaxNLocator(nbins=ncolors, symmetric=True)
            bounds = np.asarray(locator.tick_values(vmin, vmax))






    return BoundaryNorm(bounds, ncolors=ncolors), bounds, bounds[0], bounds[-1]
Пример #8
0
def get_boundary_norm_using_all_vals(to_plot, ncolors):
    vmin = np.percentile(to_plot[~to_plot.mask], 5)
    vmax = np.percentile(to_plot[~to_plot.mask], 95)
    med = np.median(to_plot[~to_plot.mask])
    locator = MaxNLocator(ncolors)
    bounds = locator.tick_values(vmin, vmax)

    return BoundaryNorm(bounds, ncolors=ncolors), bounds, bounds[0], bounds[-1]
Пример #9
0
def get_boundary_norm_using_all_vals(to_plot, ncolors):
    vmin = np.percentile(to_plot[~to_plot.mask], 5)
    vmax = np.percentile(to_plot[~to_plot.mask], 95)
    med = np.median(to_plot[~to_plot.mask])
    locator = MaxNLocator(ncolors)
    bounds = locator.tick_values(vmin, vmax)

    return BoundaryNorm(bounds, ncolors=ncolors), bounds, bounds[0], bounds[-1]
Пример #10
0
def get_best_map_ticks(ax, transform=None):
    """
    Use the matplotlib.ticker class to automatically set nice values for the major and minor ticks.
    Log axes generally come out nicely spaced without needing manual intervention. For particularly narrow latitude
    vs longitude plots the ticks can come out overlapped, so an exception is included to deal with this.
    """
    from matplotlib.ticker import MaxNLocator

    max_x_bins = 9
    max_y_bins = 7  # as plots are wider rather than taller

    lon_steps = [1, 3, 6, 9, 10]
    lat_steps = [1, 3, 6, 9, 10]
    variable_step = [1, 2, 4, 5, 10]

    xmin, xmax, ymin, ymax = ax.get_extent(crs=transform)
    # ymin, ymax = ax.get_ylim()

    if (xmax - xmin) < 5:
        lon_steps = variable_step
    if (ymax - ymin) < 5:
        lat_steps = variable_step

    # We need to make a special exception for particularly narrow and wide plots, which will be lat vs lon
    # preserving the aspect ratio. This gives more options for the spacing to try and find something that can use
    # the maximum number of bins.
    if (ymax - ymin) > 2.2 * (xmax - xmin):
        max_x_bins = 4
        max_y_bins = 11
    elif (xmax - xmin) > 2.2 * (ymax - ymin):
        max_x_bins = 14
        max_y_bins = 4

    lon_locator = MaxNLocator(nbins=max_x_bins, steps=lon_steps)
    lat_locator = MaxNLocator(nbins=max_y_bins, steps=lat_steps)
    lon_ticks = lon_locator.tick_values(xmin, xmax)
    # Prune any large longitude ticks
    lon_ticks = [t for t in lon_ticks if abs(t) <= 360.0]
    lat_ticks = lat_locator.tick_values(ymin, ymax)
    # Prune any large latitude ticks
    lat_ticks = [t for t in lat_ticks if abs(t) <= 90.0]
    return lon_ticks, lat_ticks
Пример #11
0
def get_best_map_ticks(ax, transform=None):
    """
    Use the matplotlib.ticker class to automatically set nice values for the major and minor ticks.
    Log axes generally come out nicely spaced without needing manual intervention. For particularly narrow latitude
    vs longitude plots the ticks can come out overlapped, so an exception is included to deal with this.
    """
    from matplotlib.ticker import MaxNLocator

    max_x_bins = 9
    max_y_bins = 7  # as plots are wider rather than taller

    lon_steps = [1, 3, 6, 9, 10]
    lat_steps = [1, 3, 6, 9, 10]
    variable_step = [1, 2, 4, 5, 10]

    xmin, xmax, ymin, ymax = ax.get_extent(crs=transform)
    # ymin, ymax = ax.get_ylim()

    if (xmax - xmin) < 5:
        lon_steps = variable_step
    if (ymax - ymin) < 5:
        lat_steps = variable_step

    # We need to make a special exception for particularly narrow and wide plots, which will be lat vs lon
    # preserving the aspect ratio. This gives more options for the spacing to try and find something that can use
    # the maximum number of bins.
    if (ymax - ymin) > 2.2 * (xmax - xmin):
        max_x_bins = 4
        max_y_bins = 11
    elif (xmax - xmin) > 2.2 * (ymax - ymin):
        max_x_bins = 14
        max_y_bins = 4

    lon_locator = MaxNLocator(nbins=max_x_bins, steps=lon_steps)
    lat_locator = MaxNLocator(nbins=max_y_bins, steps=lat_steps)
    lon_ticks = lon_locator.tick_values(xmin, xmax)
    # Prune any large longitude ticks
    lon_ticks = [t for t in lon_ticks if abs(t) <= 360.0]
    lat_ticks = lat_locator.tick_values(ymin, ymax)
    # Prune any large latitude ticks
    lat_ticks = [t for t in lat_ticks if abs(t) <= 90.0]
    return lon_ticks, lat_ticks
Пример #12
0
def get_diff_levels(key_to_data, ncolors=20, varname=""):
    """
    get nice levels for the contourf plot
    :param field:
    :type key_to_data: dict
    """

    locator = MaxNLocator(nbins=ncolors, symmetric=True)
    if varname in ["TT", ]:
        return locator.tick_values(-7, 7)
    elif varname in ["PR", ]:
        return locator.tick_values(-3, 3)

    delta = -1
    for k, field in key_to_data.items():
        if hasattr(field, "mask"):
            good_data = field[~field.mask]
        else:
            good_data = field.flatten()

        delta = max(np.round(np.percentile(np.abs(good_data), 95)), delta)

    return locator.tick_values(-delta, delta)
Пример #13
0
def get_colormap_and_norm_for(var_name,
                              to_plot=None,
                              ncolors=10,
                              vmin=None,
                              vmax=None):
    """
    If vmin or vmax is None then to_plot parameter is required
    :param var_name:
    :param ncolors: Number of discrete colors in the colorbar, try to take a good number like 10, 5, ...
    :return:

    Note: when `var_name` is STFL, the parameter ncolors is ignored

    """
    if None in [vmin, vmax]:
        vmin, vmax = to_plot.min(), to_plot.max()

    locator = MaxNLocator(ncolors)
    clevs = locator.tick_values(vmin, vmax)
    if var_name in ["STFL", "STFA"]:
        upper = 1000
        bounds = [0, 100, 200, 500, 1000]
        while upper <= vmax:
            upper += 1000
            bounds.append(upper)
        ncolors = len(bounds) - 1

        cmap = cm.get_cmap("Blues", ncolors)
        norm = BoundaryNorm(
            bounds, ncolors=ncolors
        )  # LogNorm(vmin=10 ** (pmax - ncolors), vmax=10 ** pmax)
    else:
        reverse = True
        # if var_name in ["PR"]:
        #     reverse = False

        cmap = cm.get_cmap("Spectral_r" if reverse else "Spectral",
                           len(clevs) - 1)

        # norm, bounds, vmin_nice, vmax_nice = get_boundary_norm_using_all_vals(to_plot, ncolors)

        norm = BoundaryNorm(clevs, len(clevs) - 1)

    return cmap, norm
Пример #14
0
class mpl_breaks:
    """
    Compute breaks using MPL's default locator

    See :class:`~matplotlib.ticker.MaxNLocator` for the
    parameter descriptions

    Examples
    --------
    >>> x = range(10)
    >>> limits = (0, 9)
    >>> mpl_breaks()(limits)
    array([0., 1., 2., 3., 4., 5., 6., 7., 8., 9.])
    >>> mpl_breaks(nbins=2)(limits)
    array([  0.,   5.,  10.])
    """
    def __init__(self, *args, **kwargs):
        self.locator = MaxNLocator(*args, **kwargs)

    def __call__(self, limits):
        """
        Compute breaks

        Parameters
        ----------
        limits : tuple
            Minimum and maximum values

        Returns
        -------
        out : array_like
            Sequence of breaks points
        """
        if any(np.isinf(limits)):
            return []

        if limits[0] == limits[1]:
            return np.array([limits[0]])

        return self.locator.tick_values(limits[0], limits[1])
Пример #15
0
class mpl_breaks:
    """
    Compute breaks using MPL's default locator

    See :class:`~matplotlib.ticker.MaxNLocator` for the
    parameter descriptions

    Examples
    --------
    >>> x = range(10)
    >>> limits = (0, 9)
    >>> mpl_breaks()(limits)
    array([0., 1., 2., 3., 4., 5., 6., 7., 8., 9.])
    >>> mpl_breaks(nbins=2)(limits)
    array([  0.,   5.,  10.])
    """
    def __init__(self, *args, **kwargs):
        self.locator = MaxNLocator(*args, **kwargs)

    def __call__(self, limits):
        """
        Compute breaks

        Parameters
        ----------
        limits : tuple
            Minimum and maximum values

        Returns
        -------
        out : array_like
            Sequence of breaks points
        """
        if any(np.isinf(limits)):
            return []

        if limits[0] == limits[1]:
            return np.array([limits[0]])

        return self.locator.tick_values(limits[0], limits[1])
Пример #16
0
def get_colormap_and_norm_for(var_name, to_plot=None, ncolors=10, vmin=None, vmax=None):
    """
    If vmin or vmax is None then to_plot parameter is required
    :param var_name:
    :param ncolors: Number of discrete colors in the colorbar, try to take a good number like 10, 5, ...
    :return:

    Note: when `var_name` is STFL, the parameter ncolors is ignored

    """
    if None in [vmin, vmax]:
        vmin, vmax = to_plot.min(), to_plot.max()

    locator = MaxNLocator(ncolors)
    clevs = locator.tick_values(vmin, vmax)
    if var_name in ["STFL", "STFA"]:
        upper = 1000
        bounds = [0, 100, 200, 500, 1000]
        while upper <= vmax:
            upper += 1000
            bounds.append(upper)
        ncolors = len(bounds) - 1

        cmap = cm.get_cmap("Blues", ncolors)
        norm = BoundaryNorm(bounds, ncolors=ncolors)  # LogNorm(vmin=10 ** (pmax - ncolors), vmax=10 ** pmax)
    else:
        reverse = True
        # if var_name in ["PR"]:
        #     reverse = False

        cmap = cm.get_cmap("Spectral_r" if reverse else "Spectral", len(clevs) - 1)

        # norm, bounds, vmin_nice, vmax_nice = get_boundary_norm_using_all_vals(to_plot, ncolors)

        norm = BoundaryNorm(clevs, len(clevs) - 1)

    return cmap, norm
def _plot_var(vname="", level=0, config_dict=None, data_dict=None):
    modif_label = config_dict.label_modif
    base_label = config_dict.label_base

    base_config_c, modif_config_c = [config_dict["Current"][the_label] for the_label in [base_label, modif_label]]
    base_config_f, modif_config_f = [config_dict["Future"][the_label] for the_label in [base_label, modif_label]]

    bmp = config_dict.basemap
    lons = config_dict.lons
    lons[lons > 180] -= 360

    lats = config_dict.lats
    xx, yy = bmp(lons, lats)

    i_to_label = {
        0: base_label,
        1: modif_label,
        2: "{}\n--\n{}".format(modif_label, base_label)
    }

    j_to_title = {
        0: "Current ({}-{})".format(base_config_c.start_year, base_config_c.end_year),
        1: "Future ({}-{})".format(base_config_f.start_year, base_config_f.end_year),
        2: "Future - Current"
    }

    # Create a folder for images
    img_folder = os.path.join("cc_paper", "{}_vs_{}".format(modif_label, base_label))
    if not os.path.isdir(img_folder):
        os.makedirs(img_folder)

    nrows = ncols = 3
    plot_utils.apply_plot_params(font_size=10, width_pt=None, width_cm=27, height_cm=20)

    field_cmap = cm.get_cmap("jet", 20)
    diff_cmap = cm.get_cmap("RdBu_r", 20)

    for season in list(data_dict[base_config_c].keys()):

        fig = plt.figure()
        fig.suptitle(
            "{} ({})".format(infovar.get_long_display_label_for_var(vname), season),
            font_properties=FontProperties(weight="bold"))

        gs = GridSpec(nrows=nrows, ncols=ncols)

        mean_c_base = data_dict[base_config_c][season].mean(axis=0)
        mean_f_base = data_dict[base_config_f][season].mean(axis=0)


        mean_c_modif = data_dict[modif_config_c][season].mean(axis=0)
        mean_f_modif = data_dict[modif_config_f][season].mean(axis=0)


        print("------------ {}, {} --------------".format(vname, season))
        print("data_dict[base_config_c][season].shape = {}".format(data_dict[base_config_c][season].shape))
        _, p_signif_base_cc = ttest_ind(data_dict[base_config_c][season], data_dict[base_config_f][season], axis=0, equal_var=False)
        _, p_signif_current = ttest_ind(data_dict[base_config_c][season], data_dict[modif_config_c][season], axis=0, equal_var=False)

        print("Base p-value ranges: {} to {}".format(p_signif_base_cc.min(), p_signif_base_cc.max()))
        _, p_signif_modif_cc = ttest_ind(data_dict[modif_config_c][season], data_dict[modif_config_f][season], axis=0, equal_var=False)
        _, p_signif_future = ttest_ind(data_dict[base_config_f][season], data_dict[modif_config_f][season], axis=0, equal_var=False)

        ij_to_pvalue = {
            (0, 2): p_signif_base_cc,
            (1, 2): p_signif_modif_cc,
            (2, 0): p_signif_current,
            (2, 1): p_signif_future,
            # (2, 2): np.minimum(p_signif_current, p_signif_future)
        }

        ij_to_data = {
            (0, 0): mean_c_base, (1, 0): mean_c_modif,
            (0, 1): mean_f_base, (1, 1): mean_f_modif
        }

        # Apply multipliers for unit conversion
        for k in list(ij_to_data.keys()):
            ij_to_data[k] *= multiplier_dict.get(vname, 1)

            # mask oceans
            mask_inland = vname in ["STFL", "STFA"] or vname.startswith("I")
            ij_to_data[k] = maskoceans(lonsin=lons, latsin=lats, datain=ij_to_data[k], inlands=mask_inland)

        # get all means to calculate the ranges of mean fields
        all_means = []
        for vals in ij_to_data.values():
            all_means.extend(vals[~vals.mask])

        if vname == "PR":
            # mm/day
            minval = 0
            maxval = 5
            extend_val = "max"
        else:
            minval = np.percentile(all_means, 1)
            maxval = np.percentile(all_means, 95)
            extend_val = "neither"


        d1 = ij_to_data[0, 1] - ij_to_data[0, 0]
        d2 = ij_to_data[1, 1] - ij_to_data[1, 0]
        all_cc_diffs = np.ma.asarray([d1, d2])
        mindiff_cc = np.percentile(all_cc_diffs[~all_cc_diffs.mask], 1)
        maxdiff_cc = np.percentile(all_cc_diffs[~all_cc_diffs.mask], 99)

        maxdiff_cc = max(np.ma.abs(maxdiff_cc), np.ma.abs(mindiff_cc))

        # Limit the temperature change scale
        if vname == "TT":
            maxdiff_cc = min(maxdiff_cc, 10)


        mindiff_cc = -maxdiff_cc


        # Add all differences due to changed processes in a list
        all_proc_diffs = []

        d1 = ij_to_data[1, 0] - ij_to_data[0, 0]
        d2 = ij_to_data[1, 1] - ij_to_data[0, 1]
        all_proc_diffs.extend([d1, d2])
        all_proc_diffs.append(d2 - d1)
        all_proc_diffs = np.ma.asarray(all_proc_diffs)


        mindiff_proc = np.percentile(all_proc_diffs[~all_proc_diffs.mask], 1)
        maxdiff_proc = np.percentile(all_proc_diffs[~all_proc_diffs.mask], 95)

        maxdiff_proc = max(np.abs(maxdiff_proc), np.abs(mindiff_proc))
        mindiff_proc = -maxdiff_proc

        plot_data = []
        for row in range(nrows - 1):
            row_data = []
            for col in range(ncols - 1):
                row_data.append(ij_to_data[row, col])
            plot_data.append(row_data + [0, ])

        # calculate differences between different model configurations
        row = 2
        plot_data.append([0, 0, 0])
        for col in range(2):
            plot_data[row][col] = plot_data[1][col] - plot_data[0][col]

        # calculate CC
        col = 2
        for row in range(3):
            plot_data[row][col] = plot_data[row][1] - plot_data[row][0]


        # Do the plotting
        for i in range(nrows):
            for j in range(ncols):

                ax = fig.add_subplot(gs[i, j])
                plotting_values = (i < 2) and (j < 2)

                if plotting_values:
                    the_min, the_max = minval, maxval
                elif i == nrows - 1:
                    the_min, the_max = mindiff_proc, maxdiff_proc
                else:
                    the_min, the_max = mindiff_cc, maxdiff_cc

                the_cmap = field_cmap if plotting_values else diff_cmap

                locator = MaxNLocator(nbins=the_cmap.N // 2, symmetric=not plotting_values)
                bounds = locator.tick_values(the_min, the_max)

                if vname in ["STFA", "STFL"] and plotting_values:
                    the_min = 1.0e-5
                    the_max = 1.0e4

                    locator = LogLocator(numticks=11)
                    bounds = locator.tick_values(the_min, the_max)

                    print(bounds)

                    norm = LogNorm(vmin=bounds[0], vmax=bounds[-1])

                    plot_data[i][j] = np.ma.masked_where(plot_data[i][j] <= the_min, plot_data[i][j])
                    print("the_max = {}".format(the_max))

                    the_cmap = cm.get_cmap("jet", len(bounds) - 1)

                else:
                    norm = BoundaryNorm(bounds, the_cmap.N)

                extend = "both" if not plotting_values else extend_val

                if plotting_values:
                    print(i, j, the_min, the_max)

                im = bmp.pcolormesh(xx, yy, plot_data[i][j][:, :], cmap=the_cmap, norm=norm)

                if (i, j) in ij_to_pvalue:
                    p = ij_to_pvalue[i, j]
                    # not_signif = (p > 0.2)
                    # not_signif = np.ma.masked_where(~not_signif, not_signif) * 0.75
                    # not_signif = np.ma.masked_where(plot_data[i][j].mask, not_signif)
                    # bmp.pcolormesh(xx, yy, not_signif, vmin=0, vmax=1, cmap=cm.get_cmap("gray", 20))
                    p = np.ma.masked_where(plot_data[i][j].mask, p)
                    cs = bmp.contourf(xx, yy, p, hatches=["..."], levels=[0.1, 1], colors='none')
                    # create a legend for the contour set
                    # artists, labels = cs.legend_elements()
                    # ax.legend(artists, labels, handleheight=2)


                bmp.colorbar(im, ticks=bounds, extend=extend)
                bmp.drawcoastlines(ax=ax, linewidth=0.5)

                ax.set_title(j_to_title.get(j, "") if i == 0 else "")
                ax.set_ylabel(i_to_label.get(i, "") if j == 0 else "")

        # Save the image to the file
        img_name = "{}_{}_{}-{}_{}-{}.png".format(
            vname + str(level), season,
            base_config_f.start_year, base_config_f.end_year,
            base_config_c.start_year, base_config_c.end_year)

        img_path = os.path.join(img_folder, img_name)
        fig.savefig(img_path, bbox_inches="tight")
        plt.close(fig)
Пример #18
0
def main():
    start_year_c = 1980
    end_year_c = 2010

    img_folder = "cc_paper"

    current_path = "/RESCUE/skynet3_rech1/huziy/hdf_store/cc-canesm2-driven/quebec_0.1_crcm5-hcd-rl-intfl-cc-canesm2-1980-2010.hdf5"
    base_label = "CRCM5-LI"

    # Need to read land fraction
    geo_file_path = "/RESCUE/skynet3_rech1/huziy/hdf_store/pm1979010100_00000000p"

    r_obj = RPN(geo_file_path)
    mg_field = r_obj.get_first_record_for_name("MG")

    lons, lats = r_obj.get_longitudes_and_latitudes_for_the_last_read_rec()
    r_obj.close()

    future_shift_years = 90

    params = dict(data_path=current_path,
                  start_year=start_year_c,
                  end_year=end_year_c,
                  label=base_label)

    base_config_c = RunConfig(**params)
    base_config_f = base_config_c.get_shifted_config(future_shift_years)

    varname = "INTF"
    level = 0
    daily_dates, intf_c = analysis.get_daily_climatology(
        path_to_hdf_file=base_config_c.data_path,
        var_name=varname,
        level=level,
        start_year=base_config_c.start_year,
        end_year=base_config_c.end_year)

    _, intf_f = analysis.get_daily_climatology(
        path_to_hdf_file=base_config_f.data_path,
        var_name=varname,
        level=level,
        start_year=base_config_f.start_year,
        end_year=base_config_f.end_year)

    mg_fields = np.asarray([mg_field for d in daily_dates])

    mg_crit = 0.0001
    the_mask = mg_fields <= mg_crit
    # Convert to mm/day as well
    intf_c = _avg_along_lon(intf_c, the_mask) * 24 * 3600
    intf_f = _avg_along_lon(intf_f, the_mask) * 24 * 3600

    lats_agg = lats.mean(axis=0)
    num_dates = date2num(daily_dates)

    lats_agg_2d, num_dates_2d = np.meshgrid(lats_agg, num_dates)

    # Do the plotting
    fig = plt.figure()

    gs = GridSpec(2, 3, width_ratios=[1, 1, 0.05])
    norm = SymLogNorm(5e-5)

    all_axes = []
    # Current
    ax = fig.add_subplot(gs[0, 0])
    cs = ax.contourf(num_dates_2d, lats_agg_2d, intf_c[:], 60, norm=norm)
    ax.set_title("Current ({}-{})".format(base_config_c.start_year,
                                          base_config_c.end_year))
    all_axes.append(ax)

    # Future
    ax = fig.add_subplot(gs[0, 1])
    ax.set_title("Future ({}-{})".format(base_config_f.start_year,
                                         base_config_f.end_year))
    cs = ax.contourf(num_dates_2d,
                     lats_agg_2d,
                     intf_f[:],
                     levels=cs.levels,
                     norm=norm)
    all_axes.append(ax)

    # Colorbar for value plots
    cax = fig.add_subplot(gs[0, 2])

    sfmt = ScalarFormatter(useMathText=True)
    sfmt.set_powerlimits((-1, 2))

    plt.colorbar(cs, cax=cax, format=sfmt)
    cax.set_xlabel("mm/day")
    cax.yaxis.get_offset_text().set_position((-2, 10))

    # CC
    diff_cmap = cm.get_cmap("RdBu_r", 20)
    diff = (intf_f - intf_c) / (0.5 * (intf_c + intf_f)) * 100
    diff[(intf_f == 0) & (intf_c == 0)] = 0
    print(np.min(diff), np.max(diff))
    print(np.any(diff.mask))
    print(np.any(intf_c.mask))
    print(np.any(intf_f.mask))
    delta = 200
    vmin = -delta
    vmax = delta
    locator = MaxNLocator(nbins=20, symmetric=True)
    clevs = locator.tick_values(vmin=vmin, vmax=vmax)

    ax = fig.add_subplot(gs[1, 1])

    cs = ax.contourf(num_dates_2d,
                     lats_agg_2d,
                     diff,
                     cmap=diff_cmap,
                     levels=clevs,
                     extend="both")
    ax.set_title("Future - Current")
    # ax.set_aspect("auto")
    all_axes.append(ax)
    cb = plt.colorbar(cs, cax=fig.add_subplot(gs[1, -1]))
    cb.ax.set_xlabel(r"%")

    for i, the_ax in enumerate(all_axes):
        the_ax.xaxis.set_minor_formatter(
            FuncFormatter(lambda d, pos: num2date(d).strftime("%b")[0]))
        the_ax.xaxis.set_major_formatter(FuncFormatter(lambda d, pos: ""))
        the_ax.xaxis.set_minor_locator(MonthLocator(bymonthday=15))
        the_ax.xaxis.set_major_locator(MonthLocator())
        the_ax.grid()
        if i != 1:
            the_ax.set_ylabel(r"Latitude ${\rm \left(^\circ N \right)}$")

    # identify approximately the melting period and lower latitudes
    march1 = date2num(datetime(daily_dates[0].year, 3, 1))
    june1 = date2num(datetime(daily_dates[0].year, 6, 1))

    sel_mask = (num_dates_2d >= march1) & (num_dates_2d < june1) & (lats_agg_2d
                                                                    <= 50)
    print("Mean interflow decrease in the southern regions: {}%".format(
        diff[sel_mask].mean()))

    # identify the regions of max interflow rates in current and future climates
    lat_min = 55
    lat_max = 57.5

    may1 = date2num(datetime(daily_dates[0].year, 5, 1))
    july1 = date2num(datetime(daily_dates[0].year, 7, 1))

    mean_max_current = intf_c[(lats_agg_2d >= lat_min)
                              & (lats_agg_2d <= lat_max) &
                              (num_dates_2d <= july1) &
                              (num_dates_2d >= june1)].mean()
    mean_max_future = intf_f[(lats_agg_2d >= lat_min)
                             & (lats_agg_2d <= lat_max) &
                             (num_dates_2d <= june1) &
                             (num_dates_2d >= may1)].mean()

    print("Mean change in the maximum interflow rate: {} %".format(
        (mean_max_future - mean_max_current) * 100 / mean_max_current))

    img_file = Path(img_folder).joinpath("INTF_rate_longit_avg.png")
    fig.tight_layout()
    from crcm5.analyse_hdf import common_plot_params
    fig.savefig(str(img_file),
                bbox_inches="tight",
                transparent=True,
                dpi=common_plot_params.FIG_SAVE_DPI)
def main():
    start_year_c = 1980
    end_year_c = 2010

    img_folder = "cc_paper"

    current_path = "/RESCUE/skynet3_rech1/huziy/hdf_store/cc-canesm2-driven/quebec_0.1_crcm5-hcd-rl-cc-canesm2-1980-2010.hdf5"
    base_label = "CRCM5-L"

    # Need to read land fraction
    geo_file_path = "/RESCUE/skynet3_rech1/huziy/hdf_store/pm1979010100_00000000p"

    r_obj = RPN(geo_file_path)
    mg_field = r_obj.get_first_record_for_name("MG")

    lons, lats = r_obj.get_longitudes_and_latitudes_for_the_last_read_rec()
    r_obj.close()

    future_shift_years = 75

    params = dict(data_path=current_path,
                  start_year=start_year_c,
                  end_year=end_year_c,
                  label=base_label)

    base_config_c = RunConfig(**params)
    base_config_f = base_config_c.get_shifted_config(future_shift_years)

    data_path = "/RESCUE/skynet3_rech1/huziy/hdf_store/cc-canesm2-driven/quebec_0.1_crcm5-hcd-rl-intfl-cc-canesm2-1980-2010.hdf5"
    params.update(dict(data_path=data_path, label="CRCM5-LI"))

    modif_config_c = RunConfig(**params)
    modif_config_f = modif_config_c.get_shifted_config(future_shift_years)

    varnames = ["I1+I2", "I0", "PR", "TRAF", "AV", "I0_max", "I0_min"]
    levels = [0, 0, 0, 0, 0, 0, 0]
    var_labels = ["SM", "ST", "PR", "TRAF", "LHF", "STmin", "STmax"]

    # width of the first soil layer in mm
    multipliers = [100, 1, 1000 * 24 * 3600, 24 * 3600, 1, 1, 1]
    offsets = [
        0,
    ] * len(varnames)
    units = ["mm", "K", "mm/day", "mm/day", r"${\rm W/m^2}$", "K", "K"]

    SimData = collections.namedtuple("SimData",
                                     "base_c base_f modif_c modif_f")

    mg_fields = None

    fig = plt.figure()
    gs = GridSpec(len(varnames), 5, width_ratios=2 * [
        1,
    ] + [0.05, 1, 0.05])

    lats_agg = lats.mean(axis=0)

    diff_cmap = cm.get_cmap("RdBu_r", 10)
    the_zip = zip(varnames, levels, var_labels, multipliers, offsets, units)
    row = 0
    for vname, level, var_label, multiplier, offset, unit_label in the_zip:

        daily_dates, base_data_c = analysis.get_daily_climatology(
            path_to_hdf_file=base_config_c.data_path,
            var_name=vname,
            level=level,
            start_year=base_config_c.start_year,
            end_year=base_config_c.end_year)

        _, base_data_f = analysis.get_daily_climatology(
            path_to_hdf_file=base_config_f.data_path,
            var_name=vname,
            level=level,
            start_year=base_config_f.start_year,
            end_year=base_config_f.end_year)

        _, modif_data_c = analysis.get_daily_climatology(
            path_to_hdf_file=modif_config_c.data_path,
            var_name=vname,
            level=level,
            start_year=modif_config_c.start_year,
            end_year=modif_config_c.end_year)

        _, modif_data_f = analysis.get_daily_climatology(
            path_to_hdf_file=modif_config_f.data_path,
            var_name=vname,
            level=level,
            start_year=modif_config_f.start_year,
            end_year=modif_config_f.end_year)

        if mg_fields is None:
            mg_fields = np.asarray([mg_field for d in daily_dates])
            num_dates = date2num(daily_dates)

            # create 2d dates and latitudes for the contour plots
            lats_agg_2d, num_dates_2d = np.meshgrid(lats_agg, num_dates)

        sim_data = SimData(_avg_along_lon(base_data_c, mg_fields),
                           _avg_along_lon(base_data_f, mg_fields),
                           _avg_along_lon(modif_data_c, mg_fields),
                           _avg_along_lon(modif_data_f, mg_fields))

        # Unit conversion
        sim_data = SimData(*[multiplier * si + offset for si in sim_data])

        # Plot the row for the variable
        all_axes = []

        # Calculate nice color levels
        delta = np.percentile(
            np.abs([
                sim_data.modif_c - sim_data.base_c,
                sim_data.modif_f - sim_data.base_f
            ]), 99)
        vmin = -delta
        vmax = delta
        locator = MaxNLocator(nbins=10, symmetric=True)
        clevs = locator.tick_values(vmin=vmin, vmax=vmax)

        # Current
        ax = fig.add_subplot(gs[row, 0])
        cs = ax.contourf(num_dates_2d,
                         lats_agg_2d,
                         sim_data.modif_c - sim_data.base_c,
                         extend="both",
                         levels=clevs,
                         cmap=diff_cmap)
        if row == 0:
            ax.set_title("Current ({}-{})".format(base_config_c.start_year,
                                                  base_config_c.end_year))
        all_axes.append(ax)

        # Future
        ax = fig.add_subplot(gs[row, 1])
        if row == 0:
            ax.set_title("Future ({}-{})".format(base_config_f.start_year,
                                                 base_config_f.end_year))

        cs = ax.contourf(num_dates_2d,
                         lats_agg_2d,
                         sim_data.modif_f - sim_data.base_f,
                         levels=cs.levels,
                         extend="both",
                         cmap=diff_cmap)
        all_axes.append(ax)

        # Colorbar for value plots
        cax = fig.add_subplot(gs[row, 2])
        plt.colorbar(cs, cax=cax)
        cax.set_title("{} ({})\n".format(var_label, unit_label))

        diff = (sim_data.modif_f - sim_data.base_f) - (sim_data.modif_c -
                                                       sim_data.base_c)
        delta = np.percentile(np.abs(diff), 99)
        vmin = -delta
        vmax = delta
        locator = MaxNLocator(nbins=10, symmetric=True)
        clevs = locator.tick_values(vmin=vmin, vmax=vmax)

        ax = fig.add_subplot(gs[row, 3])
        cs = ax.contourf(num_dates_2d,
                         lats_agg_2d,
                         diff,
                         cmap=diff_cmap,
                         levels=clevs,
                         extend="both")
        all_axes.append(ax)
        cb = plt.colorbar(cs, cax=fig.add_subplot(gs[row, 4]))

        if row == 0:
            ax.set_title("Future - Current")

        cb.ax.set_title("{}\n".format(unit_label))

        for i, the_ax in enumerate(all_axes):
            the_ax.xaxis.set_major_formatter(DateFormatter("%b"))
            the_ax.xaxis.set_major_locator(MonthLocator(interval=2))

            the_ax.grid()
            if i == 0:
                the_ax.set_ylabel("Latitude")

        row += 1

    fig.tight_layout()
    img_path = Path(img_folder).joinpath(
        "{}_long_avg_intf_impact_{}-{}_vs_{}-{}.png".format(
            "_".join(varnames), base_config_f.start_year,
            base_config_f.end_year, base_config_c.start_year,
            base_config_c.end_year))
    fig.savefig(str(img_path), bbox_inches="tight")
Пример #20
0
def _plot_row(vname="", level=0, config_dict=None, plot_cc_only_for=None, mark_significance=True):
    """
    if plot_cc_only_for is not None, should be equal to the label of the simulation to be plotted
    """

    lons, lats = config_dict.lons, config_dict.lats

    bmp = config_dict.basemap
    """
    :type bmp: mpl_toolkits.basemap.Basemap
    """


    xx, yy = bmp(lons, lats)
    lons[lons > 180] -= 360

    fig = config_dict.fig
    gs = config_dict.gs
    """:type : matplotlib.gridspec.GridSpec """
    nrows_subplots, ncols_subplots = gs.get_geometry()


    label_base = config_dict.label_base
    label_modif = config_dict.label_modif

    the_row = config_dict.the_row
    season_to_months = config_dict.season_to_months

    if "+" in vname or "-" in vname:
        op = "+" if "+" in vname else "-"
        vname1, vname2 = vname.split(op)

        vname1 = vname1.strip()
        vname2 = vname2.strip()

        current_base = {}
        future_base = {}

        current_modif = {}
        future_modif = {}

        # vname1
        current_base1 = compute_seasonal_means_for_each_year(config_dict["Current"][label_base], var_name=vname1,
                                                             level=level,
                                                             season_to_months=season_to_months)
        future_base1 = compute_seasonal_means_for_each_year(config_dict["Future"][label_base], var_name=vname1,
                                                            level=level,
                                                            season_to_months=season_to_months)

        current_modif1 = compute_seasonal_means_for_each_year(config_dict["Current"][label_modif], var_name=vname1,
                                                              level=level,
                                                              season_to_months=season_to_months)
        future_modif1 = compute_seasonal_means_for_each_year(config_dict["Future"][label_modif], var_name=vname1,
                                                             level=level,
                                                             season_to_months=season_to_months)


        # vname2
        current_base2 = compute_seasonal_means_for_each_year(config_dict["Current"][label_base], var_name=vname2,
                                                             level=level,
                                                             season_to_months=season_to_months)
        future_base2 = compute_seasonal_means_for_each_year(config_dict["Future"][label_base], var_name=vname2,
                                                            level=level,
                                                            season_to_months=season_to_months)

        current_modif2 = compute_seasonal_means_for_each_year(config_dict["Current"][label_modif], var_name=vname2,
                                                              level=level,
                                                              season_to_months=season_to_months)
        future_modif2 = compute_seasonal_means_for_each_year(config_dict["Future"][label_modif], var_name=vname2,
                                                             level=level,
                                                             season_to_months=season_to_months)

        for season in current_base1:
            current_base[season] = eval("current_base2[season]{}current_base1[season]".format(op))
            future_base[season] = eval("future_base2[season]{}future_base1[season]".format(op))
            current_modif[season] = eval("current_modif2[season]{}current_modif1[season]".format(op))
            future_modif[season] = eval("future_modif2[season]{}future_modif1[season]".format(op))


    else:
        current_base = compute_seasonal_means_for_each_year(config_dict["Current"][label_base], var_name=vname,
                                                            level=level,
                                                            season_to_months=season_to_months)
        future_base = compute_seasonal_means_for_each_year(config_dict["Future"][label_base], var_name=vname,
                                                           level=level,
                                                           season_to_months=season_to_months)

        current_modif = compute_seasonal_means_for_each_year(config_dict["Current"][label_modif], var_name=vname,
                                                             level=level,
                                                             season_to_months=season_to_months)
        future_modif = compute_seasonal_means_for_each_year(config_dict["Future"][label_modif], var_name=vname,
                                                            level=level,
                                                            season_to_months=season_to_months)




    # Calculate the differences in cc signal
    season_to_diff = OrderedDict()

    season_to_plot_diff = OrderedDict()

    diff_max = 0
    print(list(current_base.keys()))
    # Get the ranges for colorbar and calculate p-values
    print("------------------ impacts on projected changes to {} -----------------------".format(vname))
    season_to_pvalue = OrderedDict()
    for season in list(current_base.keys()):

        _, pvalue_current = ttest_ind(current_modif[season], current_base[season], axis=0, equal_var=False)
        _, pvalue_future = ttest_ind(future_modif[season], future_base[season], axis=0, equal_var=False)

        if plot_cc_only_for is None:
            season_to_pvalue[season] = np.minimum(pvalue_current, pvalue_future)

            season_to_diff[season] = (future_modif[season] - current_modif[season]) - \
                                     (future_base[season] - current_base[season])

        else:

            if plot_cc_only_for == label_base:
                _, season_to_pvalue[season] = ttest_ind(future_base[season], current_base[season], axis=0, equal_var=False)
                c_data = current_base[season]
                f_data = future_base[season]
            else:
                _, season_to_pvalue[season] = ttest_ind(future_modif[season], current_modif[season], axis=0, equal_var=False)
                c_data = current_modif[season]
                f_data = future_modif[season]

            season_to_diff[season] = f_data - c_data


        # Convert units if required
        if vname in config_dict.multipliers:
            season_to_diff[season] *= config_dict.multipliers[vname]

        field_to_plot = infovar.get_to_plot(vname, season_to_diff[season].mean(axis=0), lons=lons, lats=lats)
        season_to_plot_diff[season] = field_to_plot


        print("{}: {}".format(season, season_to_plot_diff[season].mean()))

        if hasattr(field_to_plot, "mask"):
            diff_max = max(np.percentile(np.abs(field_to_plot[~field_to_plot.mask]), 95), diff_max)
        else:
            diff_max = max(np.percentile(np.abs(field_to_plot), 95), diff_max)

    print("--------------------------------------------------------")

    img = None
    locator = MaxNLocator(nbins=10, symmetric=True)
    clevels = locator.tick_values(-diff_max, diff_max)

    bn = BoundaryNorm(clevels, len(clevels) - 1)
    cmap = cm.get_cmap("RdBu_r", len(clevels) - 1)
    for col, season in enumerate(current_base.keys()):
        ax = fig.add_subplot(gs[the_row, col])

        if not col:
            ax.set_ylabel(infovar.get_long_display_label_for_var(vname))

        if not the_row:
            ax.set_title(season)

        img = bmp.pcolormesh(xx, yy, season_to_plot_diff[season].copy(),
                             vmin=-diff_max, vmax=diff_max,
                             cmap=cmap, norm=bn, ax=ax)


        # logging
        good_vals = season_to_plot_diff[season]
        good_vals = good_vals[~good_vals.mask]
        print("------" * 10)
        print("{}: min={}; max={}; area-avg={};".format(season, good_vals.min(), good_vals.max(), good_vals.mean()))


        bmp.readshapefile(quebec_info.BASIN_BOUNDARIES_DERIVED_10km[:-4], "basin_edge", ax=ax)

        p = season_to_pvalue[season]
        if hasattr(season_to_plot_diff[season], "mask"):
            p = np.ma.masked_where(season_to_plot_diff[season].mask, p)


        if plot_cc_only_for is not None and mark_significance:
            cs = bmp.contourf(xx, yy, p, hatches=["..."], levels=[0.05, 1], colors='none')

            if (col == ncols_subplots - 2) and (the_row == nrows_subplots - 1):
                # create a legend for the contour set
                artists, labels = cs.legend_elements()
                labels = ["not significant"]
                ax.legend(artists, labels, handleheight=1, loc="upper right",
                          bbox_to_anchor=(1.0, -0.05), borderaxespad=0., frameon=False)


        bmp.drawcoastlines(ax=ax, linewidth=0.4)
        if vname in ["I5"] and season.lower() in ["summer"]:
            ax.set_visible(False)



    cb = plt.colorbar(img, cax=fig.add_subplot(gs[the_row, len(current_base)]), extend="both")

    if hasattr(config_dict, "name_to_units") and vname in config_dict.name_to_units:
        cb.ax.set_title(config_dict.name_to_units[vname])
    else:
        cb.ax.set_title(infovar.get_units(vname))
Пример #21
0
    def auto_set_ticks(self):
        """
        Use the matplotlib.ticker class to automatically set nice values for the major and minor ticks.
        Log axes generally come out nicely spaced without needing manual intervention. For particularly narrow latitude
        vs longitude plots the ticks can come out overlapped, so an exception is included to deal with this.
        """
        from cartopy.mpl.ticker import LongitudeFormatter, LatitudeFormatter

        y_variable = self.plot_args['y_variable'].lower()
        x_variable = self.plot_args['x_variable'].lower()

        ymin, ymax = self.matplotlib.ylim()

        # Matplotlib xlim doesn't work with cartopy plots
        xmin, xmax = self.xmin, self.xmax
        # xmin, xmax = self.matplotlib.xlim()

        max_x_bins = 9
        max_y_bins = 9

        xsteps = self.plot_args['xrange'].get('xstep', None)
        ysteps = self.plot_args['yrange'].get('ystep', None)

        lon_steps = [1, 3, 6, 9, 10]
        lat_steps = [1, 3, 6, 9, 10]
        variable_step = [1, 2, 4, 5, 10]

        if (xmax - xmin) < 5:
            lon_steps = variable_step
        if (ymax - ymin) < 5:
            lat_steps = variable_step

        # We need to make a special exception for particularly narrow and wide plots, which will be lat vs lon
        # preserving the aspect ratio. This gives more options for the spacing to try and find something that can use
        # the maximum number of bins.
        if x_variable.startswith('lon') and y_variable.startswith('lat'):
            max_y_bins = 7  # as plots are wider rather than taller
            if (ymax - ymin) > 2.2 * (xmax - xmin):
                max_x_bins = 4
                max_y_bins = 11
            elif (xmax - xmin) > 2.2 * (ymax - ymin):
                max_x_bins = 14
                max_y_bins = 4

        lat_or_lon = 'lat', 'lon'

        if xsteps is None and not self.plot_args['logx']:
            if self.plot_args['x_variable'].lower().startswith(lat_or_lon):
                lon_locator = MaxNLocator(nbins=max_x_bins, steps=lon_steps)
                if self.is_map():
                    self.cartopy_axis.set_xticks(lon_locator.tick_values(xmin, xmax), crs=self.transform)
                    self.cartopy_axis.xaxis.set_major_formatter(LongitudeFormatter())
                else:
                    self.matplotlib.axes().xaxis.set_major_locator(lon_locator)
            else:
                self.matplotlib.axes().xaxis.set_major_locator(MaxNLocator(nbins=max_x_bins, steps=variable_step))

            if not self.is_map():
                self.matplotlib.axes().xaxis.set_minor_locator(AutoMinorLocator())
                self.matplotlib.axes().xaxis.grid(False, which='minor')

        if ysteps is None and not self.plot_args['logy']:
            if y_variable.startswith(lat_or_lon):
                lat_locator = MaxNLocator(nbins=max_y_bins, steps=lat_steps)
                if self.is_map():
                    self.cartopy_axis.set_yticks(lat_locator.tick_values(ymin, ymax), crs=self.transform)
                    self.cartopy_axis.yaxis.set_major_formatter(LatitudeFormatter())
                else:
                    self.matplotlib.axes().yaxis.set_major_locator(lat_locator)
            else:
                self.matplotlib.axes().yaxis.set_major_locator(MaxNLocator(nbins=max_y_bins, steps=variable_step))

            if not self.is_map():
                self.matplotlib.axes().yaxis.set_minor_locator(AutoMinorLocator())
                self.matplotlib.axes().yaxis.grid(False, which='minor')
Пример #22
0
def plot_profiles():
    obs_base_dir = Path("/home/huziy/skynet3_rech1/nemo_obs_for_validation/data_from_Ram_Yerubandi/ADCP-profiles")
    obs_dir_list = [
        str(obs_base_dir.joinpath("105.317")),
        str(obs_base_dir.joinpath("155.289"))
    ]

    obs_var_col = AdcpProfileObs.vmag_col
    model_var_name = FLOW_SPEED

    model_folder = "/home/huziy/skynet3_rech1/offline_glk_output_daily_1979-2012"

    manager_nemo_u = NemoYearlyFilesManager(folder=model_folder, suffix="_U.nc")
    manager_nemo_v = NemoYearlyFilesManager(folder=model_folder, suffix="_V.nc")
    manager_nemo_w = NemoYearlyFilesManager(folder=model_folder, suffix="_W.nc")



    fig = plt.figure()
    gs = GridSpec(len(obs_dir_list), 5, width_ratios=[1, 1, 0.05, 1, 0.05])


    cmap = cm.get_cmap("jet", 10)
    diff_cmap = cm.get_cmap("RdBu_r", 10)

    for i, obs_dir in enumerate(obs_dir_list):

        adcp = AdcpProfileObs()

        dates, levels, obs_data = adcp.get_acdp_profiles(folder=obs_dir, data_column=obs_var_col)

        dates_m, levs_m, u_cs = manager_nemo_u.get_tz_crosssection_for_the_point(
            lon=adcp.longitude, lat=adcp.latitude,
            start_date=dates[0], end_date=dates[-1],
            var_name="vozocrtx", zlist=levels
        )

        dates_m, levs_m, v_cs = manager_nemo_v.get_tz_crosssection_for_the_point(
            lon=adcp.longitude, lat=adcp.latitude,
            start_date=dates[0], end_date=dates[-1],
            var_name="vomecrty", zlist=levels
        )

        dates_m, levs_m, w_cs = manager_nemo_w.get_tz_crosssection_for_the_point(
            lon=adcp.longitude, lat=adcp.latitude,
            start_date=dates[0], end_date=dates[-1],
            var_name="vovecrtz", zlist=levels
        )




        numdates = date2num(dates.tolist())
        print("Obs dates are: {} ... {}".format(dates[0], dates[-1]))
        print([num2date([n for n in numdates if n not in dates_m])])
        zz, tt = np.meshgrid(levels, numdates)

        umag_mod_cs = (u_cs ** 2 + v_cs ** 2 + w_cs ** 2) ** 0.5 * 100.0

        all_axes = []
        # Obs
        ax = fig.add_subplot(gs[i, 0])
        ax.set_title("Obs")
        cs = ax.contourf(tt, zz, obs_data, cmap=cmap)
        ax.set_ylabel("({:.1f}, {:.1f})".format(adcp.longitude, adcp.latitude))
        all_axes.append(ax)


        # Model
        ax = fig.add_subplot(gs[i, 1])
        ax.set_title("NEMO-offline")
        cs = ax.contourf(tt, zz, umag_mod_cs, levels=cs.levels, cmap=cmap)
        all_axes.append(ax)

        plt.colorbar(cs, cax=fig.add_subplot(gs[i, 2]))

        # Bias
        ax = fig.add_subplot(gs[i, 3])
        ax.set_title("Model - Obs.")
        delta = umag_mod_cs - obs_data

        vmax = np.abs(delta).max()
        vmin = -vmax
        locator = MaxNLocator(nbins=diff_cmap.N, symmetric=True)

        cs = ax.contourf(tt, zz, delta, levels=locator.tick_values(vmin, vmax), cmap=diff_cmap)
        plt.colorbar(cs, cax=fig.add_subplot(gs[i, 4]))
        all_axes.append(ax)


        for the_ax in all_axes:
            the_ax.xaxis.set_major_formatter(DateFormatter("%b"))
            the_ax.xaxis.set_major_locator(MonthLocator())
            the_ax.invert_yaxis()

    img_folder = Path("nemo/adcp")
    if not img_folder.is_dir():
        img_folder.mkdir(parents=True)

    img_file = img_folder.joinpath("adcp_profiles.pdf")
    fig.tight_layout()
    fig.savefig(str(img_file), bbox_inches="tight")
Пример #23
0
    def plot_comparisons_of_seasonal_sst_with_homa_obs(self,
                                                       start_year=None,
                                                       end_year=None,
                                                       season_to_months=None,
                                                       exp_label=""):

        model_data = self.get_seasonal_mean_lst(
            season_to_months=season_to_months,
            start_year=start_year,
            end_year=end_year)

        obs_sst_path = os.path.expanduser(
            "~/skynet3_rech1/nemo_obs_for_validation/GreatLakes_2003_5km-2/sst-glk.nc"
        )

        obs_data = self.read_and_interpolate_homa_data(
            path=obs_sst_path,
            start_year=start_year,
            end_year=end_year,
            season_to_months=season_to_months)

        plot_utils.apply_plot_params(font_size=10,
                                     width_pt=None,
                                     width_cm=20,
                                     height_cm=10)
        # calculate climatologic differences
        diff = {}
        for season in list(season_to_months.keys()):
            diff[season] = np.mean([
                model_data[y][season] - obs_data[y][season]
                for y in range(start_year, end_year + 1)
            ],
                                   axis=0)
            diff[season] = np.ma.masked_where(~self.lake_mask, diff[season])
            the_field = diff[season]
            print("diff stats({}): min={}; max={}; avg={}".format(
                season, the_field.min(), the_field.max(), the_field.mean()))

        # plot seasonal biases
        xx, yy = self.basemap(self.lons.copy(), self.lats.copy())

        # calculate difference ranges
        diff_max = 0
        for season, the_diff in diff.items():
            diff_max = max(np.percentile(np.abs(the_diff[~the_diff.mask]), 90),
                           diff_max)
        diff_max = 5

        locator = MaxNLocator(nbins=12, symmetric=True)
        bounds = locator.tick_values(-diff_max, diff_max)
        bn = BoundaryNorm(bounds, len(bounds) - 1)
        cmap = cm.get_cmap("RdBu_r", len(bounds) - 1)

        im = None
        fig = plt.figure()
        ncols = 2
        # fig.suptitle(r"LST $\left({\rm ^\circ C}\right)$", font_properties=FontProperties(weight="bold"))
        gs = GridSpec(len(season_to_months) // ncols,
                      ncols + 1,
                      width_ratios=[
                          1.0,
                      ] * ncols + [
                          0.05,
                      ])
        for i, season in enumerate(season_to_months.keys()):
            ax = fig.add_subplot(gs[i // ncols, i % ncols])
            im = self.basemap.pcolormesh(xx,
                                         yy,
                                         diff[season][:],
                                         ax=ax,
                                         cmap=cmap,
                                         norm=bn)
            ax.set_title(season)
            self.basemap.drawcoastlines(ax=ax, linewidth=0.5)
            if not i:
                ax.set_ylabel("NEMO - Obs")

        cb = plt.colorbar(im,
                          ticks=locator,
                          cax=fig.add_subplot(gs[:, -1]),
                          extend="both")

        nemo_img_dir = "nemo"
        if not os.path.isdir(nemo_img_dir):
            os.mkdir(nemo_img_dir)

        plt.tight_layout()
        fig.savefig(
            os.path.join(nemo_img_dir,
                         "sst_homa_validation_{}.pdf".format(exp_label)))
        plt.show()
Пример #24
0
def _plot_var(vname="", level=0, config_dict=None, data_dict=None):
    modif_label = config_dict.label_modif
    base_label = config_dict.label_base

    base_config_c, modif_config_c = [
        config_dict["Current"][the_label]
        for the_label in [base_label, modif_label]
    ]
    base_config_f, modif_config_f = [
        config_dict["Future"][the_label]
        for the_label in [base_label, modif_label]
    ]

    bmp = config_dict.basemap
    lons = config_dict.lons
    lons[lons > 180] -= 360

    lats = config_dict.lats
    xx, yy = bmp(lons, lats)

    i_to_label = {
        0: base_label,
        1: modif_label,
        2: "{}\n--\n{}".format(modif_label, base_label)
    }

    j_to_title = {
        0:
        "Current ({}-{})".format(base_config_c.start_year,
                                 base_config_c.end_year),
        1:
        "Future ({}-{})".format(base_config_f.start_year,
                                base_config_f.end_year),
        2:
        "Future - Current"
    }

    # Create a folder for images
    img_folder = os.path.join("cc_paper",
                              "{}_vs_{}".format(modif_label, base_label))
    if not os.path.isdir(img_folder):
        os.makedirs(img_folder)

    nrows = ncols = 3
    plot_utils.apply_plot_params(font_size=10,
                                 width_pt=None,
                                 width_cm=27,
                                 height_cm=20)

    field_cmap = cm.get_cmap("jet", 20)
    diff_cmap = cm.get_cmap("RdBu_r", 20)

    for season in list(data_dict[base_config_c].keys()):

        fig = plt.figure()
        fig.suptitle("{} ({})".format(
            infovar.get_long_display_label_for_var(vname), season),
                     font_properties=FontProperties(weight="bold"))

        gs = GridSpec(nrows=nrows, ncols=ncols)

        mean_c_base = data_dict[base_config_c][season].mean(axis=0)
        mean_f_base = data_dict[base_config_f][season].mean(axis=0)

        mean_c_modif = data_dict[modif_config_c][season].mean(axis=0)
        mean_f_modif = data_dict[modif_config_f][season].mean(axis=0)

        print("------------ {}, {} --------------".format(vname, season))
        print("data_dict[base_config_c][season].shape = {}".format(
            data_dict[base_config_c][season].shape))
        _, p_signif_base_cc = ttest_ind(data_dict[base_config_c][season],
                                        data_dict[base_config_f][season],
                                        axis=0,
                                        equal_var=False)
        _, p_signif_current = ttest_ind(data_dict[base_config_c][season],
                                        data_dict[modif_config_c][season],
                                        axis=0,
                                        equal_var=False)

        print("Base p-value ranges: {} to {}".format(p_signif_base_cc.min(),
                                                     p_signif_base_cc.max()))
        _, p_signif_modif_cc = ttest_ind(data_dict[modif_config_c][season],
                                         data_dict[modif_config_f][season],
                                         axis=0,
                                         equal_var=False)
        _, p_signif_future = ttest_ind(data_dict[base_config_f][season],
                                       data_dict[modif_config_f][season],
                                       axis=0,
                                       equal_var=False)

        ij_to_pvalue = {
            (0, 2): p_signif_base_cc,
            (1, 2): p_signif_modif_cc,
            (2, 0): p_signif_current,
            (2, 1): p_signif_future,
            # (2, 2): np.minimum(p_signif_current, p_signif_future)
        }

        ij_to_data = {
            (0, 0): mean_c_base,
            (1, 0): mean_c_modif,
            (0, 1): mean_f_base,
            (1, 1): mean_f_modif
        }

        # Apply multipliers for unit conversion
        for k in list(ij_to_data.keys()):
            ij_to_data[k] *= multiplier_dict.get(vname, 1)

            # mask oceans
            mask_inland = vname in ["STFL", "STFA"] or vname.startswith("I")
            ij_to_data[k] = maskoceans(lonsin=lons,
                                       latsin=lats,
                                       datain=ij_to_data[k],
                                       inlands=mask_inland)

        # get all means to calculate the ranges of mean fields
        all_means = []
        for vals in ij_to_data.values():
            all_means.extend(vals[~vals.mask])

        if vname == "PR":
            # mm/day
            minval = 0
            maxval = 5
            extend_val = "max"
        else:
            minval = np.percentile(all_means, 1)
            maxval = np.percentile(all_means, 95)
            extend_val = "neither"

        d1 = ij_to_data[0, 1] - ij_to_data[0, 0]
        d2 = ij_to_data[1, 1] - ij_to_data[1, 0]
        all_cc_diffs = np.ma.asarray([d1, d2])
        mindiff_cc = np.percentile(all_cc_diffs[~all_cc_diffs.mask], 1)
        maxdiff_cc = np.percentile(all_cc_diffs[~all_cc_diffs.mask], 99)

        maxdiff_cc = max(np.ma.abs(maxdiff_cc), np.ma.abs(mindiff_cc))

        # Limit the temperature change scale
        if vname == "TT":
            maxdiff_cc = min(maxdiff_cc, 10)

        mindiff_cc = -maxdiff_cc

        # Add all differences due to changed processes in a list
        all_proc_diffs = []

        d1 = ij_to_data[1, 0] - ij_to_data[0, 0]
        d2 = ij_to_data[1, 1] - ij_to_data[0, 1]
        all_proc_diffs.extend([d1, d2])
        all_proc_diffs.append(d2 - d1)
        all_proc_diffs = np.ma.asarray(all_proc_diffs)

        mindiff_proc = np.percentile(all_proc_diffs[~all_proc_diffs.mask], 1)
        maxdiff_proc = np.percentile(all_proc_diffs[~all_proc_diffs.mask], 95)

        maxdiff_proc = max(np.abs(maxdiff_proc), np.abs(mindiff_proc))
        mindiff_proc = -maxdiff_proc

        plot_data = []
        for row in range(nrows - 1):
            row_data = []
            for col in range(ncols - 1):
                row_data.append(ij_to_data[row, col])
            plot_data.append(row_data + [
                0,
            ])

        # calculate differences between different model configurations
        row = 2
        plot_data.append([0, 0, 0])
        for col in range(2):
            plot_data[row][col] = plot_data[1][col] - plot_data[0][col]

        # calculate CC
        col = 2
        for row in range(3):
            plot_data[row][col] = plot_data[row][1] - plot_data[row][0]

        # Do the plotting
        for i in range(nrows):
            for j in range(ncols):

                ax = fig.add_subplot(gs[i, j])
                plotting_values = (i < 2) and (j < 2)

                if plotting_values:
                    the_min, the_max = minval, maxval
                elif i == nrows - 1:
                    the_min, the_max = mindiff_proc, maxdiff_proc
                else:
                    the_min, the_max = mindiff_cc, maxdiff_cc

                the_cmap = field_cmap if plotting_values else diff_cmap

                locator = MaxNLocator(nbins=the_cmap.N // 2,
                                      symmetric=not plotting_values)
                bounds = locator.tick_values(the_min, the_max)

                if vname in ["STFA", "STFL"] and plotting_values:
                    the_min = 1.0e-5
                    the_max = 1.0e4

                    locator = LogLocator(numticks=11)
                    bounds = locator.tick_values(the_min, the_max)

                    print(bounds)

                    norm = LogNorm(vmin=bounds[0], vmax=bounds[-1])

                    plot_data[i][j] = np.ma.masked_where(
                        plot_data[i][j] <= the_min, plot_data[i][j])
                    print("the_max = {}".format(the_max))

                    the_cmap = cm.get_cmap("jet", len(bounds) - 1)

                else:
                    norm = BoundaryNorm(bounds, the_cmap.N)

                extend = "both" if not plotting_values else extend_val

                if plotting_values:
                    print(i, j, the_min, the_max)

                im = bmp.pcolormesh(xx,
                                    yy,
                                    plot_data[i][j][:, :],
                                    cmap=the_cmap,
                                    norm=norm)

                if (i, j) in ij_to_pvalue:
                    p = ij_to_pvalue[i, j]
                    # not_signif = (p > 0.2)
                    # not_signif = np.ma.masked_where(~not_signif, not_signif) * 0.75
                    # not_signif = np.ma.masked_where(plot_data[i][j].mask, not_signif)
                    # bmp.pcolormesh(xx, yy, not_signif, vmin=0, vmax=1, cmap=cm.get_cmap("gray", 20))
                    p = np.ma.masked_where(plot_data[i][j].mask, p)
                    cs = bmp.contourf(xx,
                                      yy,
                                      p,
                                      hatches=["..."],
                                      levels=[0.1, 1],
                                      colors='none')
                    # create a legend for the contour set
                    # artists, labels = cs.legend_elements()
                    # ax.legend(artists, labels, handleheight=2)

                bmp.colorbar(im, ticks=bounds, extend=extend)
                bmp.drawcoastlines(ax=ax, linewidth=0.5)

                ax.set_title(j_to_title.get(j, "") if i == 0 else "")
                ax.set_ylabel(i_to_label.get(i, "") if j == 0 else "")

        # Save the image to the file
        img_name = "{}_{}_{}-{}_{}-{}.png".format(vname + str(level), season,
                                                  base_config_f.start_year,
                                                  base_config_f.end_year,
                                                  base_config_c.start_year,
                                                  base_config_c.end_year)

        img_path = os.path.join(img_folder, img_name)
        fig.savefig(img_path, bbox_inches="tight")
        plt.close(fig)
Пример #25
0
def _get_ticks_by_num(vmin, vmax, numticks):
    
    from matplotlib.ticker import MaxNLocator
    locator = MaxNLocator(nbins=numticks, steps=[1,1.5,2,2.5,3,4,5,6,7.5,8,10], prune=None)
    return locator.tick_values(vmin, vmax)
def plot_profiles():
    obs_base_dir = Path("/home/huziy/skynet3_rech1/nemo_obs_for_validation/data_from_Ram_Yerubandi/ADCP-profiles")
    obs_dir_list = [
        str(obs_base_dir.joinpath("105.317")),
        str(obs_base_dir.joinpath("155.289"))
    ]

    obs_var_col = AdcpProfileObs.vmag_col
    model_var_name = FLOW_SPEED

    # model_folder = "/home/huziy/skynet3_rech1/offline_glk_output_daily_1979-2012"
    model_folder = "/RESCUE/skynet3_rech1/huziy/NEMO_OFFICIAL/dev_v3_4_STABLE_2012/NEMOGCM/CONFIG/GLK_LIM3/EXP_GLK_LIM3_1980/zdf_gls_dt_and_sbc_5min"

    manager_nemo_u = NemoYearlyFilesManager(folder=model_folder, suffix="_U.nc")
    manager_nemo_v = NemoYearlyFilesManager(folder=model_folder, suffix="_V.nc")
    manager_nemo_w = NemoYearlyFilesManager(folder=model_folder, suffix="_W.nc")



    fig = plt.figure()
    gs = GridSpec(len(obs_dir_list), 5, width_ratios=[1, 1, 0.05, 1, 0.05])


    cmap = cm.get_cmap("jet", 10)
    diff_cmap = cm.get_cmap("RdBu_r", 10)

    for i, obs_dir in enumerate(obs_dir_list):

        adcp = AdcpProfileObs()

        dates, levels, obs_data = adcp.get_acdp_profiles(folder=obs_dir, data_column=obs_var_col)

        dates_m, levs_m, u_cs = manager_nemo_u.get_tz_crosssection_for_the_point(
            lon=adcp.longitude, lat=adcp.latitude,
            start_date=dates[0], end_date=dates[-1],
            var_name="vozocrtx", zlist=levels
        )

        dates_m, levs_m, v_cs = manager_nemo_v.get_tz_crosssection_for_the_point(
            lon=adcp.longitude, lat=adcp.latitude,
            start_date=dates[0], end_date=dates[-1],
            var_name="vomecrty", zlist=levels
        )

        dates_m, levs_m, w_cs = manager_nemo_w.get_tz_crosssection_for_the_point(
            lon=adcp.longitude, lat=adcp.latitude,
            start_date=dates[0], end_date=dates[-1],
            var_name="vovecrtz", zlist=levels
        )




        numdates = date2num(dates.tolist())
        print("Obs dates are: {} ... {}".format(dates[0], dates[-1]))
        print([num2date([n for n in numdates if n not in dates_m])])
        zz, tt = np.meshgrid(levels, numdates)

        umag_mod_cs = (u_cs ** 2 + v_cs ** 2 + w_cs ** 2) ** 0.5 * 100.0

        all_axes = []
        # Obs
        ax = fig.add_subplot(gs[i, 0])
        ax.set_title("Obs")
        cs = ax.contourf(tt, zz, obs_data, cmap=cmap)
        ax.set_ylabel("({:.1f}, {:.1f})".format(adcp.longitude, adcp.latitude))
        all_axes.append(ax)


        # Model
        ax = fig.add_subplot(gs[i, 1])
        ax.set_title("NEMO-offline")
        cs = ax.contourf(tt, zz, umag_mod_cs, levels=cs.levels, cmap=cmap)
        all_axes.append(ax)

        plt.colorbar(cs, cax=fig.add_subplot(gs[i, 2]))

        # Bias
        ax = fig.add_subplot(gs[i, 3])
        ax.set_title("Model - Obs.")
        delta = umag_mod_cs - obs_data

        vmax = np.abs(delta).max()
        vmin = -vmax
        locator = MaxNLocator(nbins=diff_cmap.N, symmetric=True)

        cs = ax.contourf(tt, zz, delta, levels=locator.tick_values(vmin, vmax), cmap=diff_cmap)
        plt.colorbar(cs, cax=fig.add_subplot(gs[i, 4]))
        all_axes.append(ax)


        for the_ax in all_axes:
            the_ax.xaxis.set_major_formatter(DateFormatter("%b"))
            the_ax.xaxis.set_major_locator(MonthLocator())
            the_ax.invert_yaxis()

    img_folder = Path("nemo/adcp/zdf_gls_dt_and_sbc_5min")
    if not img_folder.is_dir():
        img_folder.mkdir(parents=True)

    img_file = img_folder.joinpath("adcp_profiles.pdf")
    fig.tight_layout()

    print("Saving plots to {}".format(img_file))
    fig.savefig(str(img_file), bbox_inches="tight")
Пример #27
0
def validate_seas_mean_lswt_from_hostetler_and_nemo_with_homa(
        hl_data_path="/home/huziy/skynet3_rech1/CRCM_GL_simulation/all_files",
        start_year=2003, end_year=2006):
    crcm5_model_manager = Crcm5ModelDataManager(samples_folder_path=hl_data_path, all_files_in_samples_folder=True)

    varname = "L1"
    season = "Fall"

    season_to_months = {season: range(9, 11)}
    season_months = list(season_to_months[season])

    print(season_months, season_to_months)

    hl_lake_temp_clim = crcm5_model_manager.get_mean_field(start_year=start_year, end_year=end_year, var_name=varname,
                                                           level=1.1, months=season_months)

    hl_lake_temp_clim = hl_lake_temp_clim[13:-13, 13:-13]

    print("hl_lake_temp_clim.shape = ", hl_lake_temp_clim.shape)




    lon_hl, lat_hl = crcm5_model_manager.lons2D, crcm5_model_manager.lats2D



    print("lon_hl.shape = ", lon_hl.shape)

    print(lon_hl.min(), lon_hl.max())
    print(lat_hl.min(), lat_hl.max())

    # Get Nemo manager here only for coordinates and mask
    nemo_manager = NemoYearlyFilesManager(folder="/home/huziy/skynet3_rech1/offline_glk_output_daily_1979-2012",
                                          suffix="icemod.nc")

    lon2d, lat2d, bmp = nemo_manager.get_coords_and_basemap()

    # Interpolate hostetler's lake fraction to the model's grid
    hl_lake_temp_clim -= 273.15
    xs, ys, zs = lat_lon.lon_lat_to_cartesian(lon_hl.flatten(), lat_hl.flatten())
    print(xs.shape)
    ktree = cKDTree(data=list(zip(xs, ys, zs)))

    xt, yt, zt = lat_lon.lon_lat_to_cartesian(lon2d.flatten(), lat2d.flatten())
    dists, inds = ktree.query(np.asarray(list(zip(xt, yt, zt))))
    print(inds[:20])
    print(type(inds))
    print(inds.min(), inds.max())
    hl_lake_temp_clim = hl_lake_temp_clim.flatten()[inds].reshape(lon2d.shape)





    # get nemo and observed sst
    obs_sst, nemo_sst, _, _, _ = nemo_manager.get_nemo_and_homa_seasonal_mean_sst(start_year=start_year,
                                                                                  end_year=end_year,
                                                                                  season_to_months=season_to_months)

    obs_sst_clim = np.ma.mean([obs_sst[y][season] for y in range(start_year, end_year + 1)], axis=0)
    nemo_sst_clim = np.ma.mean([nemo_sst[y][season] for y in range(start_year, end_year + 1)], axis=0)


    obs_sst_clim = np.ma.masked_where(~nemo_manager.lake_mask, obs_sst_clim)
    nemo_sst_clim = np.ma.masked_where(~nemo_manager.lake_mask, nemo_sst_clim)
    hl_lake_temp_clim = np.ma.masked_where(~nemo_manager.lake_mask, hl_lake_temp_clim)

    # plt.figure()
    xx, yy = bmp(lon2d.copy(), lat2d.copy())
    # im = bmp.pcolormesh(xx, yy, model_yearmax_ice_conc)
    # bmp.colorbar(im)

    vmin = min(obs_sst_clim.min(), nemo_sst_clim.min(), hl_lake_temp_clim.min())
    vmax = max(obs_sst_clim.max(), nemo_sst_clim.max(), hl_lake_temp_clim.max())

    print("vmin={}; vmax={}".format(vmin, vmax))

    # plt.figure()
    # b = Basemap()
    # xx, yy = b(lons_obs, lats_obs)
    # im = b.pcolormesh(xx, yy, obs_yearmax_ice_conc)
    # b.colorbar(im)
    # b.drawcoastlines()

    # Plot as usual: model, obs, model - obs
    img_folder = Path("nemo/hostetler")
    if not img_folder.is_dir():
        img_folder.mkdir()
    img_file = img_folder.joinpath("validate_{}_lswt_hostetler_nemo_vs_homa_{}-{}.png".format(
        season, start_year, end_year))

    fig = plt.figure()
    gs = GridSpec(1, 4, width_ratios=[1, 1, 1, 0.05])
    all_axes = []

    cmap = cm.get_cmap("jet", 10)
    locator = MaxNLocator(nbins=10)
    ticks = locator.tick_values(vmin=vmin, vmax=vmax)
    norm = BoundaryNorm(boundaries=ticks, ncolors=len(ticks) - 1)

    # Model, Hostetler
    ax = fig.add_subplot(gs[0, 0])
    ax.set_title("Hostetler+CRCM5")
    bmp.pcolormesh(xx, yy, hl_lake_temp_clim, cmap=cmap, vmin=vmin, vmax=vmax, norm=norm)
    all_axes.append(ax)

    #
    ax = fig.add_subplot(gs[0, 1])
    ax.set_title("NEMO-offline")
    im = bmp.pcolormesh(xx, yy, nemo_sst_clim, cmap=cmap, vmin=vmin, vmax=vmax, norm=norm)
    all_axes.append(ax)


    # Obs: Homa
    ax = fig.add_subplot(gs[0, 2])
    ax.set_title("MODIS")
    im = bmp.pcolormesh(xx, yy, obs_sst_clim, cmap=cmap, vmin=vmin, vmax=vmax, norm=norm)
    all_axes.append(ax)

    plt.colorbar(im, cax=fig.add_subplot(gs[0, -1]), ticks=ticks)

    for the_ax in all_axes:
        bmp.drawcoastlines(ax=the_ax)

    fig.savefig(str(img_file), bbox_inches="tight")
    plt.close(fig)
Пример #28
0
def validate_seas_mean_lswt_from_hostetler_and_nemo_with_homa(
        hl_data_path="/home/huziy/skynet3_rech1/CRCM_GL_simulation/all_files",
        start_year=2003, end_year=2009):
    crcm5_model_manager = Crcm5ModelDataManager(samples_folder_path=hl_data_path, all_files_in_samples_folder=True)

    varname = "sohefldo"
    season = "Summer"

    season_to_months = {season: range(6, 9)}
    season_months = list(season_to_months[season])




    # Get Nemo manager here only for coordinates and mask
    nemo_offline_manager = NemoYearlyFilesManager(folder="/home/huziy/skynet3_rech1/offline_glk_output_daily_1979-2012",
                                                  suffix="grid_T.nc")

    nemo_crcm5_manager = NemoYearlyFilesManager(
        folder="/home/huziy/skynet3_rech1/one_way_coupled_nemo_outputs_1979_1985",
        suffix="grid_T.nc")

    lon2d, lat2d, bmp = nemo_offline_manager.get_coords_and_basemap()

    # Interpolate


    # get nemo sst
    nemo_offline_sst = nemo_offline_manager.get_seasonal_clim_field(start_year=start_year,
                                                                    end_year=end_year,
                                                                    season_to_months=season_to_months,
                                                                    varname=varname)

    nemo_crcm5_sst = nemo_crcm5_manager.get_seasonal_clim_field(start_year=start_year,
                                                                end_year=end_year,
                                                                season_to_months=season_to_months,
                                                                varname=varname)

    nemo_offline_sst = np.ma.masked_where(~nemo_offline_manager.lake_mask, nemo_offline_sst[season])
    nemo_crcm5_sst = np.ma.masked_where(~nemo_offline_manager.lake_mask, nemo_crcm5_sst[season])

    # plt.figure()
    xx, yy = bmp(lon2d.copy(), lat2d.copy())
    # im = bmp.pcolormesh(xx, yy, model_yearmax_ice_conc)
    # bmp.colorbar(im)

    vmin = min(nemo_offline_sst.min(), nemo_crcm5_sst.min())
    vmax = max(nemo_offline_sst.max(), nemo_crcm5_sst.max())

    # plt.figure()
    # b = Basemap()
    # xx, yy = b(lons_obs, lats_obs)
    # im = b.pcolormesh(xx, yy, obs_yearmax_ice_conc)
    # b.colorbar(im)
    # b.drawcoastlines()

    # Plot as usual: model, obs, model - obs
    img_folder = Path("nemo")
    if not img_folder.is_dir():
        img_folder.mkdir()
    img_file = img_folder.joinpath("{}_{}_nemo-offline_vs_nemo-crcm5_{}-{}.png".format(season.lower(),
                                                                                       varname, start_year, end_year))

    fig = plt.figure()
    gs = GridSpec(1, 3, width_ratios=[1, 1, 0.05])
    all_axes = []

    cmap = cm.get_cmap("jet", 10)
    locator = MaxNLocator(nbins=10)
    ticks = locator.tick_values(vmin=vmin, vmax=vmax)
    norm = BoundaryNorm(boundaries=ticks, ncolors=len(ticks) - 1)

    # Model, Hostetler
    ax = fig.add_subplot(gs[0, 0])
    ax.set_title("NEMO+CRCM5")
    bmp.pcolormesh(xx, yy, nemo_crcm5_sst, cmap=cmap, vmin=vmin, vmax=vmax, norm=norm)
    all_axes.append(ax)

    #
    ax = fig.add_subplot(gs[0, 1])
    ax.set_title("NEMO-offline")
    im = bmp.pcolormesh(xx, yy, nemo_offline_sst, cmap=cmap, vmin=vmin, vmax=vmax, norm=norm)
    all_axes.append(ax)


    # Obs: Homa
    # ax = fig.add_subplot(gs[0, 2])
    # ax.set_title("MODIS")
    # im = bmp.pcolormesh(xx, yy, obs_sst_clim, cmap=cmap, vmin=vmin, vmax=vmax, norm=norm)
    # all_axes.append(ax)

    plt.colorbar(im, cax=fig.add_subplot(gs[0, -1]), ticks=ticks)

    for the_ax in all_axes:
        bmp.drawcoastlines(ax=the_ax)

    fig.savefig(str(img_file), bbox_inches="tight")
    plt.close(fig)
Пример #29
0
class AxisLocator(object):
    """Determine the location of ticks in a view.

    Constructor
    -----------

    nbinsx : int
        Number of ticks on the x axis.
    nbinsy : int
        Number of ticks on the y axis.
    data_bounds : 4-tuple
        Initial coordinates of the viewport, as (xmin, ymin, xmax, ymax), in data coordinates.
        These are the data coordinates of the lower left and upper right points of the window.

    """

    _default_nbinsx = 24
    _default_nbinsy = 16
    # ticks are extended beyond the viewport for smooth transition
    # when panzooming: -2, -1, 0, +1, +2
    _bins_margin = 5
    _default_steps = (1, 2, 2.5, 5, 10)

    def __init__(self, nbinsx=None, nbinsy=None, data_bounds=None):
        """data_bounds is the initial bounds of the view in data coordinates."""
        self.data_bounds = data_bounds
        self._tr = Range(from_bounds=NDC, to_bounds=self.data_bounds)
        self._tri = self._tr.inverse()
        self.set_nbins(nbinsx, nbinsy)

    def set_nbins(self, nbinsx=None, nbinsy=None):
        """Change the number of bins on the x and y axes."""
        nbinsx = self._bins_margin * nbinsx if _is_integer(nbinsx) else self._default_nbinsx
        nbinsy = self._bins_margin * nbinsy if _is_integer(nbinsy) else self._default_nbinsy
        self.locx = MaxNLocator(nbins=nbinsx, steps=self._default_steps)
        self.locy = MaxNLocator(nbins=nbinsy, steps=self._default_steps)

    def _transform_ticks(self, xticks, yticks):
        """Transform ticks from data coordinates to view coordinates."""
        nx, ny = len(xticks), len(yticks)
        arr = np.zeros((nx + ny, 2))
        arr[:nx, 0] = xticks
        arr[nx:, 1] = yticks
        out = self._tri.apply(arr)
        return out[:nx, 0], out[nx:, 1]

    def set_view_bounds(self, view_bounds=None):
        """Set the view bounds in normalized device coordinates. Used when panning and zooming.

        This method updates the following attributes:

        * xticks : the position of the ticks on the x axis
        * yticks : the position of the ticks on the y axis
        * xtext : the text of the ticks on the x axis
        * ytext : the text of the ticks on the y axis

        """
        view_bounds = view_bounds or NDC
        x0, y0, x1, y1 = view_bounds
        dx = 2 * (x1 - x0)
        dy = 2 * (y1 - y0)

        # Get the bounds in data coordinates.
        ((dx0, dy0), (dx1, dy1)) = self._tr.apply([
            [x0 - dx, y0 - dy],
            [x1 + dx, y1 + dy]])

        # Compute the ticks in data coordinates.
        self.xticks = self.locx.tick_values(dx0, dx1)
        self.yticks = self.locy.tick_values(dy0, dy1)

        # Get the ticks in view coordinates.
        self.xticks_view, self.yticks_view = self._transform_ticks(self.xticks, self.yticks)

        # Get the text in data coordinates.
        fmt = '%.9g'
        self.xtext = [fmt % v for v in self.xticks]
        self.ytext = [fmt % v for v in self.yticks]
Пример #30
0
def main():
    start_year_c = 1980
    end_year_c = 2010

    img_folder = "cc_paper"

    current_path = "/RESCUE/skynet3_rech1/huziy/hdf_store/cc-canesm2-driven/quebec_0.1_crcm5-hcd-rl-intfl-cc-canesm2-1980-2010.hdf5"
    base_label = "CRCM5-LI"

    # Need to read land fraction
    geo_file_path = "/RESCUE/skynet3_rech1/huziy/hdf_store/pm1979010100_00000000p"

    r_obj = RPN(geo_file_path)
    mg_field = r_obj.get_first_record_for_name("MG")

    lons, lats = r_obj.get_longitudes_and_latitudes_for_the_last_read_rec()
    r_obj.close()

    future_shift_years = 90

    params = dict(
        data_path=current_path,
        start_year=start_year_c, end_year=end_year_c,
        label=base_label
    )

    base_config_c = RunConfig(**params)
    base_config_f = base_config_c.get_shifted_config(future_shift_years)

    varname = "INTF"
    level = 0
    daily_dates, intf_c = analysis.get_daily_climatology(path_to_hdf_file=base_config_c.data_path,
                                                         var_name=varname, level=level,
                                                         start_year=base_config_c.start_year,
                                                         end_year=base_config_c.end_year)

    _, intf_f = analysis.get_daily_climatology(path_to_hdf_file=base_config_f.data_path,
                                               var_name=varname, level=level,
                                               start_year=base_config_f.start_year,
                                               end_year=base_config_f.end_year)


    mg_fields = np.asarray([mg_field for d in daily_dates])

    mg_crit = 0.0001
    the_mask = mg_fields <= mg_crit
    # Convert to mm/day as well
    intf_c = _avg_along_lon(intf_c, the_mask) * 24 * 3600
    intf_f = _avg_along_lon(intf_f, the_mask) * 24 * 3600



    lats_agg = lats.mean(axis=0)
    num_dates = date2num(daily_dates)

    lats_agg_2d, num_dates_2d = np.meshgrid(lats_agg, num_dates)


    # Do the plotting
    fig = plt.figure()

    gs = GridSpec(2, 3, width_ratios=[1, 1, 0.05])
    norm = SymLogNorm(5e-5)

    all_axes = []
    # Current
    ax = fig.add_subplot(gs[0, 0])
    cs = ax.contourf(num_dates_2d, lats_agg_2d, intf_c[:], 60, norm=norm)
    ax.set_title("Current ({}-{})".format(
        base_config_c.start_year, base_config_c.end_year))
    all_axes.append(ax)

    # Future
    ax = fig.add_subplot(gs[0, 1])
    ax.set_title("Future ({}-{})".format(
        base_config_f.start_year, base_config_f.end_year))
    cs = ax.contourf(num_dates_2d, lats_agg_2d, intf_f[:], levels=cs.levels, norm=norm)
    all_axes.append(ax)





    # Colorbar for value plots
    cax = fig.add_subplot(gs[0, 2])

    sfmt = ScalarFormatter(useMathText=True)
    sfmt.set_powerlimits((-1, 2))

    plt.colorbar(cs, cax=cax, format=sfmt)
    cax.set_xlabel("mm/day")
    cax.yaxis.get_offset_text().set_position((-2, 10))



    # CC
    diff_cmap = cm.get_cmap("RdBu_r", 20)
    diff = (intf_f - intf_c) / (0.5 * (intf_c + intf_f)) * 100
    diff[(intf_f == 0) & (intf_c == 0)] = 0
    print(np.min(diff), np.max(diff))
    print(np.any(diff.mask))
    print(np.any(intf_c.mask))
    print(np.any(intf_f.mask))
    delta = 200
    vmin = -delta
    vmax = delta
    locator = MaxNLocator(nbins=20, symmetric=True)
    clevs = locator.tick_values(vmin=vmin, vmax=vmax)

    ax = fig.add_subplot(gs[1, 1])

    cs = ax.contourf(num_dates_2d, lats_agg_2d, diff, cmap=diff_cmap,
                     levels=clevs, extend="both")
    ax.set_title("Future - Current")
    # ax.set_aspect("auto")
    all_axes.append(ax)
    cb = plt.colorbar(cs, cax=fig.add_subplot(gs[1, -1]))
    cb.ax.set_xlabel(r"%")


    for i, the_ax in enumerate(all_axes):
        the_ax.xaxis.set_minor_formatter(FuncFormatter(lambda d, pos: num2date(d).strftime("%b")[0]))
        the_ax.xaxis.set_major_formatter(FuncFormatter(lambda d, pos: ""))
        the_ax.xaxis.set_minor_locator(MonthLocator(bymonthday=15))
        the_ax.xaxis.set_major_locator(MonthLocator())
        the_ax.grid()
        if i != 1:
            the_ax.set_ylabel(r"Latitude ${\rm \left(^\circ N \right)}$")



    # identify approximately the melting period and lower latitudes
    march1 = date2num(datetime(daily_dates[0].year, 3, 1))
    june1 = date2num(datetime(daily_dates[0].year, 6, 1))

    sel_mask = (num_dates_2d >= march1) & (num_dates_2d < june1) & (lats_agg_2d <= 50)
    print("Mean interflow decrease in the southern regions: {}%".format(diff[sel_mask].mean()))


    # identify the regions of max interflow rates in current and future climates
    lat_min = 55
    lat_max = 57.5

    may1 = date2num(datetime(daily_dates[0].year, 5, 1))
    july1 = date2num(datetime(daily_dates[0].year, 7, 1))

    mean_max_current = intf_c[(lats_agg_2d >= lat_min) & (lats_agg_2d <= lat_max) & (num_dates_2d <= july1) & (num_dates_2d >= june1)].mean()
    mean_max_future = intf_f[(lats_agg_2d >= lat_min) & (lats_agg_2d <= lat_max) & (num_dates_2d <= june1) & (num_dates_2d >= may1)].mean()

    print("Mean change in the maximum interflow rate: {} %".format((mean_max_future - mean_max_current) * 100 / mean_max_current))

    img_file = Path(img_folder).joinpath("INTF_rate_longit_avg.png")
    fig.tight_layout()
    from crcm5.analyse_hdf import common_plot_params
    fig.savefig(str(img_file), bbox_inches="tight", transparent=True, dpi=common_plot_params.FIG_SAVE_DPI)