def show_profile(self, var_key, coord_key, loc_list):
        """
        Display profile along coordinate for any variable
        :param coord_key: Varying coordinate x or y.
        :param loc_list: Location of fixed coordinate.
        :param var_key: Variable to display on the profile.
        :return: void.
        """

        # Horizontal profile
        if coord_key == 'x':
            xlabel = coord_key
            ylabel = var_key

        # Vertical profile
        elif coord_key == 'y':
            xlabel = var_key
            ylabel = coord_key

        else:
            xlabel = 'error'
            ylabel = 'error'
            assert (coord_key == 'x' or coord_key == 'y'), 'Invalid key for coordinates, ' \
                                                           'must be x or y instead: %r' % coord_key

        # Get data for requested profile
        profile_data = get_profile_data(self, var_key, coord_key, loc_list)

        # Plot the profile
        plot.lining(*profile_data,
                    xlabel=xlabel,
                    ylabel=ylabel,
                    title=self.case_name,
                    line_label=var_key + ' at y = ' + str(loc_list))
        return
    def show_geometry(self):
        """
        Plot the geometry for the given case using a Line2D.
        :return: figure and axis object for the plot.
        """

        # Get points on the boundaries
        boundaries = get_boundaries(self)

        # Configure the plot
        xlim = [np.min(self.flow_dict['x']), np.max(self.flow_dict['x'])]
        ylim = [np.min(self.flow_dict['y']), np.max(self.flow_dict['y'])]
        linestyle = '-k'  # Solid black line

        # Plot boundaries
        fig, ax = plot.empty_plot()
        for boundary in boundaries:
            plot.lining(*boundary,
                        linestyle=linestyle,
                        xlim=xlim,
                        ylim=ylim,
                        append_to_fig_ax=(fig, ax))

        return fig, ax
Example #3
0
# compare_profiles('pm', 'x', 0, *hifi_data)
#
# # Fig 27 (a), (c)
# compare_profiles('um', 'y', 4, *hifi_data, xlim=[-0.2, 1.2], ylim=[-0.1, 3.1])
# compare_profiles('uu', 'y', 4, *hifi_data, xlim=[0, 0.1], ylim=[-0.1, 3.1])
#
# # Fig 23, tiny separation bubble
# hifi_data[3].show_flow('um', contour_level=[-0.1, 0, 0.1, 0.2, 0.3], xlim=[0.55, 0.93], ylim=[0.58, 0.82])
#
# # Fig 24, tiny recirculation bubble
# hifi_data[2].show_flow('um', contour_level=[-0.1, 0, 0.1, 0.2, 0.3], xlim=[6.9, 7.5], ylim=[-0.01, 0.31])
#
# # Fig 29, tke comparison
# hifi_data[0].show_flow('k', contour=False)
# hifi_data[-1].show_flow('k', contour=False)

# Fig 30, lumley triangles with invariants
loc = 4
p_IIb = get_profile_data(hifi_data[0], 'IIb', 'y', loc)
p_IIIb = get_profile_data(hifi_data[0], 'IIIb', 'y', loc)

p2_IIb = get_profile_data(hifi_data[-1], 'IIb', 'y', loc)
p2_IIIb = get_profile_data(hifi_data[-1], 'IIIb', 'y', loc)

fig, ax = empty_plot()
lining(p_IIIb[0][221:-1], p_IIb[0][221:-1], xlim=[-0.03, 0.09], ylim=[0, 0.41], append_to_fig_ax=(fig, ax), linestyle='-s')
lining(p2_IIIb[0][221:-1], p2_IIb[0][221:-1], xlim=[-0.03, 0.09], ylim=[0, 0.41], append_to_fig_ax=(fig, ax))


show()
def receiver_operating_characteristic(configuration):
    # Get all models
    filenames = find_results()
    test_sets = ['PH-Breuer', 'PH-Xiao', 'CBFS', 'TBL-APG', 'NACA']
    algorithms = ["logReg", "spaRTA"]

    f1_bests = []
    tpr_bests = []
    fpr_bests = []
    pbests = []
    f1_highs = []
    tpr_highs = []
    fpr_highs = []
    prc_highs = []
    phighs = []

    for algorithm in algorithms:
        result_names = [
            get_single_result_name(filenames,
                                   [algorithm] + configuration[1:-1] +
                                   [test_set_i.replace('-', '_')])
            for test_set_i in test_sets
        ]

        if config[2] == "non_negative":
            if algorithm == "logReg":
                highlight = [10, 10, 40, 10, 10]  # LogReg nut
            else:
                highlight = [26, 29, 27, 29, 3]  # SpaRTA nut
        else:
            if algorithm == "logReg":
                highlight = [23, 43, 32, 2, 2]  # LogReg II
            else:
                highlight = [90, 1, 2, 1, 1]  # SpaRTA II

        for name, high in zip(result_names, highlight):
            df_quant = pd.read_csv("./results/" + name + "/quantitative.csv")

            tprs = df_quant['tpr_test'].to_list()
            fprs = df_quant['fpr_test'].to_list()
            prcs = df_quant['prc_test'].to_list()
            f1s = df_quant['f1_test'].to_list()

            # Best model
            idx_best = f1s.index(np.sort(f1s)[-1])
            # tpr_bests.append(np.sort(tprs)[-1])
            # idx_best = tprs.index(tpr_bests[-1])
            f1_bests.append(f1s[idx_best])
            tpr_bests.append(tprs[idx_best])
            fpr_bests.append(fprs[idx_best])
            pbests.append([fpr_bests[-1], tpr_bests[-1]])

            # Highlights
            f1_highs.append(f1s[high])
            tpr_highs.append(tprs[high])
            fpr_highs.append(fprs[high])
            prc_highs.append(prcs[high])
            phighs.append([fpr_highs[-1], tpr_highs[-1]])  # ROC
            # phighs.append([tpr_highs[-1], prc_highs[-1]])  # Precision-Recall curve

    # Total average performance
    total_logreg_best = np.mean(tpr_bests[:5]), np.mean(fpr_bests[:5])
    total_sparta_best = np.mean(tpr_bests[5:]), np.mean(fpr_bests[5:])
    total_logreg_high = np.mean(tpr_highs[:5]), np.mean(fpr_highs[:5])
    total_sparta_high = np.mean(tpr_highs[5:]), np.mean(fpr_highs[5:])

    print(
        f"Best model performance for Logistic Regression\nTPR, FPR:\t{total_logreg_best}"
    )
    print(f"Best model performance for SpaRTA\nTPR, FPR:\t{total_sparta_best}")
    print(
        f"Selected model performance for Logistic Regression\nTPR, FPR:\t{total_logreg_high}"
    )
    print(
        f"Selected model performance for SpaRTA\nTPR, FPR:\t{total_sparta_high}"
    )

    # Setup
    fig, ax = empty_plot(figwidth=latex_textwidth * 1.0)
    lining(
        [0, 1],
        [0, 1],
        linestyle='-k',
        # color=cblack,
        # xlim=[0.9, 1200],
        # ylim=[0.0, 1.01],
        # xlog=True,
        append_to_fig_ax=(fig, ax))

    legend_elements = []
    marker = cycle(['o', '^', 's', 'P', 'D'])
    fillstyles = ["full"] * 5 + ["left"] * 5
    colors = cycle(all_colors[:5])
    # for pbest, phigh, mark, fill, color, test_set_i in zip([total_logreg_high[::-1], total_sparta_high[::-1]], phighs, marker, fillstyles, colors, cycle([r'\textsf{Logistic Regression}', r'\textsf{SpaRTA}'])):
    for pbest, phigh, mark, fill, color, test_set_i in zip(
            pbests, phighs, marker, fillstyles, colors,
            cycle([
                r'\textsf{PH-Re}', r'\textsf{PH-Geo}', r'\textsf{CBFS}',
                r'\textsf{TBL-APG}', r'\textsf{NACA}'
            ])):
        # scattering(*pbest, 1,
        #            color=cred,
        #            marker=mark,
        #            scale=100,
        #            xlabel="FPR",
        #            ylabel="TPR",
        #            zorder=2.5,
        #            append_to_fig_ax=(fig, ax))

        lining(
            *phigh,
            color=color,
            xlim=[0.0, 1.0],
            ylim=[0.0, 1.0],
            marker=mark,
            linestyle='-',
            markerfacecoloralt=cblack,
            markersize=10,
            markeredgecolor=cblack,
            fillstyle=fill,
            # xlabel="False-positive rate",
            # ylabel="True-positive rate",
            xlabel=r"$\textsf{FPR}=FP/(FP+TN)$",
            ylabel=r"$\textsf{TPR}=TP/(TP+FN)$",
            line_label="1",
            # zorder=2.5,
            append_to_fig_ax=(fig, ax))
        legend_elements.append(
            Line2D([0], [0],
                   marker=mark,
                   linestyle='-',
                   markerfacecoloralt=cblack,
                   markersize=10,
                   markeredgecolor=cblack,
                   markeredgewidth=1,
                   fillstyle=fill,
                   color=color,
                   label=test_set_i,
                   lw=0))

    # Legend
    ax.legend(handles=legend_elements[:5], loc="lower right", numpoints=1)
    ax.annotate("",
                xy=[0.55, 0.85],
                xytext=[0.7, 0.7],
                arrowprops=dict(fc='k', ec='k', arrowstyle="simple", lw=1.5))
    ax.annotate("",
                xy=[0.15, 0.45],
                xytext=[0.3, 0.3],
                arrowprops=dict(fc='k', ec='k', arrowstyle="simple", lw=1.5))
    ax.set_aspect("equal")

    # show()
    save("figures/" + "roc_" + str(emetric) + ".pdf")

    return 1
def performance_complexity(name, highlight_idx=None):
    df_quant = pd.read_csv("./results/" + name + "/quantitative.csv")
    complexitys = df_quant['complexity'].to_list()
    f1_tests = df_quant['f1_test'].to_list()

    f1_best = np.sort(f1_tests)[-1]
    idx_best = f1_tests.index(f1_best)
    complexity_best = complexitys[idx_best]
    print(
        f"Best model: {idx_best}\tF1: {f1_best}\t\tcomplexity: {complexity_best}"
    )

    # All models
    fig, ax = empty_plot(figwidth=latex_textwidth * 0.9)
    lining(complexitys,
           f1_tests,
           linestyle='o',
           marker='o',
           markeredgewidth=0,
           color=cgrey,
           xlim=[0.9, 1200],
           ylim=[0.0, 1.01],
           xlog=True,
           append_to_fig_ax=(fig, ax))

    # Best model
    scattering(complexity_best,
               f1_best,
               1,
               color=cred,
               marker='X',
               scale=100,
               xlabel="Model complexity",
               ylabel="F-measure",
               zorder=2.5,
               append_to_fig_ax=(fig, ax))

    sname_add = "_"

    # Highlights
    if isinstance(highlight_idx, int):
        highlight_idx = [highlight_idx]

    if isinstance(highlight_idx, list):
        for idx, color in zip(
                highlight_idx,
                cycle([corange, cyellow, cdarkred, clightyellow, cdarkred])):
            complexity_high = complexitys[idx]
            f1_high = f1_tests[idx]
            print(
                f"Highlight {idx} at:\tF1: {f1_high}\t\tcomplexity: {complexity_high}"
            )
            scattering(complexity_high,
                       f1_high,
                       1,
                       color=color,
                       scale=100,
                       marker='^',
                       xlabel="Model complexity",
                       ylabel="F-measure",
                       zorder=2.5,
                       append_to_fig_ax=(fig, ax))
        sname_add = "highlight_"

    legend_elements = [
        Line2D([0], [0],
               marker="X",
               linestyle='',
               lw=0,
               markersize=10,
               color=cred,
               label="Best"),
        Line2D([0], [0],
               marker="^",
               linestyle='',
               lw=0,
               markersize=10,
               color=corange,
               label="Algebraic")
    ]
    # Legend
    ax.legend(handles=legend_elements, loc="lower right", numpoints=1)

    # save("./results/" + name + "/figures/performance_vs_complexity" + sname_add + ".pdf")
    save("figures/" + "performance_vs_complexity_" + sname_add + str(algo) +
         "_" + str(scenario) + "_" + str(test_set.replace("-", "_")) + "_" +
         str(emetric) + "_" + ".pdf")
    # show()

    return idx_best
import numpy as np
import matplotlib.pyplot as plt
from itertools import cycle

from uncert_ident.utilities import TRUE_NEGATIVE, TRUE_POSITIVE, FALSE_NEGATIVE, FALSE_POSITIVE
from uncert_ident.visualisation.plotter import empty_plot, lining, scattering, \
    latex_textwidth, cblack, cgrey, cwhite, save, all_colors

fig, ax = empty_plot(figwidth=latex_textwidth)
lining([0, 1], [0, 1], linestyle='-k', append_to_fig_ax=(fig, ax))

points = [[0, 1], [1, 1], [0, 0], [0.44, 0.77], [0.22, 0.55]]

marker = cycle(['o', 'P', 's', '.', '.'])
# fillstyles = ["full"] * 5
# colors = cycle(all_colors[:5])
for point, mark in zip(points, marker):

    lining(
        *point,
        color=cblack,
        xlim=[0.0, 1.0],
        ylim=[0.0, 1.0],
        marker=mark,
        linestyle='-',
        markersize=20,
        xlabel="False-positive rate",
        ylabel="True-positive rate",
        # zorder=2.5,
        append_to_fig_ax=(fig, ax))
        'num_of_datasets': num_of_datasets
    }))

# Look at results both methods
print(df_rslt)

# Write results to csv
print("Finished bias-variance analysis for {0:s}, results in {1:s}".format(
    dataset, fname))

try:
    df_rslt.to_csv("results/{0}.csv".format(fname))
except Exception:
    df_rslt.to_csv("../results/{0}.csv".format(fname))

#####################################################################
### Plot results
#####################################################################
bias_variance_data = pd.read_csv("results/{0}.csv".format(fname))
n_data = np.unique(bias_variance_data.loc[:, 'num_of_datasets'].to_numpy())
n_datasets = n_data[-1]
tn_scores = bias_variance_data.loc[:, 'train_score'].to_numpy()
tt_scores = bias_variance_data.loc[:, 'test_score'].to_numpy()

# CHECK AVERAGING WITH PROPER VALUES
mean_tn_scores = np.mean(tn_scores.reshape(n_datasets, n_datasets + 1), axis=1)
mean_tt_scores = np.mean(tt_scores.reshape(n_datasets, n_datasets + 1), axis=1)

plot.lining(np.arange(n_datasets) + 1, mean_tn_scores)
plot.lining(np.arange(n_datasets) + 1, mean_tt_scores)
def compare_integral_quantity(var_key,
                              coord_key,
                              *cases,
                              xlog=False,
                              ylog=False,
                              xlim=None,
                              ylim=None):
    """
    Compare an integral quantity along the given coordinate.
    :param ylim: List with shape [min_y, max_y]
    :param xlim: List with shape [min_x, max_x]
    :param ylog: Option for log-scaled y-axis.
    :param xlog: Option for log-scaled x-axis.
    :param var_key: Key for an integral quantity.
    :param coord_key: Key for any coordinate.
    :return: 1: success.
    """

    # Generate figure and subplot
    fig, ax = plot.empty_plot()

    for case in cases:
        # For convenience
        coord = case.flow_dict[coord_key]
        var = case.flow_dict[var_key]
        nx = case.flow_dict['nx']
        ny = case.flow_dict['ny']

        if coord.shape == var.shape:
            plot.lining(coord,
                        var,
                        xlog=xlog,
                        ylog=ylog,
                        xlim=xlim,
                        ylim=ylim,
                        xlabel=coord_key,
                        ylabel=var_key,
                        line_label=case.case_name,
                        append_to_fig_ax=(fig, ax))

        elif coord_key == 'x':
            plot.lining(coord[::ny],
                        var,
                        xlog=xlog,
                        ylog=ylog,
                        xlim=xlim,
                        ylim=ylim,
                        xlabel=coord_key,
                        ylabel=var_key,
                        line_label=case.case_name,
                        append_to_fig_ax=(fig, ax))

        elif coord_key == 'y':
            plot.lining(coord[:ny],
                        var,
                        xlog=xlog,
                        ylog=ylog,
                        xlim=xlim,
                        ylim=ylim,
                        xlabel=coord_key,
                        ylabel=var_key,
                        line_label=case.case_name,
                        append_to_fig_ax=(fig, ax))

        else:
            assert False, 'Cannot print variable and coordinate: %r and %r' % (
                var_key, coord_key)

    return 1
def compare_profiles(var_key,
                     coord_key,
                     loc,
                     *cases,
                     var_scale=1,
                     xlim=None,
                     ylim=None,
                     xlog=False,
                     ylog=False,
                     append_to_fig_ax=(False, False)):
    """
    Compare a profile-plot setup between different flowCases.
    :param append_to_fig_ax: Append plot to another figure and axes.
    :param var_scale: Scaling factor for the variable.
    :param ylog: Optional logarithmic scale for y-axis.
    :param xlog: Optional logarithmic scale for x-axis.
    :param ylim: List with shape [min_y, max_y]
    :param xlim: List with shape [min_x, max_x]
    :param var_key: Any key within flowCase.flow_dict.
    :param coord_key: Varying coordinate.
    :param loc: Fixed location.
    :param cases: All flowCase objects.
    :return: Tuple of figure and axes.
    """

    # Generate new plot or append to given
    fig, ax = plot.check_append_to_fig_ax(append_to_fig_ax)

    for case in cases:
        profile_data = get_profile_data(case, var_key, coord_key, loc)

        # Horizontal profile
        if coord_key == 'x' or coord_key == 'y+':
            xlabel = coord_key
            ylabel = var_key
            scale_x = 1
            scale_y = var_scale

            # Vertical profile
        elif coord_key == 'y':
            xlabel = var_key
            ylabel = coord_key
            scale_x = var_scale
            scale_y = 1

        else:
            xlabel = 'error'
            ylabel = 'error'
            scale_x = 1
            scale_y = 1
            assert (coord_key == 'x' or coord_key == 'y'), 'Invalid key for coordinates, ' \
                                                           'must be x or y instead: %r' % coord_key

        plot.lining(*profile_data,
                    append_to_fig_ax=(fig, ax),
                    xlim=xlim,
                    ylim=ylim,
                    xlog=xlog,
                    ylog=ylog,
                    scale_x=scale_x,
                    scale_y=scale_y,
                    xlabel=xlabel,
                    ylabel=ylabel,
                    line_label=case.case_name)

    return fig, ax
    def show_integral_quantity(self,
                               var_key,
                               coord_key,
                               xlog=False,
                               ylog=False,
                               xlim=None,
                               ylim=None):
        """
        Plot an integral quantity along the given coordinate.
        :param ylim: List with shape [min_y, max_y]
        :param xlim: List with shape [min_x, max_x]
        :param ylog: Option for log-scaled y-axis.
        :param xlog: Option for log-scaled x-axis.
        :param var_key: Key for an integral quantity.
        :param coord_key: Key for any coordinate.
        :return: 1: success.
        """

        # For convenience
        coord = self.flow_dict[coord_key]
        var = self.flow_dict[var_key]
        nx = self.flow_dict['nx']
        ny = self.flow_dict['ny']

        if coord.shape == var.shape:
            plot.lining(coord,
                        var,
                        xlog=xlog,
                        ylog=ylog,
                        xlim=xlim,
                        ylim=ylim,
                        xlabel=coord_key,
                        ylabel=var_key,
                        line_label=None)
            return 1

        elif coord_key == 'x':
            plot.lining(coord[::ny],
                        var,
                        xlog=xlog,
                        ylog=ylog,
                        xlim=xlim,
                        ylim=ylim,
                        xlabel=coord_key,
                        ylabel=var_key,
                        line_label=None)
            return 1

        elif coord_key == 'y':
            plot.lining(coord[:ny],
                        var,
                        xlog=xlog,
                        ylog=ylog,
                        xlim=xlim,
                        ylim=ylim,
                        xlabel=coord_key,
                        ylabel=var_key,
                        line_label=None)
            return 1

        else:
            assert False, 'Cannot print variable and coordinate: %r and %r' % (
                var_key, coord_key)
    def show_label(self,
                   label_key='non_negative',
                   show_all=False,
                   show_geometry=True,
                   show_background=False,
                   labelpos='center',
                   only_positive=False,
                   zoom_box=False):
        """
        Display the labels in the physical coordinates.
        :param show_geometry: Print outline of the boundary.
        :param label_key: Key for the label (see utilities.py)
        :param show_all: Display all labels.
        :return: void.
        """

        if show_all:
            for key in self.label_dict:

                # Create figure
                fig, ax = plot.empty_plot(figwidth=plot.latex_textwidth)
                boundaries, xlabel, ylabel, title, xlim, ylim, mask, seeding = plot.get_geometry_plot_data(
                    self, return_seeding=True)

                plot.scattering(self.flow_dict['x'][~mask],
                                self.flow_dict['y'][~mask],
                                self.label_dict[key][~mask],
                                scale=10,
                                alpha=1.0,
                                title=key,
                                cmap=plot.confusion_cmap,
                                append_to_fig_ax=(fig, ax))

                # 2D Geometry outline
                if show_geometry:
                    for boundary in boundaries:
                        plot.lining(*boundary,
                                    linestyle='-',
                                    color=plot.cblack,
                                    append_to_fig_ax=(fig, ax))
                    plot.set_labels_title(ax, xlabel, ylabel, title)
                    plot.set_limits(ax, xlim=xlim, ylim=ylim)
                else:
                    fig, ax = plot.empty_plot(figwidth=plot.latex_textwidth)

                # Background flow
                if show_background:
                    nx, ny = self.nx, self.ny
                    X, Y = self.flow_dict['x'].reshape(
                        nx, ny), self.flow_dict['y'].reshape(nx, ny)
                    U, V = self.flow_dict['um'].reshape(
                        nx, ny), self.flow_dict['vm'].reshape(nx, ny)
                    if "NACA" in self.case_name:
                        pass
                    else:
                        plot.streams(ax,
                                     X,
                                     Y,
                                     U,
                                     V,
                                     start_points=seeding,
                                     color=plot.cblack)
                    pass

        else:
            assert (
                label_key in self.label_dict
            ), "label_key is not a valid key for labels: %r" % label_key

            # Create figure
            fig, ax = plot.empty_plot(figwidth=plot.latex_textwidth * 0.9)
            boundaries, xlabel, ylabel, title, xlim, ylim, mask, seeding = plot.get_geometry_plot_data(
                self, return_seeding=True)

            # plot.scattering(self.flow_dict['x'][~mask],
            #                 self.flow_dict['y'][~mask],
            #                 self.label_dict[label_key][~mask],
            #                 scale=10,
            #                 alpha=1.0,
            #                 cmap=plot.confusion_cmap,
            #                 append_to_fig_ax=(fig, ax))
            X, Y, LABEL = self.flow_dict['x'][~mask], self.flow_dict['y'][
                ~mask], self.label_dict[label_key][~mask]
            positive = LABEL == 1
            negative = LABEL == 0
            xs = [X[positive], X[negative]]
            ys = [Y[positive], Y[negative]]
            labels = [LABEL[positive], LABEL[negative]]
            zorders = [3, 2.9, 2.7, 2.8]
            if only_positive:
                xs = [xs[0]]
                ys = [ys[0]]
                labels = [labels[0]]
            for x, y, label, zorder in zip(xs, ys, labels, zorders):
                ax.scatter(x,
                           y,
                           s=10,
                           c=label,
                           cmap=plot.confusion_cmap,
                           vmin=0,
                           vmax=1,
                           zorder=zorder)

            # Background flow
            if show_background:
                nx, ny = self.nx, self.ny
                X, Y = self.flow_dict['x'].reshape(
                    nx, ny), self.flow_dict['y'].reshape(nx, ny)
                U, V = self.flow_dict['um'].reshape(
                    nx, ny), self.flow_dict['vm'].reshape(nx, ny)
                if "NACA" in self.case_name:
                    pass
                else:
                    plot.streams(ax,
                                 X,
                                 Y,
                                 U,
                                 V,
                                 start_points=seeding,
                                 color=plot.cgrey)
                pass

            # 2D Geometry outline
            if show_geometry:
                for boundary in boundaries:
                    plot.lining(*boundary,
                                linestyle='-',
                                color=plot.cblack,
                                append_to_fig_ax=(fig, ax))
                plot.set_labels_title(ax, xlabel, ylabel, title)
                plot.set_limits(ax, xlim=xlim, ylim=ylim)
            else:
                fig, ax = plot.empty_plot(figwidth=plot.latex_textwidth)

            # Legend
            labels = [
                r"\textsf{True-Positive}", r"\textsf{True-Negative}",
                r"\textsf{False-Positive}", r"\textsf{False-Negative}"
            ]
            # labels = ["Richtig-Positiv", "Richtig-Negativ", "Falsch-Positiv", "Falsch-Negativ"]
            label_values = [1, 0, 0.3, 0.7]

            cmap = plot.confusion_cmap
            clrs = cmap(label_values)

            legend_elements = list()
            for clr, label in zip(clrs[:2], labels[:2]):
                legend_elements.append(
                    plot.line2d([0], [0],
                                marker='o',
                                linestyle='',
                                color=clr,
                                markersize=4,
                                markerfacecolor=clr,
                                label=label))
            ax.legend(handles=legend_elements, loc=labelpos)

            # Zoom box
            if isinstance(zoom_box, list):
                for xi, yi in zip(zoom_box[0], zoom_box[1]):
                    # Create a Rectangle patch
                    rect = plot.patches.Rectangle((xi[0], yi[0]),
                                                  abs(xi[1] - xi[0]),
                                                  abs(yi[1] - yi[0]),
                                                  linewidth=2.0,
                                                  edgecolor=plot.cblack,
                                                  facecolor='none',
                                                  zorder=10)
                    ax.add_patch(rect)

        return fig, ax
#         etaeta > 1/6, xixi > -1/3),
#     xixi < 1/3)
# scattering(xixi[bools], etaeta[bools], np.ones_like(xixi[bools]),
#            append_to_fig_ax=(fig, ax),
#            alpha=0.4,
#            scale=5,
#            xlabel=r'$\xi$', ylabel=r'$\eta$',
#            )

# Test lumley triangle
# Plot realizability limits
limit_linestyle = '-k'

# Left limit
fig, ax = lining([0, -1 / 6], [0, 1 / 6],
                 xlim=[-1 / 5, 1 / 2.8],
                 ylim=[-0.01, 1 / 2.8],
                 linestyle=limit_linestyle)
# Right limit
lining([0, 1 / 3], [0, 1 / 3],
       append_to_fig_ax=(fig, ax),
       linestyle=limit_linestyle)

# Upper limit
xi_range = np.linspace(-1 / 6, 1 / 3, 20)
eta_lim = (1 / 27 + 2 * xi_range**3)**0.5
lining(xi_range,
       eta_lim,
       append_to_fig_ax=(fig, ax),
       linestyle=limit_linestyle)

# Anisotropy metric limit
x = case.flow_dict['x']
y = case.flow_dict['y']

xa = case.flow_dict['xa']
ya = case.flow_dict['ya']

x_min = np.min(x)
x_max = np.max(x)
y_min = np.min(y)
y_max = np.max(y)

# Plot reference
scattering(x, y, np.arange(2600), append_to_fig_ax=(fig, ax))

ref = (xa, ya)
lining(*ref, append_to_fig_ax=(fig, ax), linestyle='rx')

# Compute naca profile
x = np.linspace(0, 1, 1000)

# upper = geometry_naca_profile(x, 4, 4, 12, 'upper')
# lower = geometry_naca_profile(x, 4, 4, 12, 'lower')

upper = geometry_naca_profile(x, 0, 0, 12, 'upper')
lower = geometry_naca_profile(x, 0, 0, 12, 'lower')

boundary = tuple([upper,
                  lower])

# Plot boundaries
for b in boundary:
train_scores, \
valid_scores = learning_curve(idf,
                              X_all,
                              y_all,
                              groups=groups,
                              cv=logo,
                              train_sizes=np.linspace(0.1, 1, 10),
                              scoring='f1',
                              n_jobs=-1,
                              verbose=10
                              )

# Average the scores
mean_train_scores = np.mean(train_scores, axis=1)
mean_valid_scores = np.mean(valid_scores, axis=1)

# Plot learning curve
# fig, ax = plot.empty_plot()
fig1, ax1 = plot.lining(train_sizes,
                        mean_train_scores,
                        line_label='Train accuracy',
                        linestyle='r--',
                        ylim=[0, 1])
# plot.lining(train_sizes, train_scores, append_to_fig_ax=(fig1, ax1))
fig2, ax2 = plot.lining(train_sizes,
                        mean_valid_scores,
                        line_label='Valid accuracy',
                        linestyle='g--',
                        append_to_fig_ax=(fig1, ax1))
# plot.lining(train_sizes, valid_scores, append_to_fig_ax=(fig2, ax2))