Пример #1
0
    def test_confidence_interval_to_polygon_second(self):
        """Ensures correct output from confidence_interval_to_polygon.

        In this case, using second set of inputs.
        """

        this_coord_matrix = evaluation.confidence_interval_to_polygon(
            x_value_matrix=SECOND_X_VALUE_MATRIX,
            y_value_matrix=SECOND_Y_VALUE_MATRIX,
            confidence_level=SECOND_CONFIDENCE_LEVEL,
            same_order=SECOND_SAME_ORDER_FLAG)

        self.assertTrue(
            numpy.allclose(this_coord_matrix,
                           SECOND_POLYGON_COORD_MATRIX,
                           atol=TOLERANCE))
Пример #2
0
def _plot_unitless_scores(mae_skill_score_matrix, mse_skill_score_matrix,
                          correlation_matrix, kge_matrix, num_examples_array,
                          plot_legend, confidence_level):
    """Plots scores without physical units, for one time split and one field.

    B = number of bootstrap replicates
    T = number of time chunks

    :param mae_skill_score_matrix: T-by-B numpy array of MAE (mean absolute
        error) skill scores.
    :param mse_skill_score_matrix: T-by-B numpy array of MSE (mean squared
        error) skill scores.
    :param correlation_matrix: T-by-B numpy array of correlations.
    :param kge_matrix: T-by-B numpy array of KGE values.
    :param num_examples_array: length-T numpy array with number of examples for
        each time chunk.
    :param plot_legend: See doc for `_plot_scores_with_units`.
    :param confidence_level: Same.
    :return: figure_object: Same.
    :return: axes_object: Same.
    """

    # Housekeeping.
    figure_object, main_axes_object = pyplot.subplots(
        1, 1, figsize=(FIGURE_WIDTH_INCHES, FIGURE_HEIGHT_INCHES))

    histogram_axes_object = main_axes_object.twinx()
    main_axes_object.set_zorder(histogram_axes_object.get_zorder() + 1)
    main_axes_object.patch.set_visible(False)

    num_time_chunks = mae_skill_score_matrix.shape[0]
    num_bootstrap_reps = mae_skill_score_matrix.shape[1]

    x_values = numpy.linspace(0,
                              num_time_chunks - 1,
                              num=num_time_chunks,
                              dtype=float)

    # Plot mean MAE skill score.
    this_handle = main_axes_object.plot(x_values,
                                        numpy.mean(mae_skill_score_matrix,
                                                   axis=1),
                                        color=MAE_SKILL_COLOUR,
                                        linewidth=LINE_WIDTH,
                                        marker=MARKER_TYPE,
                                        markersize=MARKER_SIZE,
                                        markerfacecolor=MAE_SKILL_COLOUR,
                                        markeredgecolor=MAE_SKILL_COLOUR,
                                        markeredgewidth=0)[0]

    legend_handles = [this_handle]
    legend_strings = ['MAE skill score']

    # Plot confidence interval for MAE skill score.
    if num_bootstrap_reps > 1 and confidence_level is not None:
        polygon_coord_matrix = evaluation.confidence_interval_to_polygon(
            x_value_matrix=numpy.expand_dims(x_values, axis=-1),
            y_value_matrix=mae_skill_score_matrix,
            confidence_level=confidence_level,
            same_order=True)

        if polygon_coord_matrix is not None:
            polygon_colour = matplotlib.colors.to_rgba(MAE_SKILL_COLOUR,
                                                       POLYGON_OPACITY)
            patch_object = matplotlib.patches.Polygon(polygon_coord_matrix,
                                                      lw=0,
                                                      ec=polygon_colour,
                                                      fc=polygon_colour)
            main_axes_object.add_patch(patch_object)

    # Plot mean MSE skill score.
    this_handle = main_axes_object.plot(x_values,
                                        numpy.mean(mse_skill_score_matrix,
                                                   axis=1),
                                        color=MSE_SKILL_COLOUR,
                                        linewidth=LINE_WIDTH,
                                        marker=MARKER_TYPE,
                                        markersize=MARKER_SIZE,
                                        markerfacecolor=MSE_SKILL_COLOUR,
                                        markeredgecolor=MSE_SKILL_COLOUR,
                                        markeredgewidth=0)[0]

    legend_handles.append(this_handle)
    legend_strings.append('MSE skill score')

    # Plot confidence interval for MSE skill score.
    if num_bootstrap_reps > 1 and confidence_level is not None:
        polygon_coord_matrix = evaluation.confidence_interval_to_polygon(
            x_value_matrix=numpy.expand_dims(x_values, axis=-1),
            y_value_matrix=mse_skill_score_matrix,
            confidence_level=confidence_level,
            same_order=True)

        if polygon_coord_matrix is not None:
            polygon_colour = matplotlib.colors.to_rgba(MSE_SKILL_COLOUR,
                                                       POLYGON_OPACITY)
            patch_object = matplotlib.patches.Polygon(polygon_coord_matrix,
                                                      lw=0,
                                                      ec=polygon_colour,
                                                      fc=polygon_colour)
            main_axes_object.add_patch(patch_object)

    # Plot mean correlation.
    this_handle = main_axes_object.plot(x_values,
                                        numpy.mean(correlation_matrix, axis=1),
                                        color=CORRELATION_COLOUR,
                                        linewidth=LINE_WIDTH,
                                        marker=MARKER_TYPE,
                                        markersize=MARKER_SIZE,
                                        markerfacecolor=CORRELATION_COLOUR,
                                        markeredgecolor=CORRELATION_COLOUR,
                                        markeredgewidth=0)[0]

    legend_handles.append(this_handle)
    legend_strings.append('Correlation')

    # Plot confidence interval for correlation.
    if num_bootstrap_reps > 1 and confidence_level is not None:
        polygon_coord_matrix = evaluation.confidence_interval_to_polygon(
            x_value_matrix=numpy.expand_dims(x_values, axis=-1),
            y_value_matrix=correlation_matrix,
            confidence_level=confidence_level,
            same_order=True)

        if polygon_coord_matrix is not None:
            polygon_colour = matplotlib.colors.to_rgba(CORRELATION_COLOUR,
                                                       POLYGON_OPACITY)
            patch_object = matplotlib.patches.Polygon(polygon_coord_matrix,
                                                      lw=0,
                                                      ec=polygon_colour,
                                                      fc=polygon_colour)
            main_axes_object.add_patch(patch_object)

    # Plot mean KGE.
    this_handle = main_axes_object.plot(x_values,
                                        numpy.mean(kge_matrix, axis=1),
                                        color=KGE_COLOUR,
                                        linewidth=LINE_WIDTH,
                                        marker=MARKER_TYPE,
                                        markersize=MARKER_SIZE,
                                        markerfacecolor=KGE_COLOUR,
                                        markeredgecolor=KGE_COLOUR,
                                        markeredgewidth=0)[0]

    legend_handles.append(this_handle)
    legend_strings.append('KGE')

    # Plot confidence interval for KGE.
    if num_bootstrap_reps > 1 and confidence_level is not None:
        polygon_coord_matrix = evaluation.confidence_interval_to_polygon(
            x_value_matrix=numpy.expand_dims(x_values, axis=-1),
            y_value_matrix=kge_matrix,
            confidence_level=confidence_level,
            same_order=True)

        if polygon_coord_matrix is not None:
            polygon_colour = matplotlib.colors.to_rgba(KGE_COLOUR,
                                                       POLYGON_OPACITY)
            patch_object = matplotlib.patches.Polygon(polygon_coord_matrix,
                                                      lw=0,
                                                      ec=polygon_colour,
                                                      fc=polygon_colour)
            main_axes_object.add_patch(patch_object)

    y_min, y_max = main_axes_object.get_ylim()
    y_min = numpy.maximum(y_min, -1.)
    y_max = numpy.minimum(y_max, 1.)
    main_axes_object.set_ylim(y_min, y_max)

    main_axes_object.set_xticks(x_values)
    main_axes_object.set_xlim(
        numpy.min(x_values) - 0.5,
        numpy.max(x_values) + 0.5)

    # Plot histogram of example counts.
    y_values = numpy.maximum(numpy.log10(num_examples_array), 0.)

    histogram_axes_object.bar(x=x_values,
                              height=y_values,
                              width=1.,
                              color=HISTOGRAM_FACE_COLOUR,
                              edgecolor=HISTOGRAM_EDGE_COLOUR,
                              linewidth=HISTOGRAM_EDGE_WIDTH)
    histogram_axes_object.set_ylabel('Number of examples')

    tick_values = histogram_axes_object.get_yticks()
    tick_strings = [
        '{0:d}'.format(int(numpy.round(10**v))) for v in tick_values
    ]
    histogram_axes_object.set_yticklabels(tick_strings)

    print('Number of examples by chunk: {0:s}'.format(str(num_examples_array)))

    if plot_legend:
        main_axes_object.legend(legend_handles,
                                legend_strings,
                                loc='lower right',
                                bbox_to_anchor=(1, 0),
                                fancybox=True,
                                shadow=False,
                                facecolor='white',
                                edgecolor='k',
                                framealpha=0.5,
                                ncol=1)

    return figure_object, main_axes_object
Пример #3
0
def _plot_score_profile(evaluation_tables_xarray, line_styles, line_colours,
                        set_descriptions_verbose, confidence_level,
                        target_name, score_name, use_log_scale,
                        output_dir_name):
    """Plots vertical profile of one score.

    :param evaluation_tables_xarray: See doc for `_plot_attributes_diagram`.
    :param line_styles: Same.
    :param line_colours: Same.
    :param set_descriptions_verbose: Same.
    :param confidence_level: Same.
    :param target_name: Name of target variable for which score is being plotted.
    :param score_name: Name of score being plotted.
    :param use_log_scale: Boolean flag.  If True, will plot heights (y-axis) in
        log scale.
    :param output_dir_name: Name of output directory.  Figure will be saved
        here.
    """

    target_indices = numpy.array([
        numpy.where(
            t.coords[evaluation.VECTOR_FIELD_DIM].values == target_name)[0][0]
        for t in evaluation_tables_xarray
    ],
                                 dtype=int)

    figure_object, axes_object = pyplot.subplots(
        1, 1, figsize=(FIGURE_WIDTH_INCHES, FIGURE_HEIGHT_INCHES))

    score_key = SCORE_NAME_TO_PROFILE_KEY[score_name]
    legend_handles = []
    legend_strings = []
    num_evaluation_sets = len(evaluation_tables_xarray)

    for i in range(num_evaluation_sets):
        k = target_indices[i]
        t = evaluation_tables_xarray[i]

        this_score_matrix = t[score_key].values[:, k, :]
        heights_m_agl = t.coords[evaluation.HEIGHT_DIM].values

        this_handle = evaluation_plotting.plot_score_profile(
            heights_m_agl=heights_m_agl,
            score_values=numpy.nanmean(this_score_matrix, axis=1),
            score_name=score_name,
            line_colour=line_colours[i],
            line_width=4,
            line_style=line_styles[i],
            use_log_scale=use_log_scale,
            axes_object=axes_object,
            are_axes_new=i == 0)

        legend_handles.append(this_handle)
        legend_strings.append(set_descriptions_verbose[i])

        num_bootstrap_reps = this_score_matrix.shape[1]

        if num_bootstrap_reps > 1 and confidence_level is not None:
            polygon_coord_matrix = evaluation.confidence_interval_to_polygon(
                x_value_matrix=numpy.expand_dims(heights_m_agl, axis=-1),
                y_value_matrix=this_score_matrix,
                confidence_level=confidence_level,
                same_order=True)

            polygon_coord_matrix = numpy.fliplr(polygon_coord_matrix)
            polygon_coord_matrix[:, 1] = (polygon_coord_matrix[:, 1] *
                                          METRES_TO_KM)

            polygon_colour = matplotlib.colors.to_rgba(line_colours[i],
                                                       POLYGON_OPACITY)
            patch_object = matplotlib.patches.Polygon(polygon_coord_matrix,
                                                      lw=0,
                                                      ec=polygon_colour,
                                                      fc=polygon_colour)
            axes_object.add_patch(patch_object)

    if len(legend_handles) > 1:
        axes_object.legend(legend_handles,
                           legend_strings,
                           loc='center left',
                           bbox_to_anchor=(0, 0.5),
                           fancybox=True,
                           shadow=False,
                           facecolor='white',
                           edgecolor='k',
                           framealpha=0.5,
                           ncol=1)

    title_string = '{0:s} for {1:s}'.format(
        SCORE_NAME_TO_VERBOSE[score_name], TARGET_NAME_TO_VERBOSE[target_name])

    x_label_string = '{0:s}'.format(SCORE_NAME_TO_VERBOSE[score_name])

    if score_name in SQUARED_UNIT_SCORE_NAMES:
        x_label_string += ' ({0:s})'.format(
            TARGET_NAME_TO_SQUARED_UNITS[target_name])
    elif score_name in ORIG_UNIT_SCORE_NAMES:
        x_label_string += ' ({0:s})'.format(TARGET_NAME_TO_UNITS[target_name])

    axes_object.set_xlabel(x_label_string)
    axes_object.set_title(title_string)

    figure_file_name = '{0:s}/{1:s}_{2:s}_profile.jpg'.format(
        output_dir_name, target_name.replace('_', '-'),
        score_name.replace('_', '-'))

    print('Saving figure to: "{0:s}"...'.format(figure_file_name))
    figure_object.savefig(figure_file_name,
                          dpi=FIGURE_RESOLUTION_DPI,
                          pad_inches=0,
                          bbox_inches='tight')
    pyplot.close(figure_object)
Пример #4
0
def _plot_scores_with_units(mae_matrix, rmse_matrix, bias_matrix,
                            target_matrices, plot_legend, confidence_level):
    """Plots scores with physical units, for one time split and one field.

    B = number of bootstrap replicates
    T = number of time chunks

    :param mae_matrix: T-by-B numpy array of MAE (mean absolute error) values.
    :param rmse_matrix: T-by-B numpy array of RMSE (root mean squared error)
        values.
    :param bias_matrix: T-by-B numpy array of biases.
    :param target_matrices: length-T list of numpy arrays.  The [i]th array has
        length E_i, where E_i = number of examples for [i]th time chunk.
    :param plot_legend: Boolean flag.  If True, will plot legend above figure.
    :param confidence_level: See documentation at top of file.
    :return: figure_object: Figure handle (instance of
        `matplotlib.figure.Figure`).
    :return: axes_object: Axes handle (instance of
        `matplotlib.axes._subplots.AxesSubplot`).
    """

    # Housekeeping.
    figure_object, axes_object = pyplot.subplots(
        1, 1, figsize=(FIGURE_WIDTH_INCHES, FIGURE_HEIGHT_INCHES))

    num_time_chunks = mae_matrix.shape[0]
    num_bootstrap_reps = mae_matrix.shape[1]

    x_values = numpy.linspace(0,
                              num_time_chunks - 1,
                              num=num_time_chunks,
                              dtype=float)

    # Plot boxplots.
    boxplot_style_dict = {'color': 'k', 'linewidth': 2}

    legend_handles = []
    legend_strings = []

    for i in range(num_time_chunks):
        this_dict = axes_object.boxplot(target_matrices[i],
                                        widths=1.,
                                        notch=False,
                                        sym='',
                                        whis=(5, 95),
                                        medianprops=boxplot_style_dict,
                                        boxprops=boxplot_style_dict,
                                        whiskerprops=boxplot_style_dict,
                                        capprops=boxplot_style_dict,
                                        positions=x_values[[i]])

        if i != 0:
            continue

        legend_handles.append(this_dict['boxes'][0])
        legend_strings.append('Boxplot of\nactual values')

    # Plot reference line.
    axes_object.plot(axes_object.get_xlim(),
                     numpy.full(2, 0.),
                     color=REFERENCE_LINE_COLOUR,
                     linewidth=REFERENCE_LINE_WIDTH,
                     linestyle='dashed')

    # Plot mean MAE.
    this_handle = axes_object.plot(x_values,
                                   numpy.mean(mae_matrix, axis=1),
                                   color=MAE_COLOUR,
                                   linewidth=LINE_WIDTH,
                                   marker=MARKER_TYPE,
                                   markersize=MARKER_SIZE,
                                   markerfacecolor=MAE_COLOUR,
                                   markeredgecolor=MAE_COLOUR,
                                   markeredgewidth=0)[0]

    legend_handles.append(this_handle)
    legend_strings.append('MAE')

    # Plot confidence interval for MAE.
    if num_bootstrap_reps > 1 and confidence_level is not None:
        polygon_coord_matrix = evaluation.confidence_interval_to_polygon(
            x_value_matrix=numpy.expand_dims(x_values, axis=-1),
            y_value_matrix=mae_matrix,
            confidence_level=confidence_level,
            same_order=True)

        if polygon_coord_matrix is not None:
            polygon_colour = matplotlib.colors.to_rgba(MAE_COLOUR,
                                                       POLYGON_OPACITY)
            patch_object = matplotlib.patches.Polygon(polygon_coord_matrix,
                                                      lw=0,
                                                      ec=polygon_colour,
                                                      fc=polygon_colour)
            axes_object.add_patch(patch_object)

    # Plot mean RMSE.
    this_handle = axes_object.plot(x_values,
                                   numpy.mean(rmse_matrix, axis=1),
                                   color=RMSE_COLOUR,
                                   linewidth=LINE_WIDTH,
                                   marker=MARKER_TYPE,
                                   markersize=MARKER_SIZE,
                                   markerfacecolor=RMSE_COLOUR,
                                   markeredgecolor=RMSE_COLOUR,
                                   markeredgewidth=0)[0]

    legend_handles.append(this_handle)
    legend_strings.append('RMSE')

    # Plot confidence interval for RMSE.
    if num_bootstrap_reps > 1 and confidence_level is not None:
        polygon_coord_matrix = evaluation.confidence_interval_to_polygon(
            x_value_matrix=numpy.expand_dims(x_values, axis=-1),
            y_value_matrix=rmse_matrix,
            confidence_level=confidence_level,
            same_order=True)

        if polygon_coord_matrix is not None:
            polygon_colour = matplotlib.colors.to_rgba(RMSE_COLOUR,
                                                       POLYGON_OPACITY)
            patch_object = matplotlib.patches.Polygon(polygon_coord_matrix,
                                                      lw=0,
                                                      ec=polygon_colour,
                                                      fc=polygon_colour)
            axes_object.add_patch(patch_object)

    # Plot mean bias.
    this_handle = axes_object.plot(x_values,
                                   numpy.mean(bias_matrix, axis=1),
                                   color=BIAS_COLOUR,
                                   linewidth=LINE_WIDTH,
                                   marker=MARKER_TYPE,
                                   markersize=MARKER_SIZE,
                                   markerfacecolor=BIAS_COLOUR,
                                   markeredgecolor=BIAS_COLOUR,
                                   markeredgewidth=0)[0]

    legend_handles.append(this_handle)
    legend_strings.append('Bias')

    # Plot confidence interval for bias.
    if num_bootstrap_reps > 1 and confidence_level is not None:
        polygon_coord_matrix = evaluation.confidence_interval_to_polygon(
            x_value_matrix=numpy.expand_dims(x_values, axis=-1),
            y_value_matrix=bias_matrix,
            confidence_level=confidence_level,
            same_order=True)

        if polygon_coord_matrix is not None:
            polygon_colour = matplotlib.colors.to_rgba(BIAS_COLOUR,
                                                       POLYGON_OPACITY)
            patch_object = matplotlib.patches.Polygon(polygon_coord_matrix,
                                                      lw=0,
                                                      ec=polygon_colour,
                                                      fc=polygon_colour)
            axes_object.add_patch(patch_object)

    axes_object.set_xticks(x_values)
    axes_object.set_xlim(numpy.min(x_values) - 0.5, numpy.max(x_values) + 0.5)

    if plot_legend:
        axes_object.legend(legend_handles,
                           legend_strings,
                           loc='upper right',
                           bbox_to_anchor=(1, 1),
                           fancybox=True,
                           shadow=False,
                           facecolor='white',
                           edgecolor='k',
                           framealpha=0.5,
                           ncol=1)

    return figure_object, axes_object
Пример #5
0
def _plot_attributes_diagram(evaluation_tables_xarray,
                             line_styles,
                             line_colours,
                             set_descriptions_abbrev,
                             set_descriptions_verbose,
                             confidence_level,
                             mean_training_example_dict,
                             target_name,
                             output_dir_name,
                             height_m_agl=None):
    """Plots attributes diagram for each set and each target variable.

    S = number of evaluation sets
    T_v = number of vector target variables
    T_s = number of scalar target variables
    H = number of heights

    :param evaluation_tables_xarray: length-S list of xarray tables in format
        returned by `evaluation.read_file`.
    :param line_styles: length-S list of line styles.
    :param line_colours: length-S list of line colours.
    :param set_descriptions_abbrev: length-S list of abbreviated descriptions
        for evaluation sets.
    :param set_descriptions_verbose: length-S list of verbose descriptions for
        evaluation sets.
    :param confidence_level: See documentation at top of file.
    :param mean_training_example_dict: Dictionary created by
        `normalization.create_mean_example`.
    :param target_name: Name of target variable.
    :param output_dir_name: Name of output directory.  Figures will be saved
        here.
    :param height_m_agl: Height (metres above ground level).
    """

    t = evaluation_tables_xarray[0]
    is_scalar = target_name in t.coords[evaluation.SCALAR_FIELD_DIM].values
    is_aux = target_name in t.coords[evaluation.AUX_TARGET_FIELD_DIM].values
    is_vector = target_name in t.coords[evaluation.VECTOR_FIELD_DIM].values

    if is_scalar:
        target_indices = numpy.array([
            numpy.where(t.coords[evaluation.SCALAR_FIELD_DIM].values ==
                        target_name)[0][0] for t in evaluation_tables_xarray
        ],
                                     dtype=int)

        mean_predictions_by_set = [
            t[evaluation.SCALAR_RELIABILITY_X_KEY].values[k, ...]
            for t, k in zip(evaluation_tables_xarray, target_indices)
        ]
        mean_observations_by_set = [
            t[evaluation.SCALAR_RELIABILITY_Y_KEY].values[k, ...]
            for t, k in zip(evaluation_tables_xarray, target_indices)
        ]
        bin_centers_by_set = [
            t[evaluation.SCALAR_RELIA_BIN_CENTER_KEY].values[k, ...]
            for t, k in zip(evaluation_tables_xarray, target_indices)
        ]
        example_counts_by_set = [
            t[evaluation.SCALAR_RELIABILITY_COUNT_KEY].values[k, ...]
            for t, k in zip(evaluation_tables_xarray, target_indices)
        ]
        inverted_bin_centers_by_set = [
            t[evaluation.SCALAR_INV_RELIA_BIN_CENTER_KEY].values[k, ...]
            for t, k in zip(evaluation_tables_xarray, target_indices)
        ]
        inverted_example_counts_by_set = [
            t[evaluation.SCALAR_INV_RELIABILITY_COUNT_KEY].values[k, ...]
            for t, k in zip(evaluation_tables_xarray, target_indices)
        ]

        k = mean_training_example_dict[
            example_utils.SCALAR_TARGET_NAMES_KEY].index(target_name)

        climo_value = mean_training_example_dict[
            example_utils.SCALAR_TARGET_VALS_KEY][0, k]

    elif is_aux:
        target_indices = numpy.array([
            numpy.where(t.coords[evaluation.AUX_TARGET_FIELD_DIM].values ==
                        target_name)[0][0] for t in evaluation_tables_xarray
        ],
                                     dtype=int)

        mean_predictions_by_set = [
            t[evaluation.AUX_RELIABILITY_X_KEY].values[k, ...]
            for t, k in zip(evaluation_tables_xarray, target_indices)
        ]
        mean_observations_by_set = [
            t[evaluation.AUX_RELIABILITY_Y_KEY].values[k, ...]
            for t, k in zip(evaluation_tables_xarray, target_indices)
        ]
        bin_centers_by_set = [
            t[evaluation.AUX_RELIA_BIN_CENTER_KEY].values[k, ...]
            for t, k in zip(evaluation_tables_xarray, target_indices)
        ]
        example_counts_by_set = [
            t[evaluation.AUX_RELIABILITY_COUNT_KEY].values[k, ...]
            for t, k in zip(evaluation_tables_xarray, target_indices)
        ]
        inverted_bin_centers_by_set = [
            t[evaluation.AUX_INV_RELIA_BIN_CENTER_KEY].values[k, ...]
            for t, k in zip(evaluation_tables_xarray, target_indices)
        ]
        inverted_example_counts_by_set = [
            t[evaluation.AUX_INV_RELIABILITY_COUNT_KEY].values[k, ...]
            for t, k in zip(evaluation_tables_xarray, target_indices)
        ]

        training_target_names = mean_training_example_dict[
            example_utils.SCALAR_TARGET_NAMES_KEY]
        training_target_matrix = mean_training_example_dict[
            example_utils.SCALAR_TARGET_VALS_KEY]

        if target_name == evaluation.NET_FLUX_NAME:
            down_flux_index = training_target_names.index(
                example_utils.SHORTWAVE_SURFACE_DOWN_FLUX_NAME)
            up_flux_index = training_target_names.index(
                example_utils.SHORTWAVE_TOA_UP_FLUX_NAME)
            climo_value = (training_target_matrix[0, down_flux_index] -
                           training_target_matrix[0, up_flux_index])
        else:
            k = training_target_names.index(target_name)
            climo_value = training_target_matrix[0, k]
    else:
        target_indices = numpy.array([
            numpy.where(t.coords[evaluation.VECTOR_FIELD_DIM].values ==
                        target_name)[0][0] for t in evaluation_tables_xarray
        ],
                                     dtype=int)

        height_indices = numpy.array([
            numpy.argmin(
                numpy.absolute(t.coords[evaluation.HEIGHT_DIM].values -
                               height_m_agl)) for t in evaluation_tables_xarray
        ],
                                     dtype=int)

        mean_predictions_by_set = [
            t[evaluation.VECTOR_RELIABILITY_X_KEY].values[j, k, ...] for t, j,
            k in zip(evaluation_tables_xarray, height_indices, target_indices)
        ]
        mean_observations_by_set = [
            t[evaluation.VECTOR_RELIABILITY_Y_KEY].values[j, k, ...] for t, j,
            k in zip(evaluation_tables_xarray, height_indices, target_indices)
        ]
        bin_centers_by_set = [
            t[evaluation.VECTOR_RELIA_BIN_CENTER_KEY].values[j, k, ...]
            for t, j, k in zip(evaluation_tables_xarray, height_indices,
                               target_indices)
        ]
        example_counts_by_set = [
            t[evaluation.VECTOR_RELIABILITY_COUNT_KEY].values[j, k, ...]
            for t, j, k in zip(evaluation_tables_xarray, height_indices,
                               target_indices)
        ]
        inverted_bin_centers_by_set = [
            t[evaluation.VECTOR_INV_RELIA_BIN_CENTER_KEY].values[j, k, ...]
            for t, j, k in zip(evaluation_tables_xarray, height_indices,
                               target_indices)
        ]
        inverted_example_counts_by_set = [
            t[evaluation.VECTOR_INV_RELIABILITY_COUNT_KEY].values[j, k, ...]
            for t, j, k in zip(evaluation_tables_xarray, height_indices,
                               target_indices)
        ]

        j = numpy.argmin(
            numpy.absolute(
                mean_training_example_dict[example_utils.HEIGHTS_KEY] -
                height_m_agl))

        k = mean_training_example_dict[
            example_utils.VECTOR_TARGET_NAMES_KEY].index(target_name)

        climo_value = mean_training_example_dict[
            example_utils.VECTOR_TARGET_VALS_KEY][0, j, k]

    concat_values = numpy.concatenate([
        numpy.nanmean(a, axis=-1)
        for a in mean_predictions_by_set + mean_observations_by_set
        if a is not None
    ])
    max_value_to_plot = numpy.nanpercentile(concat_values, 99.9)
    min_value_to_plot = numpy.nanpercentile(concat_values, 0.1)
    min_value_to_plot = numpy.minimum(min_value_to_plot, 0.)

    num_evaluation_sets = len(evaluation_tables_xarray)

    for main_index in range(num_evaluation_sets):
        figure_object, axes_object = pyplot.subplots(
            1, 1, figsize=(FIGURE_WIDTH_INCHES, FIGURE_HEIGHT_INCHES))

        legend_handles = []
        legend_strings = []

        this_handle = evaluation_plotting.plot_attributes_diagram(
            figure_object=figure_object,
            axes_object=axes_object,
            mean_predictions=numpy.nanmean(mean_predictions_by_set[main_index],
                                           axis=-1),
            mean_observations=numpy.nanmean(
                mean_observations_by_set[main_index], axis=-1),
            mean_value_in_training=climo_value,
            min_value_to_plot=min_value_to_plot,
            max_value_to_plot=max_value_to_plot,
            line_colour=line_colours[main_index],
            line_style=line_styles[main_index],
            line_width=4)

        if this_handle is not None:
            legend_handles.append(this_handle)
            legend_strings.append(set_descriptions_verbose[main_index])

        num_bootstrap_reps = mean_predictions_by_set[main_index].shape[1]

        if num_bootstrap_reps > 1 and confidence_level is not None:
            polygon_coord_matrix = evaluation.confidence_interval_to_polygon(
                x_value_matrix=mean_predictions_by_set[main_index],
                y_value_matrix=mean_observations_by_set[main_index],
                confidence_level=confidence_level,
                same_order=False)

            polygon_colour = matplotlib.colors.to_rgba(
                line_colours[main_index], POLYGON_OPACITY)
            patch_object = matplotlib.patches.Polygon(polygon_coord_matrix,
                                                      lw=0,
                                                      ec=polygon_colour,
                                                      fc=polygon_colour)
            axes_object.add_patch(patch_object)

        evaluation_plotting.plot_inset_histogram(
            figure_object=figure_object,
            bin_centers=bin_centers_by_set[main_index],
            bin_counts=example_counts_by_set[main_index],
            has_predictions=True,
            bar_colour=line_colours[main_index])

        evaluation_plotting.plot_inset_histogram(
            figure_object=figure_object,
            bin_centers=inverted_bin_centers_by_set[main_index],
            bin_counts=inverted_example_counts_by_set[main_index],
            has_predictions=False,
            bar_colour=line_colours[main_index])

        axes_object.set_xlabel('Prediction ({0:s})'.format(
            TARGET_NAME_TO_UNITS[target_name]))
        axes_object.set_ylabel('Conditional mean observation ({0:s})'.format(
            TARGET_NAME_TO_UNITS[target_name]))

        title_string = 'Attributes diagram for {0:s}'.format(
            TARGET_NAME_TO_VERBOSE[target_name])
        if is_vector:
            title_string += ' at {0:d} m AGL'.format(
                int(numpy.round(height_m_agl)))

        axes_object.set_title(title_string)

        for i in range(num_evaluation_sets):
            if i == main_index:
                continue

            this_handle = evaluation_plotting._plot_reliability_curve(
                axes_object=axes_object,
                mean_predictions=numpy.nanmean(mean_predictions_by_set[i],
                                               axis=-1),
                mean_observations=numpy.nanmean(mean_observations_by_set[i],
                                                axis=-1),
                min_value_to_plot=min_value_to_plot,
                max_value_to_plot=max_value_to_plot,
                line_colour=line_colours[i],
                line_style=line_styles[i],
                line_width=4)

            if this_handle is not None:
                legend_handles.append(this_handle)
                legend_strings.append(set_descriptions_verbose[i])

            num_bootstrap_reps = mean_predictions_by_set[i].shape[1]

            if num_bootstrap_reps > 1 and confidence_level is not None:
                polygon_coord_matrix = (
                    evaluation.confidence_interval_to_polygon(
                        x_value_matrix=mean_predictions_by_set[i],
                        y_value_matrix=mean_observations_by_set[i],
                        confidence_level=confidence_level,
                        same_order=False))

                polygon_colour = matplotlib.colors.to_rgba(
                    line_colours[i], POLYGON_OPACITY)
                patch_object = matplotlib.patches.Polygon(polygon_coord_matrix,
                                                          lw=0,
                                                          ec=polygon_colour,
                                                          fc=polygon_colour)
                axes_object.add_patch(patch_object)

        if len(legend_handles) > 1:
            axes_object.legend(legend_handles,
                               legend_strings,
                               loc='center left',
                               bbox_to_anchor=(0, 0.35),
                               fancybox=True,
                               shadow=False,
                               facecolor='white',
                               edgecolor='k',
                               framealpha=0.5,
                               ncol=1)

        figure_file_name = '{0:s}/{1:s}'.format(output_dir_name,
                                                target_name.replace('_', '-'))

        if is_vector:
            figure_file_name += '_{0:05d}m-agl'.format(
                int(numpy.round(height_m_agl)))

        figure_file_name += '_attributes_{0:s}.jpg'.format(
            set_descriptions_abbrev[main_index])

        print('Saving figure to: "{0:s}"...'.format(figure_file_name))
        figure_object.savefig(figure_file_name,
                              dpi=FIGURE_RESOLUTION_DPI,
                              pad_inches=0,
                              bbox_inches='tight')
        pyplot.close(figure_object)