def show_features(self,
                      feature_key='tke',
                      show_all=False,
                      show_geometry=True):
        """
        Display the feature in the physical domain.
        :param show_geometry: Print outline of the boundary.
        :param feature_key: Key for the feature (see utilties.py and features.py)
        :param show_all: Display all features (WARNING >50 plots).
        :return: 1:success.
        """

        # Plot all features
        if show_all:
            for key in self.feature_dict:
                # 2D Geometry outline
                if show_geometry:
                    fig, ax = self.show_geometry()
                else:
                    fig, ax = plot.empty_plot()

                plot.scattering(self.flow_dict['x'],
                                self.flow_dict['y'],
                                self.feature_dict[key],
                                scale=5,
                                alpha=1.0,
                                xlabel='x',
                                ylabel='y',
                                title=key,
                                colorbar=True,
                                append_to_fig_ax=(fig, ax))
        # Plot requested feature
        else:
            assert (
                feature_key in self.feature_dict
            ), "feature_key is not a valid key for features: %r" % feature_key

            # 2D Geometry outline
            if show_geometry:
                fig, ax = self.show_geometry()
            else:
                fig, ax = plot.empty_plot()

            plot.scattering(self.flow_dict['x'],
                            self.flow_dict['y'],
                            self.feature_dict[feature_key],
                            scale=5,
                            alpha=1.0,
                            xlabel='x/h',
                            ylabel='y/h',
                            title=feature_key,
                            cmap='viridis',
                            colorbar=True,
                            append_to_fig_ax=(fig, ax))

        return 1
def mean_coefficients(configuration):
    # Get all models
    filenames = find_results()
    result_names = [
        get_single_result_name(
            filenames, configuration[:-1] + [test_set_i.replace('-', '_')])
        for test_set_i in ['PH-Breuer', 'PH-Xiao', 'CBFS', 'TBL-APG', 'NACA']
    ]
    df_eval_all = model_and_params(result_names, configuration[0])

    feature_keys = df_eval_all['model'][0].feature_keys

    # Get and average coefficients
    list_coefs = [
        row.model.coef_ for row in df_eval_all.itertuples(index=True)
    ]
    coefs = np.vstack(list_coefs)
    mean_coefs = np.abs(coefs).mean(axis=0)
    nzero_coefs = np.count_nonzero(coefs, axis=0)

    # Sort ticklabels and mean coefs
    QKEYS = [feature_to_q_keys(fkey) for fkey in feature_keys]
    selected_q_keys = [
        qkey for _, qkey in sorted(
            zip(mean_coefs, QKEYS), key=lambda pair: pair[0], reverse=True)
    ]
    selected_feature_keys = [
        fkey for _, fkey in sorted(zip(mean_coefs, feature_keys),
                                   key=lambda pair: pair[0],
                                   reverse=True)
    ]
    sorted_mean_coefs = np.sort(mean_coefs)[::-1]  # Sort ascending

    # Reduce number of features
    n_feat = 5
    selected_q_keys = selected_q_keys[:n_feat]
    selected_feature_keys = selected_feature_keys[:n_feat]
    sorted_mean_coefs = sorted_mean_coefs[:n_feat]

    # Print feature map (might deviate from thesis)
    print("Feature map:\n")
    for qkey, fkey in zip(selected_q_keys, selected_feature_keys):
        print(f" {qkey.replace('$', '')}\t:\t{fkey}")

    fig, ax = empty_plot(figwidth=latex_textwidth / 2)
    baring(
        np.arange(sorted_mean_coefs.size),
        heights=sorted_mean_coefs,
        width=0.5,
        color=corange,
        xticklabels=[qkey for qkey in selected_q_keys],
        # xticklabels=[r"$\overline{\mathbf{S}^3}$", r"$\overline{\mathbf{P}^2 \mathbf{S}^2}$", r"$\dfrac{k}{\epsilon}\lVert\mathbf{S}\rVert$", r"$k$", r"$\overline{\mathbf{S}^2}$"],
        # xticklabels=[r"$\text{Re}_{\text{d}}$", r"$\overline{\mathbf{\Omega}^2}$", r"$k$", r"$\dfrac{k}{\epsilon}\lVert\mathbf{S}\rVert$", r"$\overline{\mathbf{S}^2}$"],
        ylabel="Average magnitude",
        xlabel="",
        append_to_fig_ax=(fig, ax),
        # sname="figures/logreg_model_mean_coef_" + configuration[2] + "_equations",
    )

    return 1
def compare_flow(var_key, *cases):
    """
    Compare distinct flow cases for a given variable on a
    grid of plots.
    :param var_key: Key of variable.
    :param cases: flowCase instances.
    :return: 1:success.
    """

    # Check valid key
    assert var_key in cases[
        0].flow_dict, "Invalid variable key given: %r" % var_key

    # Check required amount of subplots
    num_of_plots = len(cases)
    grid_length = int(num_of_plots**0.5) + 1

    # Create figure
    fig = plot.empty_plot(no_axis=True)

    # Add Title
    ax = fig.add_subplot(111)
    ax.set_title('Data basis with %r cases' % num_of_plots)
    ax.get_xaxis().set_visible(False)
    ax.get_yaxis().set_visible(False)

    # Plot individual cases
    for i, case in enumerate(cases):
        ax = fig.add_subplot(grid_length, grid_length,
                             i + 1)  # Add plot to grid
        ax.get_xaxis().set_visible(False)  # No axes
        ax.get_yaxis().set_visible(False)

        x = case.flow_dict['x']
        y = case.flow_dict['y']
        nx = case.flow_dict['nx']
        ny = case.flow_dict['ny']
        var = case.flow_dict[var_key]

        plot.contouring(x.reshape(nx, ny),
                        y.reshape(nx, ny),
                        var.reshape(nx, ny),
                        xlabel='',
                        ylabel='',
                        colorbar=False,
                        append_to_fig_ax=(fig, ax))
    plot.show()

    return 1
    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
Пример #5
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))
#####################################################################
### Test
#####################################################################
# Coefficients with colour
coefs = np.random.random(num_of_features) * np.random.randint(
    -100, 100, num_of_features)
coefs = np.abs(coefs)
colours = plot.general_cmap(coefs / np.max(coefs))

# Bar config
bar_width = 0.9
bar_pos = [i for i in range(num_of_features)]

# Bar plot
fig, ax = plot.empty_plot()
ax.bar(bar_pos, coefs, width=bar_width, color=colours)

# Set xticks position and label
ax.set_xticks(bar_pos)
ax.set_xticklabels(FEATURE_KEYS, rotation=90)

# Adjust position for labels
l, b, w, h = ax.get_position().bounds
ax.set_position([l, 0.2, w, h])

# Set y-scale to log
ax.set_xlim(None)
ax.set_ylim(None)
ax.set_autoscaley_on(True)
ax.set_yscale('log')
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 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
    def show_flow(self,
                  var_key,
                  contour=True,
                  contour_level=10,
                  xlim=None,
                  ylim=None,
                  colorbar=False,
                  show_geometry=True):
        """
        Display the requested variable in the physical coordinates.
        :param show_geometry: Print outline of the boundary.
        :param contour_level: Set amount of or specific levels.
        :param contour: Option for contour plot instead of scatter.
        :param ylim: List with shape [min_y, max_y]
        :param xlim: List with shape [min_x, max_x]
        :param var_key: Key in flow_dict for flow quantity.
        :return: void.
        """

        assert (var_key in self.flow_dict
                ), "var_key is not a valid key for flow data: %r" % var_key

        title = var_key + ' in ' + self.case_name

        if self.flow_dict[var_key].shape[0] == 3:
            var = self.flow_dict[var_key][0]  # x-component of vector
        else:
            var = self.flow_dict[var_key]

        # 2D Geometry outline
        if show_geometry:
            fig, ax = self.show_geometry()
        else:
            fig, ax = plot.empty_plot()

        # Contour plot
        if contour:
            plot.contouring(self.flow_dict['x'].reshape(self.nx, self.ny),
                            self.flow_dict['y'].reshape(self.nx, self.ny),
                            var.reshape(self.nx, self.ny),
                            xlabel='x',
                            ylabel='y',
                            title=title,
                            levels=contour_level,
                            colorbar=colorbar,
                            xlim=xlim,
                            ylim=ylim,
                            append_to_fig_ax=(fig, ax))

        # Scatter plot
        else:
            plot.scattering(self.flow_dict['x'],
                            self.flow_dict['y'],
                            var,
                            scale=20,
                            alpha=0.3,
                            colorbar=colorbar,
                            xlim=xlim,
                            ylim=ylim,
                            xlabel='x',
                            ylabel='y',
                            title=title,
                            append_to_fig_ax=(fig, ax))