Exemple #1
0
def create_labels(label_name, label_ticks):
    if label_name == "months":
        if len(label_ticks) > 40:
            mult = 6
        elif len(label_ticks) > 10:
            mult = 4
        else:
            mult = 3
        label_ticks = [ii for ii in label_ticks if ii % mult == 0]
        label = [calendar_months[ii % 12] for ii in label_ticks]
    elif label_name == "latitude":
        if len(label_ticks) < 40:
            mult = 10
        else:
            mult = 20
        label_ticks = [ii for ii in label_ticks if ii % mult == 0]
        if min(label_ticks) < 0 and max(label_ticks) > 0 and 0 not in label_ticks:
            label_ticks = NUMPYarray(label_ticks)
            while 0 not in label_ticks:
                label_ticks = label_ticks + 1
        label = [str(abs(int(ii))) + '$^\circ$S' if ii < 0 else (str(abs(int(ii))) + '$^\circ$N' if ii > 0 else 'eq')
                 for ii in label_ticks]
    elif label_name == "longitude":
        if len(label_ticks) < 200:
            mult = 40
        else:
            mult = 90
        label_ticks = [ii for ii in label_ticks if ii % mult == 0]
        if min(label_ticks) < 180 and max(label_ticks) > 180 and 180 not in label_ticks:
            label_ticks = NUMPYarray(label_ticks)
            while 180 not in label_ticks:
                label_ticks = label_ticks + 10
        label = [str(int(ii)) + "$^\circ$E" if ii < 180 else (
            str(abs(int(ii) - 360)) + "$^\circ$W" if ii > 180 else "180$^\circ$") for ii in label_ticks]
    return label_ticks, label
def my_mask(tab, remove_masked=False):
    tmp = NUMPYarray(tab, dtype=float)
    tmp = NUMPYwhere(tmp == None, NUMPYnan, tmp)
    tmp = NUMPYma__masked_invalid(tmp)
    if remove_masked is True:
        # tmp = tmp[~tmp.mask]
        tmp = tmp.compressed()
    return tmp
Exemple #3
0
def FindXYMinMax(tab, return_val='both'):
    """
    #################################################################################
    Description:
    Finds in tab the position (t,x,y,z) of the minimum (return_val='mini') or the maximum (return_val='maxi') or both
    values (if return_val is neither 'mini' nor 'maxi')
    Returned position(s) are not the position in tab but in the (t,x,y,z) space defined by tab axes
    #################################################################################

    :param tab: masked_array
        array for which you would like to know the position (t,x,y,z) of the minimum and/or the maximum values
    :param return_val: string, optional
        'mini' to return the position of the minimum value
        'maxi' to return the position of the maximum value
        to return both minimum and maximum values, pass anything else
        default value = 'both', returns both minimum and maximum values

    :return: minimum/maximum position or both minimum and maximum positions, int, float or list
        position(s) in the (t,x,y,z) space defined by tab axes of the minimum and/or maximum values of tab
    """
    mini = NUMPYunravel_index(tab.argmin(), tab.shape)
    maxi = NUMPYunravel_index(tab.argmax(), tab.shape)
    list_ax = NUMPYarray([tab.getAxis(ii)[:] for ii in range(len(mini))])
    axis_min = [list_ax[ii][mini[ii]] for ii in range(len(mini))]
    axis_max = [list_ax[ii][maxi[ii]] for ii in range(len(mini))]
    if return_val == 'mini':
        if len(axis_min) == 1:
            tab_out = axis_min[0]
        else:
            tab_out = axis_min
    elif return_val == 'maxi':
        if len(axis_max) == 1:
            tab_out = axis_max[0]
        else:
            tab_out = axis_max
    else:
        if len(axis_min) == 1 and len(axis_max) == 1:
            tab_out = [axis_min[0], axis_max[0]]
        else:
            tab_out = [axis_min, axis_max]
    return tab_out
def plot_curves(tab_mod,
                tab_obs,
                name_png,
                title='',
                xname='',
                yname='',
                units='',
                mytext=[]):
    axisname = tab_mod.coords.keys()[0]
    axis = list(NUMPYarray(tab_mod.coords[axisname]))
    tab_mod = NUMPYarray(tab_mod)
    tab_obs = NUMPYarray(tab_obs)
    # figure initialization
    if (axisname == "month" or axisname == "months"
            or axisname == "time") and len(tab_mod) == 72:
        fig, ax = plt.subplots(figsize=(8, 4))
    else:
        fig, ax = plt.subplots(figsize=(4, 4))
    # title
    ax.set_title(title, fontsize=20, y=1.01, loc='left')
    # x axis
    tmp = list(range(int(MATHfloor(min(axis))), int(MATHceil(max(axis))) + 1))
    plt.xlim(min(axis), max(axis))
    if axisname == "month" or axisname == "months" or axisname == "time":
        if len(tmp) > 40:
            mult = 6
        else:
            mult = 4
        tmp = [ii for ii in tmp if ii % mult == 0]
        label = [seasons_1m[ii % 12] for ii in tmp]
        if xname == '':
            xname = 'months'
    elif "lat" in axisname:
        if len(tmp) < 40:
            mult = 10
        else:
            mult = 20
        tmp = [ii for ii in tmp if ii % mult == 0]
        if min(tmp) < 0 and max(tmp) > 0 and 0 not in tmp:
            tmp = NUMPYarray(tmp)
            while 0 not in tmp:
                tmp = tmp + 1
        label = [
            str(abs(int(ii))) + '$^\circ$S' if ii < 0 else
            (str(abs(int(ii))) + '$^\circ$N' if ii > 0 else 'eq') for ii in tmp
        ]
        if xname == '':
            xname = 'latitude'
    elif "lon" in axisname:
        if len(tmp) < 200:
            mult = 40
        else:
            mult = 90
        tmp = [ii for ii in tmp if ii % mult == 0]
        if min(tmp) < 180 and max(tmp) > 180 and 180 not in tmp:
            tmp = NUMPYarray(tmp)
            while 180 not in tmp:
                tmp = tmp + 10
        label = [
            str(int(ii)) + '$^\circ$E' if ii < 180 else
            (str(abs(int(ii) - 360)) +
             '$^\circ$W' if ii > 180 else '180$^\circ$') for ii in tmp
        ]
        if xname == '':
            xname = 'longitude'
    plt.xticks(tmp, label)
    ax.set_xlabel(xname, fontsize=20)
    for tick in ax.xaxis.get_major_ticks():
        tick.label.set_fontsize(15)
    # y axis
    minmax, mult = create_minmax_plot(
        [tab_mod.min(),
         tab_mod.max(),
         tab_obs.min(),
         tab_obs.max()])
    if mult != 1.:
        tab_mod = tab_mod / mult
        tab_obs = tab_obs / mult
        tmp = units.split(" ")
        if len(tmp) == 1:
            scale = format_scale(mult)
            name_units = deepcopy(units)
        else:
            scale = format_scale(float(tmp[0]) * mult)
            name_units = deepcopy(tmp[1])
        ylabel = yname.replace(units, scale + " " + name_units)
    else:
        ylabel = deepcopy(yname)
    plt.ylim(min(minmax), max(minmax))
    plt.locator_params(axis='y', nbins=4)
    ax.set_ylabel(ylabel, fontsize=20)
    for tick in ax.yaxis.get_major_ticks():
        tick.label.set_fontsize(15)
    if min(minmax) < 0 and max(minmax) > 0:
        ax.axhline(0, color='k', linestyle='-', linewidth=2)
    # plot curves
    ax.plot(axis,
            list(tab_mod),
            lw=4,
            label='model',
            color=ref_colors['model'])
    ax.plot(axis, list(tab_obs), lw=4, label='obs', color=ref_colors['obs'])
    # relative space
    x1 = min(axis)
    x2 = max(axis)
    dx = (x2 - x1) / 100.
    y1 = min(minmax)
    y2 = max(minmax)
    dy = (y2 - y1) / 100.
    # legend
    leg_text = ['obs', 'model']
    for ii, txt in enumerate(leg_text):
        plt.text((2 * dx) + x1,
                 y2 - (((ii + 1) * 6) * dy),
                 txt,
                 fontsize=15,
                 color=ref_colors[txt],
                 horizontalalignment='left',
                 verticalalignment='center')
    # my text
    for ii, txt in enumerate(mytext):
        plt.text(x2 - (2 * dx),
                 y2 - (((ii + 1) * 6) * dy),
                 txt,
                 fontsize=15,
                 color='k',
                 horizontalalignment='right',
                 verticalalignment='center')
    plt.grid(linestyle='--', linewidth=1, which='major')
    plt.savefig(name_png, bbox_inches='tight')
    plt.close()
    return
def get_metric_values(project,
                      metric_collection,
                      dict_json,
                      dict_mod_mem,
                      reduced_set=True,
                      portraitplot=False):
    """
    Finds fixed variables, here areacell and sftlf (landmask), mostly used for observational dataset

    Inputs:
    ------
    :param project: strings
        project name (e.g., "CMIP5", "CMIP6")
    :param metric_collection: strings
        metric collection (e.g., "ENSO_perf", "ENSO_proc", "ENSO_tel")
    :param dict_json: dictionary
        Dictionary with path and name of json files output of the CLIVAR PRP ENSO metrics package.
    :param dict_mod_mem: dictionary
        Dictionary with every models available and members in the given json files, for the given projects and metric
        collections.
    **Optional arguments:**
    :param reduced_set: boolean, optional
        True to remove extra metrics that are not in the final set chosen by CLIVAR PRP.
        If set to False it removes metrics that are in more than one metric collection.
        Default value is True.
    :param portraitplot: boolean, optional
        True to remove extra metrics that are not in the final set chosen by CLIVAR PRP but keep metrics that are in
        more than one metric collection.
        If set to False it removes metrics that are in more than one metric collection.
        Default value is False.

    Output:
    ------
    :return dict_out: dictionary
        Dictionary with every models available and metrics, member values averaged
    """

    # open and read json file
    data_json = read_json(dict_json[project][metric_collection])
    list_models = list(dict_mod_mem[project].keys())
    dict_out = dict()
    for mod in list_models:
        list_members = sort_members(dict_mod_mem[project][mod])
        dict2 = dict()
        for mem in list_members:
            try:
                data_mod = data_json[mod][mem]["value"]
            except:
                data_mod = None
            list_metrics = list()
            try:
                list(data_mod.keys())
            except:
                pass
            else:
                list_metrics += list(data_mod.keys())
            list_metrics = remove_metrics(list_metrics,
                                          metric_collection,
                                          reduced_set=reduced_set,
                                          portraitplot=portraitplot)
            dict3 = dict()
            if len(list_metrics) > 0:
                for met in list_metrics:
                    dict3[met] = data_mod[met]["metric"][get_reference(
                        metric_collection, met)]["value"]
                dict2[mem] = dict3
            del data_mod, dict3, list_metrics
        # models and metrics
        list_metrics = list()
        for mem in list_members:
            try:
                list(dict2[mem].keys())
            except:
                pass
            else:
                list_metrics += list(dict2[mem].keys())
        # average member values if there is more than one available
        dict_met = dict()
        for met in list_metrics:
            tmp = [
                dict2[mem][met] for mem in list_members
                if dict2[mem][met] is not None and dict2[mem][met] != 1e20
            ]
            if len(tmp) > 0:
                dict_met[met] = float(tmp[0]) if len(tmp) == 1 else float(
                    NUMPYarray(tmp).mean())
            del tmp
        dict_out[mod] = dict_met
        del dict2, dict_met, list_members, list_metrics
    return dict_out
def my_bootstrap(tab1, tab2):
    mea1 = float(NUMPYarray(tab1).mean())
    mea2 = float(NUMPYarray(tab2).mean())
    bst1 = bootstrap(NUMPYarray(tab1), nech=len(tab2))
    bst2 = bootstrap(NUMPYarray(tab2), nech=len(tab1))
    return bst1, bst2, mea1, mea2
def minmax_plot(tab, metric=False):
    # define minimum and maximum
    mini, maxi = minimaxi(tab)
    if mini == maxi or abs(maxi - mini) / float(abs(maxi + mini)) < 1e-2:
        tt = max(abs(mini), abs(maxi)) / 10.
        tmp = int(str("%.e" % tt)[3:])
        if mini == maxi or (mini < 0 and maxi > 0):
            tmp = 10**-tmp if tt < 1 else 10**tmp
        elif mini >= 0:
            tmp = 10**-tmp if tt < 1 else 10**tmp
        else:
            tmp = 10**-tmp if tt < 1 else 10**tmp
        mini = 0 if mini > 0 and (mini - tmp) < 0 else mini - tmp
        maxi = 0 if maxi < 0 and (maxi + tmp) > 0 else maxi + tmp
    if mini < 0 and maxi > 0:
        locmaxi = max([abs(mini), abs(maxi)])
        locmini = -deepcopy(locmaxi)
    else:
        locmini, locmaxi = deepcopy(mini), deepcopy(maxi)
    # find the power of ten to get an interval between 1 and 10
    mult = pow(10, int(str("%e" % abs(locmaxi - locmini)).split('e')[1]))
    locmini, locmaxi = int(MATHfloor(float(locmini) / mult)), int(
        MATHceil(float(locmaxi) / mult))
    if locmaxi == 2 and maxi < 15 and mult == 10 and abs(locmini) != locmaxi:
        locmini, locmaxi = 0, 15
        mult = 1.
    scalmini, scalemaxi = mini / mult, maxi / mult
    interval = locmaxi - locmini
    listbase = list(
        NUMPYaround(
            [ii * 10**exp for exp in range(-1, 1) for ii in range(1, 6)],
            decimals=1))
    listbase = listbase + listbase
    listmult = [3] * int(round(len(listbase) / 2.)) + [4] * int(
        round(len(listbase) / 2.))
    list1 = list(
        NUMPYaround(
            [listbase[ii] * listmult[ii] for ii in range(len(listbase))],
            decimals=1))
    list2 = list(NUMPYaround([abs(ii - interval) for ii in list1], decimals=1))
    interval = list1[list2.index(min(list2))]
    base = listbase[list1.index(interval)]
    if base * 4.5 < interval:
        ii = 1
        tmp = sorted(list2)
        while base * 4.5 < interval:
            interval = list1[list2.index(tmp[ii])]
            base = listbase[list1.index(interval)]
            ii += 1
    if abs(locmini) == locmaxi:
        maxi_out = 2 * base
        while maxi_out - base > locmaxi:
            maxi_out -= base
        if metric is True and maxi_out < scalemaxi + base * 0.4:
            maxi_out += base
        mini_out = -maxi_out
    else:
        if locmini < 0 and locmaxi <= 0:
            locmini, locmaxi = abs(locmaxi), abs(locmini)
            sign = -1
        else:
            sign = 1
        half_int = int(round(interval / 2.))
        tmp_middle = locmini + half_int
        mini_out = max([0, tmp_middle - half_int])
        while mini_out > locmini:
            mini_out -= base
        while mini_out + base < locmini:
            mini_out += base
        maxi_out = mini_out + 2 * base
        while maxi_out < locmaxi:
            maxi_out += base
        while maxi_out - base > locmaxi:
            maxi_out -= base
        minmax = list(
            NUMPYaround(NUMPYarray([mini_out, maxi_out]) * sign,
                        decimals=0).astype(int))
        mini_out, maxi_out = min(minmax), max(minmax)
        if metric is True:
            if maxi_out < scalemaxi + base * 0.4:
                maxi_out += base
    tick_labels = NUMPYarange(mini_out, maxi_out + base / 2., base)
    tick_labels = list(NUMPYaround(tick_labels * mult, decimals=4))
    if all([True if int(ii) == float(ii) else False for ii in tick_labels]):
        tick_labels = list(NUMPYaround(tick_labels, decimals=0).astype(int))
    if len(tick_labels) > 7:
        list_strings = [
            "WARNING" + EnsoErrorsWarnings.message_formating(INSPECTstack()) +
            ": too many ticks for axis",
            str().ljust(5) + str(len(tick_labels)) + " ticks: " +
            str(tick_labels),
            str().ljust(5) + "there should not be more than 7"
        ]
        EnsoErrorsWarnings.my_warning(list_strings)
    if min(tick_labels) > mini or max(tick_labels) < maxi:
        list_strings = [
            "WARNING" + EnsoErrorsWarnings.message_formating(INSPECTstack()) +
            ": wrong bounds in ticks for axis"
        ]
        if min(tick_labels) > mini:
            list_strings += [
                str().ljust(5) + "ticks minimum (" + str(min(tick_labels)) +
                ") > tab minimum (" + str(mini) + ")"
            ]
        if max(tick_labels) < maxi:
            list_strings += [
                str().ljust(5) + "ticks maximum (" + str(max(tick_labels)) +
                ") > tab maximum (" + str(maxi) + ")"
            ]
        EnsoErrorsWarnings.my_warning(list_strings)
    return tick_labels
def my_map(model,
           filename_nc,
           dict_param,
           reference,
           metric_variables,
           figure_name,
           metric_type=None,
           metric_values=None,
           metric_units=None,
           diagnostic_values=None,
           diagnostic_units=None,
           regions=None):
    # get data
    variables = dict_param["varpattern"]
    if isinstance(variables, str):
        nbr_val = 1
    else:
        nbr_val = len(variables)
    tab_mod, tab_obs, metval, obsname = \
        read_var(variables, filename_nc, model, reference, metric_variables, metric_values)
    if metric_type is not None:
        plot_metric = True
    else:
        plot_metric = False
    if metric_units is not None:
        metric_units = metric_units.replace("C", "$^\circ$C").replace(
            "long", "$^\circ$long")
    if isinstance(filename_nc, str):
        lon = list(NUMPYarray(tab_mod[0].coords[tab_mod[0].dims[1]]))
        lat = list(NUMPYarray(tab_mod[0].coords[tab_mod[0].dims[0]]))
    else:
        lon = list(NUMPYarray(tab_mod[0][0].coords[tab_mod[0][0].dims[1]]))
        lat = list(NUMPYarray(tab_mod[0][0].coords[tab_mod[0][0].dims[0]]))
    # figure initialization
    nbr_panel = dict_param["nbr_panel"]
    if isinstance(filename_nc, list):
        nbr_panel = nbr_panel + ((len(tab_mod) - 1) * nbr_val)
    title = dict_param["title"]
    xname = dict_param["xname"]
    yname = dict_param["yname"]
    zname = dict_param["zname"]
    if isinstance(filename_nc, list):
        if nbr_val == 1:
            title = [obsname] + mod_nicknames  # model
        else:
            title = [obsname] + mod_nicknames  #list()
            title = title * nbr_val
            # for tt in dict_param["title"]:
            #     title.append(tt + ": " + obsname)
            #     for mod in mod_nicknames:#model:
            #         title.append(tt + ": " + mod)
    if isinstance(filename_nc, str):
        units = tab_mod[0].units.replace("C", "$^\circ$C").replace(
            "long", "$^\circ$long")
    else:
        units = tab_mod[0][0].units.replace("C", "$^\circ$C").replace(
            "long", "$^\circ$long")
    if units != "":
        zname = zname + " (" + units + ")"
    colorbar = "cmo." + dict_param["colorbar"]
    labelbar = dict_param["label"]
    if "maskland" in dict_param.keys():
        maskland = dict_param["maskland"]
    else:
        maskland = False
    nbrl = int(round(nbr_panel / 2.))
    nbrc = 1 if nbr_panel == 1 else 2
    fig, axes = plt.subplots(nbrl,
                             nbrc,
                             figsize=(4 * nbrc, 4 * nbrl),
                             sharex="col",
                             sharey="row")
    hspa1 = 0.1
    hspa2 = 0.01
    if nbr_panel in [3, 4]:
        plt.subplots_adjust(hspace=-0.75, wspace=0.2)
    elif nbr_panel in [5, 6]:
        plt.subplots_adjust(hspace=-0.8, wspace=0.2)
    elif nbr_panel in [7, 8]:
        plt.subplots_adjust(hspace=-0.85, wspace=0.2)
    elif nbr_panel in [11, 12]:
        plt.subplots_adjust(hspace=-0.9, wspace=0.2)
    else:
        plt.subplots_adjust(hspace=hspa1, wspace=0.2)
    xlabel_ticks = list(
        range(int(MATHfloor(min(lon))),
              int(MATHceil(max(lon))) + 1))
    xlabel_ticks, xlabel = create_labels(xname, xlabel_ticks)
    ylabel_ticks = list(
        range(int(MATHfloor(min(lat))),
              int(MATHceil(max(lat))) + 1))
    ylabel_ticks, ylabel = create_labels(yname, ylabel_ticks)
    tab = list()
    if isinstance(filename_nc, str):
        legend = ["ref: " + obsname, model]
        for ii in range(len(tab_mod)):
            tab.append(tab_obs[ii])
            tab.append(tab_mod[ii])
    else:
        legend = ["ref: " + obsname] + model
        for ii in range(len(tab_obs)):
            tab.append(tab_obs[ii])
            for kk in range(len(tab_mod)):
                tab.append(tab_mod[kk][ii])
    for ii in range(nbr_panel):
        if nbr_panel == 1:
            ax = axes
        elif nbrl == 1 and nbrc != 1:
            ax = axes[ii % 2]
        else:
            ax = axes[ii / 2, ii % 2]
        if isinstance(filename_nc, list):
            if ii % 2 == 0:
                ax.set_title(title[ii], fontsize=15, y=1. + hspa2, loc="left")
            else:
                ax.set_title(title[ii], fontsize=15, y=1. + hspa2, loc="right")
            if nbr_val > 1:
                if ii % (len(filename_nc) + 1) == 0:
                    ax.text(1.1,
                            1.02,
                            dict_param["title"][ii / (len(filename_nc) + 1)],
                            fontsize=15,
                            weight="bold",
                            horizontalalignment="center",
                            verticalalignment="bottom",
                            transform=ax.transAxes)
        else:
            ax.set_title(title[ii / 2], fontsize=15, y=1. + hspa2, loc="left")
        if isinstance(filename_nc, str):
            if ii in [0, 1]:
                ax.text(0.5,
                        1. + hspa1 * 6,
                        legend[ii % 2],
                        fontsize=15,
                        weight="bold",
                        horizontalalignment="center",
                        verticalalignment="center",
                        transform=ax.transAxes)
        # map
        xx, yy = NUMPYmeshgrid(lon, lat)
        if lat[-1] - lat[0] < 40:
            locmap = Basemap(projection="cyl",
                             llcrnrlat=lat[0] - 5,
                             urcrnrlat=lat[-1] + 5,
                             llcrnrlon=lon[0],
                             urcrnrlon=lon[-1],
                             ax=ax)
        else:
            locmap = Basemap(projection="cyl",
                             llcrnrlat=lat[0],
                             urcrnrlat=lat[-1],
                             llcrnrlon=lon[0],
                             urcrnrlon=lon[-1],
                             ax=ax)
        # draw coastlines
        locmap.drawcoastlines()
        # fill continents
        if maskland is True:
            locmap.fillcontinents(color="gainsboro")
        # draw parallels
        locmap.drawparallels(ylabel_ticks,
                             labels=[1, 0, 0, 0],
                             fontsize=12,
                             dashes=[3, 1],
                             linewidth=1)
        # draw meridians
        locmap.drawmeridians(xlabel_ticks,
                             labels=[0, 0, 0, 1],
                             fontsize=12,
                             dashes=[3, 1],
                             linewidth=1)
        #cs = locmap.pcolormesh(xx, yy, tab[ii], vmin=min(labelbar), vmax=max(labelbar), cmap=colorbar)
        levels = create_levels(labelbar)
        cs = locmap.contourf(xx,
                             yy,
                             tab[ii],
                             levels=levels,
                             extend="both",
                             cmap=colorbar)
        # my text
        if ii == 0 and plot_metric is True:
            x1 = ax.get_position().x1
            y2 = ax.get_position().y1
            if nbrl == 1:
                ax2 = axes[(ii + 1) % 2]
            else:
                ax2 = axes[(ii + 1) / 2, (ii + 1) % 2]
            x2 = ax2.get_position().x0
            txt = format_metric(metric_type, metval, metric_units)
            ax.text(x1 + ((x2 - x1) / 2.),
                    y2 + 0.1,
                    txt,
                    fontsize=12,
                    color="k",
                    horizontalalignment="center",
                    verticalalignment="center",
                    transform=fig.transFigure)
        if ii == nbr_panel - 2:
            x1 = ax.get_position().x0
        elif ii == nbr_panel - 1:
            x2 = ax.get_position().x1
            y1 = ax.get_position().y0
    # add colorbar
    if nbr_panel in [3, 4]:
        cax = plt.axes([x1, y1 + 0.21, x2 - x1, 0.015])
    elif nbr_panel in [5, 6]:
        cax = plt.axes([x1, y1 + 0.2, x2 - x1, 0.015])
    elif nbr_panel in [7, 8]:
        cax = plt.axes([x1, y1 + 0.21, x2 - x1, 0.01])
    elif nbr_panel in [11, 12]:
        cax = plt.axes([x1, y1 + 0.22, x2 - x1, 0.005])
    else:
        cax = plt.axes([x1, y1 + 0.2, x2 - x1, 0.03])
    cbar = plt.colorbar(cs,
                        cax=cax,
                        orientation="horizontal",
                        ticks=labelbar,
                        pad=0.35,
                        extend="both")
    cbar.set_label(zname, fontsize=15)
    cbar.ax.tick_params(labelsize=12)
    plt.savefig(figure_name, bbox_inches="tight")
    plt.close()
    return
def my_hovmoeller(model,
                  filename_nc,
                  dict_param,
                  reference,
                  metric_variables,
                  figure_name,
                  metric_type=None,
                  metric_values=None,
                  metric_units=None,
                  diagnostic_values=None,
                  diagnostic_units=None,
                  regions=None):
    # get data
    variables = dict_param["varpattern"]
    if isinstance(variables, str):
        nbr_val = 1
    else:
        nbr_val = len(variables)
    tab_mod, tab_obs, metval, obsname = \
        read_var(variables, filename_nc, model, reference, metric_variables, metric_values)
    if isinstance(filename_nc, str):
        tim = list(NUMPYarray(tab_mod[0].coords[tab_mod[0].dims[0]]))
        lon = list(NUMPYarray(tab_mod[0].coords[tab_mod[0].dims[1]]))
    else:
        tim = list(NUMPYarray(tab_mod[0][0].coords[tab_mod[0][0].dims[0]]))
        lon = list(NUMPYarray(tab_mod[0][0].coords[tab_mod[0][0].dims[1]]))
    nbr_years = len(tim) / 12.
    # figure initialization
    nbr_panel = dict_param["nbr_panel"]
    if isinstance(filename_nc, list):
        nbr_panel = nbr_panel + ((len(tab_mod) - 1) * nbr_val)
    title = dict_param["title"]
    if isinstance(filename_nc, list):
        if nbr_val == 1:
            title = [obsname] + mod_nicknames  # model[ii]
        else:
            title = [obsname] + mod_nicknames  # list()
            title = title * nbr_val
            # for tt in dict_param["title"]:
            #     title.append(tt + ": " + obsname)
            #     for mod in mod_nicknames:#model:
            #         title.append(tt + ": " + mod)
    xname = dict_param["xname"]
    yname = dict_param["yname"]
    zname = dict_param["zname"]
    if isinstance(filename_nc, str):
        units = tab_mod[0].units.replace("C", "$^\circ$C").replace(
            "long", "$^\circ$long")
    else:
        units = tab_mod[0][0].units.replace("C", "$^\circ$C").replace(
            "long", "$^\circ$long")
    if units != "":
        zname = zname + " (" + units + ")"
    colorbar = "cmo." + dict_param["colorbar"]
    labelbar = dict_param["label"]
    nbrl = int(round(nbr_panel / 2.))
    nbrc = 1 if nbr_panel == 1 else 2
    fig, axes = plt.subplots(nbrl,
                             nbrc,
                             figsize=(4 * nbrc, 4 * nbr_years * nbrl),
                             sharex="col",
                             sharey="row")
    hspa1 = 0.3 / nbr_years
    hspa2 = 0.01 / nbr_years
    plt.subplots_adjust(hspace=hspa1, wspace=0.1)
    xlabel_ticks = list(
        range(int(MATHfloor(min(lon))),
              int(MATHceil(max(lon))) + 1))
    xlabel_ticks, xlabel = create_labels(xname, xlabel_ticks)
    ylabel_ticks = list(
        range(int(MATHfloor(min(tim))),
              int(MATHceil(max(tim))) + 1))
    ylabel_ticks, ylabel = create_labels(yname, ylabel_ticks)
    tab = list()
    if isinstance(filename_nc, str):
        legend = ["ref: " + obsname, model]
        for ii in range(len(tab_obs)):
            tab.append(tab_obs[ii])
            tab.append(tab_mod[ii])
    else:
        legend = ["ref: " + obsname] + model
        for ii in range(len(tab_obs)):
            tab.append(tab_obs[ii])
            for kk in range(len(tab_mod)):
                tab.append(tab_mod[kk][ii])
    for ii in range(nbr_panel):
        if nbr_panel == 1:
            ax = axes
        elif nbrl == 1 and nbrc != 1:
            ax = axes[ii % 2]
        else:
            ax = axes[ii / 2, ii % 2]
        # title
        if isinstance(filename_nc, str):
            ax.set_title(title[ii / 2], fontsize=15, y=1. + hspa2, loc="left")
        else:
            if ii % 2 == 0:
                ax.set_title(title[ii], fontsize=15, y=1. + hspa2, loc="left")
            else:
                ax.set_title(title[ii], fontsize=15, y=1. + hspa2, loc="right")
            if nbr_val > 1:
                if ii % (len(filename_nc) + 1) == 0:
                    ttx2 = ax.get_position().x1
                elif (ii - 1) % (len(filename_nc) + 1) == 0:
                    ttx1 = ax.get_position().x0
                    tty2 = ax.get_position().y1
                    ax.text(ttx2 + (ttx1 - ttx2) / 2.,
                            tty2 + hspa2 / 2,
                            dict_param["title"][(ii - 1) /
                                                (len(filename_nc) + 1)],
                            fontsize=15,
                            weight="bold",
                            horizontalalignment="center",
                            verticalalignment="center",
                            transform=fig.transFigure)
        if isinstance(filename_nc, str):
            if ii in [0, 1]:
                ax.text(0.5,
                        1. + hspa1,
                        legend[ii % 2],
                        fontsize=15,
                        weight="bold",
                        horizontalalignment="center",
                        verticalalignment="center",
                        transform=ax.transAxes)
        # x axis
        ax.set_xlim(xmin=min(lon), xmax=max(lon))
        if ii >= nbr_panel - 2:
            ax.set_xticks(xlabel_ticks)
            ax.set_xticklabels(xlabel)
            ax.set_xlabel(xname, fontsize=15)
        for tick in ax.xaxis.get_major_ticks():
            tick.label.set_fontsize(12)
        # y axis
        ax.set_ylim(ymin=min(tim), ymax=max(tim))
        if ii % 2 == 0:
            ax.set_yticks(ylabel_ticks)
            ax.set_yticklabels(ylabel)
            ax.set_ylabel(yname, fontsize=15)
        for tick in ax.yaxis.get_major_ticks():
            tick.label.set_fontsize(12)
        # hovmoeller
        levels = create_levels(labelbar)
        xx, yy = NUMPYmeshgrid(lon, tim)
        cs = ax.contourf(xx,
                         yy,
                         tab[ii],
                         levels=levels,
                         extend="both",
                         cmap=colorbar)
        if ii == nbr_panel - 2:
            x1 = ax.get_position().x0
        elif ii == nbr_panel - 1:
            x2 = ax.get_position().x1
    # add colorbar
    if nbr_years == 1 and nbrl == 1:
        cax = plt.axes([x1, -0.1, x2 - x1, 0.04])
    else:
        if nbr_panel in [5, 6]:
            if nbr_years == 6:
                cax = plt.axes([x1, 0.09, x2 - x1, 0.005])
            else:
                cax = plt.axes([x1, 0.03, x2 - x1, 0.02])
        elif nbr_panel in [3, 4] and nbr_years == 6:
            cax = plt.axes([x1, 0.09, x2 - x1, 0.006])
        elif nbr_panel in [7, 8] and nbr_years == 6:
            cax = plt.axes([x1, 0.1, x2 - x1, 0.002])
        elif nbr_panel in [11, 12] and nbr_years == 6:
            cax = plt.axes([x1, 0.1, x2 - x1, 0.002])
        elif nbr_panel in [17, 18]:
            if nbr_years < 1:
                cax = plt.axes([x1, 0.07, x2 - x1, 0.01])
            else:
                cax = plt.axes([x1, 0.08, x2 - x1, 0.005])
        else:
            cax = plt.axes([x1, 0.0, x2 - x1, 0.02])
    cbar = plt.colorbar(cs,
                        cax=cax,
                        orientation="horizontal",
                        ticks=labelbar,
                        pad=0.35,
                        extend="both")
    cbar.set_label(zname, fontsize=15)
    cbar.ax.tick_params(labelsize=12)
    plt.savefig(figure_name, bbox_inches="tight")
    plt.close()
    return
def my_curve(model,
             filename_nc,
             dict_param,
             reference,
             metric_variables,
             figure_name,
             metric_type=None,
             metric_values=None,
             metric_units=None,
             diagnostic_values=None,
             diagnostic_units=None,
             regions=None):
    # get data
    variables = dict_param["varpattern"]
    if isinstance(variables, str):
        nbr_val = 1
    else:
        nbr_val = len(variables)
    tab_mod, tab_obs, metval, obsname =\
        read_var(deepcopy(variables), filename_nc, model, reference, metric_variables, metric_values)
    if metric_type is not None and isinstance(filename_nc, str) is True:
        plot_metric = True
    else:
        plot_metric = False
    if isinstance(filename_nc, str):
        axis = list(NUMPYarray(tab_mod[0].coords[tab_mod[0].coords.keys()[0]]))
    else:
        axis = list(
            NUMPYarray(tab_mod[0][0].coords[tab_mod[0][0].coords.keys()[0]]))
    # figure initialization
    title = dict_param["title"]
    xname = dict_param["xname"]
    yname = dict_param["yname"]
    if isinstance(filename_nc, str):
        units = tab_mod[0].units.replace("C", "$^\circ$C").replace(
            "long", "$^\circ$long")
    else:
        units = tab_mod[0][0].units.replace("C", "$^\circ$C").replace(
            "long", "$^\circ$long")
    if units != "":
        yname = yname + " (" + units + ")"
    if "colors" in dict_param.keys():
        linecolors = dict_param["colors"]
    else:
        linecolors = {"model": ["r"], "reference": ["k"]}
    if "linestyles" in dict_param.keys():
        linestyles = dict_param["linestyles"]
    else:
        linestyles = {"model": ["-"], "reference": ["-"]}
    if "legend" in dict_param.keys():
        legend = dict_param["legend"]
    else:
        if isinstance(filename_nc, str):
            legend = ["ref: " + obsname, model]
        else:
            legend = ["ref: " + obsname] + mod_nicknames  # model
    nbr = len(tab_mod[0]) if isinstance(filename_nc, str) else len(
        tab_mod[0][0])
    if isinstance(filename_nc, str):
        tmp = tab_mod + tab_obs
    else:
        tmp = deepcopy(tab_obs)
        for ii in range(len(tab_mod)):
            tmp += tab_mod[ii]
    ytick_labels = minmax_plot(tmp, metric=plot_metric)
    # plot
    if isinstance(filename_nc, str):
        if xname == "months" and nbr == 72:
            fig, ax = plt.subplots(figsize=(8, 4))
        else:
            fig, ax = plt.subplots(figsize=(4, 4))
        plot_curve(tab_mod,
                   tab_obs,
                   ax,
                   title,
                   axis,
                   xname,
                   yname,
                   ytick_labels,
                   linecolors,
                   linestyles,
                   metric_type,
                   metval,
                   metric_units,
                   model=model,
                   obsname=obsname,
                   legend=legend,
                   multimodel=False,
                   plot_metric=plot_metric)
    else:
        if metric_type is not None:
            plot_metric = True
        if xname == "months" and nbr == 72:
            nbrl = nbr_val
            nbrc = 1
            fig, axes = plt.subplots(nbrl,
                                     nbrc,
                                     figsize=(8, 4 * nbrl),
                                     sharex="col",
                                     sharey="row")
        else:
            nbrl = int(round(nbr_val / 2.))
            nbrc = 1 if nbr_val == 1 else 2
            fig, axes = plt.subplots(nbrl,
                                     nbrc,
                                     figsize=(4 * nbrc, 4 * nbrl),
                                     sharex="col",
                                     sharey="row")
        old_leg = deepcopy(legend)
        legend = ["ref: " + obsname] + mod_nicknames  # model
        for kk in range(len(tab_obs)):
            tab_tmp = [tab_mod[jj][kk] for jj in range(len(tab_mod))]
            if nbr_val == 1:
                ax = axes
            elif (nbrl == 1 and nbrc != 1) or (nbrl != 1 and nbrc == 1):
                ax = axes[kk % 2]
            else:
                ax = axes[kk / 2, kk % 2]
            if "legend" in dict_param.keys():
                title_tmp = title + ": " + old_leg[kk]
            else:
                title_tmp = title
            lcol = {"model": ["dodgerblue"], "reference": ["k"]}
            lsty = {"model": ["-"], "reference": ["-"]}
            for jj in range(len(filename_nc) - 1):
                lcol["model"].append(colors_sup[jj])
                lsty["model"].append("-")
            if (nbrc == 2 and kk == 1) or (nbrc == 1
                                           and kk == 0) or nbr_val == 1:
                plot_legend = True
            else:
                plot_legend = False
            plot_curve(tab_tmp, [tab_obs[kk]],
                       ax,
                       title_tmp,
                       axis,
                       xname,
                       yname,
                       ytick_labels,
                       lcol,
                       lsty,
                       metric_type,
                       metval,
                       metric_units,
                       model=model,
                       obsname=obsname,
                       legend=legend,
                       multimodel=True,
                       plot_metric=plot_metric,
                       plot_legend=plot_legend)
    plt.savefig(figure_name, bbox_inches='tight')
    plt.close()
    return
Exemple #11
0
         list_metrics += list(dict_met[k1][k2].keys())
 list_metrics = sort_metrics(list(set(list_metrics)))
 opposed_groups = deepcopy(
     list_projects) if big_ensemble is False else deepcopy(my_project)
 # mean metric evaluation
 tab_bst, tab_val = list(), list()
 for met in list_metrics:
     tab_tmp = list()
     for grp in opposed_groups:
         tab = list()
         for mod in list(dict_met[grp].keys()):
             if met in list(dict_met[grp][mod].keys()):
                 if dict_met[grp][mod][met] is not None and dict_met[grp][
                         mod][met] != 1e20:
                     tab.append(dict_met[grp][mod][met])
         tab = NUMPYarray(tab)
         tab_tmp.append(NUMPYma__masked_invalid(tab).compressed())
         del tab
     tab1, tab2 = list(), list()
     for ii in range(len(tab_tmp)):
         tab1.append(float(NUMPYmean(tab_tmp[ii])))
         nbr = nbr = len(tab_tmp[1]) if ii == 0 else len(tab_tmp[0])
         bst = bootstrap(tab_tmp[ii], nech=nbr)
         tab2.append(bst)
         del bst, nbr
     tab_bst.append(tab2)
     tab_val.append(tab1)
 tab_bst = NUMPYmoveaxis(NUMPYarray(tab_bst), 0, 1)
 tab_bst = NUMPYma__masked_where(tab_bst == 1e20, tab_bst)
 tab_val = NUMPYmoveaxis(NUMPYarray(tab_val), 0, -1)
 tmp = NUMPYmoveaxis(NUMPYarray([tab_val[1], tab_val[1]]), 0, 1)