diff --git a/config_files/config_test.yml b/config_files/config_test.yml
index 5a4d59df8fc4edc1066c69fb6d7d99b427f66f15..7f1aa89e1133b4079de02901147d4966a0c1d6d5 100644
--- a/config_files/config_test.yml
+++ b/config_files/config_test.yml
@@ -1,7 +1,7 @@
 # The base configuration of the benchmark
 Base :
   log: true
-  name: ["Plausible"]
+  name: ["plausible"]
   label: "_"
   type: ".hdf5"
   views:
@@ -22,9 +22,9 @@ Classification:
   nb_folds: 2
   nb_class: 2
   classes:
-  type: ["multiview"]
-  algos_monoview: ["all"]
-  algos_multiview: ["mumbo"]
+  type: ["monoview",]
+  algos_monoview: ["adaboost", "decision_tree"]
+  algos_multiview: ["all"]
   stats_iter: 2
   metrics: ["accuracy_score", "f1_score"]
   metric_princ: "f1_score"
diff --git a/multiview_platform/mono_multi_view_classifiers/exec_classif.py b/multiview_platform/mono_multi_view_classifiers/exec_classif.py
index ce66f7057c9867ecee20a5c441b2049bc8f18c81..88ae2c8717d873d46a2ceb85f1144abcc0adb5c5 100644
--- a/multiview_platform/mono_multi_view_classifiers/exec_classif.py
+++ b/multiview_platform/mono_multi_view_classifiers/exec_classif.py
@@ -581,8 +581,7 @@ def exec_one_benchmark_multicore(nb_cores=-1, labels_dictionary=None,
                                  benchmark=None, views=None, views_indices=None,
                                  flag=None, labels=None,
                                  exec_monoview_multicore=exec_monoview_multicore,
-                                 exec_multiview_multicore=exec_multiview_multicore,
-                                 init_multiview_arguments=init_multiview_arguments):
+                                 exec_multiview_multicore=exec_multiview_multicore,):
     """Used to run a benchmark using multiple cores. ExecMonoview_multicore, initMultiviewArguments and
      exec_multiview_multicore args are only used for tests"""
 
@@ -648,13 +647,11 @@ def exec_one_benchmark_mono_core(dataset_var=None, labels_dictionary=None,
                                  hyper_param_search=None, metrics=None,
                                  argument_dictionaries=None,
                                  benchmark=None, views=None, views_indices=None,
-                                 flag=None, labels=None,
-                                 exec_monoview_multicore=exec_monoview_multicore,
-                                 exec_multiview_multicore=exec_multiview_multicore,
-                                 init_multiview_arguments=init_multiview_arguments):
+                                 flag=None, labels=None,):
     results_monoview, labels_names = benchmark_init(directory,
                                                  classification_indices, labels,
                                                  labels_dictionary, k_folds)
+    logging.getLogger('matplotlib.font_manager').disabled = True
     logging.debug("Start:\t monoview benchmark")
     for arguments in argument_dictionaries["monoview"]:
         X = dataset_var.get_v(arguments["view_index"])
@@ -759,7 +756,6 @@ def exec_benchmark(nb_cores, stats_iter, nb_multiclass,
             benchmark_arguments_dictionaries[0])]
     else:
         for arguments in benchmark_arguments_dictionaries:
-            print(arguments)
             results += [exec_one_benchmark_mono_core(dataset_var=dataset_var, **arguments)]
     logging.debug("Done:\t Executing all the needed biclass benchmarks")
 
@@ -777,7 +773,8 @@ def exec_benchmark(nb_cores, stats_iter, nb_multiclass,
                                     directory,
                                     labels_dictionary,
                                     nb_examples,
-                                    nb_labels)
+                                    nb_labels,
+                                    dataset_var.example_ids)
     logging.debug("Done:\t Analyzing predictions")
     delete(benchmark_arguments_dictionaries, nb_cores, dataset_var)
     return results_mean_stds
diff --git a/multiview_platform/mono_multi_view_classifiers/monoview/exec_classif_mono_view.py b/multiview_platform/mono_multi_view_classifiers/monoview/exec_classif_mono_view.py
index 0b7b8f5bd4d7dcd1107149b821fb6456ff7b236b..875e3763ab77ea4ea771e6653aa80e2242b87ef2 100644
--- a/multiview_platform/mono_multi_view_classifiers/monoview/exec_classif_mono_view.py
+++ b/multiview_platform/mono_multi_view_classifiers/monoview/exec_classif_mono_view.py
@@ -97,15 +97,19 @@ def exec_monoview(directory, X, Y, name, labels_names, classificationIndices,
     logging.debug("Start:\t Predicting")
     y_train_pred = classifier.predict(X_train)
     y_test_pred = classifier.predict(X_test)
-    full_labels_pred = np.zeros(Y.shape, dtype=int) - 100
+
+    #Filling the full prediction in the right order
+    full_pred = np.zeros(Y.shape, dtype=int) - 100
     for trainIndex, index in enumerate(classificationIndices[0]):
-        full_labels_pred[index] = y_train_pred[trainIndex]
+        full_pred[index] = y_train_pred[trainIndex]
     for testIndex, index in enumerate(classificationIndices[1]):
-        full_labels_pred[index] = y_test_pred[testIndex]
+        full_pred[index] = y_test_pred[testIndex]
+
     if X_test_multiclass != []:
         y_test_multiclass_pred = classifier.predict(X_test_multiclass)
     else:
         y_test_multiclass_pred = []
+
     logging.debug("Done:\t Predicting")
 
     t_end = time.time() - t_start
@@ -124,7 +128,7 @@ def exec_monoview(directory, X, Y, name, labels_names, classificationIndices,
     logging.debug("Done:\t Getting results")
 
     logging.debug("Start:\t Saving preds")
-    saveResults(stringAnalysis, outputFileName, full_labels_pred, y_train_pred,
+    saveResults(stringAnalysis, outputFileName, full_pred, y_train_pred,
                 y_train, imagesAnalysis, y_test)
     logging.info("Done:\t Saving results")
 
@@ -132,7 +136,7 @@ def exec_monoview(directory, X, Y, name, labels_names, classificationIndices,
     if testFoldsPreds is None:
         testFoldsPreds = y_train_pred
     return monoview_utils.MonoviewResult(viewIndex, classifier_name, feat, metricsScores,
-                                         full_labels_pred, clKWARGS,
+                                         full_pred, clKWARGS,
                                          y_test_multiclass_pred, testFoldsPreds)
     # return viewIndex, [CL_type, feat, metricsScores, full_labels_pred, clKWARGS, y_test_multiclass_pred, testFoldsPreds]
 
diff --git a/multiview_platform/mono_multi_view_classifiers/multiview/analyze_results.py b/multiview_platform/mono_multi_view_classifiers/multiview/analyze_results.py
index 90637f5d70b256275e0cad083701c3f748b2a422..aa305849e6903b42bf63eb9e7b440ec3a20f85c6 100644
--- a/multiview_platform/mono_multi_view_classifiers/multiview/analyze_results.py
+++ b/multiview_platform/mono_multi_view_classifiers/multiview/analyze_results.py
@@ -66,14 +66,8 @@ def getTotalMetricScores(metric, trainLabels, testLabels, validationIndices,
                             enumerate(metric[1]))
     else:
         metricKWARGS = {}
-    try:
-        trainScore = metricModule.score(labels[learningIndices], trainLabels,
+    trainScore = metricModule.score(labels[learningIndices], trainLabels,
                                         **metricKWARGS)
-    except:
-        print(labels[learningIndices])
-        print(trainLabels)
-        import pdb;
-        pdb.set_trace()
     testScore = metricModule.score(labels[validationIndices], testLabels,
                                    **metricKWARGS)
     return [trainScore, testScore]
diff --git a/multiview_platform/mono_multi_view_classifiers/multiview/multiview_utils.py b/multiview_platform/mono_multi_view_classifiers/multiview/multiview_utils.py
index 8006f46e71ba3c90d4f5626d765045750cfe13bf..4c5e34719f0692260492bd4b1b95524a1d756bb5 100644
--- a/multiview_platform/mono_multi_view_classifiers/multiview/multiview_utils.py
+++ b/multiview_platform/mono_multi_view_classifiers/multiview/multiview_utils.py
@@ -16,11 +16,14 @@ class MultiviewResult(object):
         self.y_test_multiclass_pred = test_labels_multiclass
 
     def get_classifier_name(self):
-        multiview_classifier_module = getattr(multiview_classifiers,
-                                            self.classifier_name)
-        multiview_classifier = getattr(multiview_classifier_module,
-                                       multiview_classifier_module.classifier_class_name)(42)
-        return multiview_classifier.short_name
+        try:
+            multiview_classifier_module = getattr(multiview_classifiers,
+                                                self.classifier_name)
+            multiview_classifier = getattr(multiview_classifier_module,
+                                           multiview_classifier_module.classifier_class_name)(42)
+            return multiview_classifier.short_name
+        except:
+            return self.classifier_name
 
 
 def get_names(classed_list):
diff --git a/multiview_platform/mono_multi_view_classifiers/result_analysis.py b/multiview_platform/mono_multi_view_classifiers/result_analysis.py
index 661b84afcf664b0b57869e35ffc66bf374a14385..41e9abcda7057ffcf1c3c7b877ca73d3f05ef0d8 100644
--- a/multiview_platform/mono_multi_view_classifiers/result_analysis.py
+++ b/multiview_platform/mono_multi_view_classifiers/result_analysis.py
@@ -61,6 +61,193 @@ def plot_results_noise(directory, noise_results, metric_to_plot, name, width=0.1
     df.to_csv(directory+name+"_noise_analysis.csv")
 
 
+def plot_metric_scores(train_scores, test_scores, names, nb_results, metric_name,
+                       file_name,
+                       tag="", train_STDs=None, test_STDs=None):
+    r"""Used to plot and save the score barplot for a specific metric.
+
+    Parameters
+    ----------
+    train_scores : list or np.array of floats
+        The scores of each classifier on the training set.
+    test_scores : list or np.array of floats
+        The scores of each classifier on the testing set.
+    names : list or np.array of strs
+        The names of all the classifiers.
+    nb_results: int
+        The number of classifiers to plot.
+    metric_name : str
+        The plotted metric's name
+    file_name : str
+        The name of the file where the figure will be saved.
+    tag : str
+        Some text to personalize the title, must start with a whitespace.
+    train_STDs : np.array of floats or None
+        The array containing the standard deviations for the averaged scores on the training set.
+    test_STDs : np.array of floats or None
+        The array containing the standard deviations for the averaged scores on the testing set.
+
+    Returns
+    -------
+    """
+
+    figKW, barWidth = get_fig_size(nb_results)
+
+    names, train_scores, test_scores, train_STDs, test_STDs = sort_by_test_score(
+        train_scores, test_scores, names,
+        train_STDs, test_STDs)
+
+    f, ax = plt.subplots(nrows=1, ncols=1, **figKW)
+    ax.set_title(metric_name + "\n" + tag + " scores for each classifier")
+
+    rects = ax.bar(range(nb_results), test_scores, barWidth, color="0.1",
+                   yerr=test_STDs)
+    rect2 = ax.bar(np.arange(nb_results) + barWidth, train_scores, barWidth,
+                   color="0.8", yerr=train_STDs)
+    autolabel(rects, ax, set=1, std=test_STDs)
+    autolabel(rect2, ax, set=2, std=train_STDs)
+    ax.legend((rects[0], rect2[0]), ('Test', 'Train'))
+    ax.set_ylim(-0.1, 1.1)
+    ax.set_xticks(np.arange(nb_results) + barWidth)
+    ax.set_xticklabels(names, rotation="vertical")
+
+    try:
+        plt.tight_layout()
+    except:
+        pass
+    f.savefig(file_name + '.png', transparent=True)
+    plt.close()
+    import pandas as pd
+    if train_STDs is None:
+        dataframe = pd.DataFrame(np.transpose(np.concatenate((
+            train_scores.reshape((train_scores.shape[0], 1)),
+            test_scores.reshape((train_scores.shape[0], 1))), axis=1)),
+            columns=names)
+    else:
+        dataframe = pd.DataFrame(np.transpose(np.concatenate((
+            train_scores.reshape((train_scores.shape[0], 1)),
+            train_STDs.reshape((train_scores.shape[0], 1)),
+            test_scores.reshape((train_scores.shape[0], 1)),
+            test_STDs.reshape((train_scores.shape[0], 1))), axis=1)),
+            columns=names)
+    dataframe.to_csv(file_name + ".csv")
+
+
+def plot_2d(data, classifiers_names, nbClassifiers, nbExamples,
+            fileName, minSize=10,
+            width_denominator=2.0, height_denominator=20.0, stats_iter=1,
+            use_plotly=True, example_ids=None):
+    r"""Used to generate a 2D plot of the errors.
+
+    Parameters
+    ----------
+    data : np.array of shape `(nbClassifiers, nbExamples)`
+        A matrix with zeros where the classifier failed to classifiy the example, ones where it classified it well
+        and -100 if the example was not classified.
+    classifiers_names : list of str
+        The names of the classifiers.
+    nbClassifiers : int
+        The number of classifiers.
+    nbExamples : int
+        The number of examples.
+    nbCopies : int
+        The number of times the data is copied (classifier wise) in order for the figure to be more readable
+    fileName : str
+        The name of the file in which the figure will be saved ("error_analysis_2D.png" will be added at the end)
+    minSize : int, optinal, default: 10
+        The minimum width and height of the figure.
+    width_denominator : float, optional, default: 1.0
+        To obtain the image width, the number of classifiers will be divided by this number.
+    height_denominator : float, optional, default: 1.0
+        To obtain the image width, the number of examples will be divided by this number.
+    stats_iter : int, optional, default: 1
+        The number of statistical iterations realized.
+
+    Returns
+    -------
+    """
+    fig, ax = plt.subplots(nrows=1, ncols=1,)
+    cmap, norm = iterCmap(stats_iter)
+    cax = plt.imshow(data, cmap=cmap, norm=norm,
+                     aspect='auto')
+    plt.title('Errors depending on the classifier')
+    ticks = np.arange(0, nbClassifiers, 1)
+    labels = classifiers_names
+    plt.xticks(ticks, labels, rotation="vertical")
+    cbar = fig.colorbar(cax, ticks=[-100 * stats_iter / 2, 0, stats_iter])
+    cbar.ax.set_yticklabels(['Unseen', 'Always Wrong', 'Always Right'])
+
+    fig.savefig(fileName + "error_analysis_2D.png", bbox_inches="tight", transparent=True)
+    plt.close()
+    ### The following part is used to generate an interactive graph.
+    if use_plotly:
+        import plotly
+        fig = plotly.graph_objs.Figure(data=plotly.graph_objs.Heatmap(
+            x=list(classifiers_names),
+            y=example_ids,
+            z=data,
+            colorscale="Greys",
+            reversescale=True))
+        fig.update_layout(
+            xaxis={"showgrid": False, "showticklabels": False, "ticks": ''},
+            yaxis={"showgrid": False, "showticklabels": False, "ticks": ''})
+        plotly.offline.plot(fig, filename=fileName + "error_analysis_2D.html", auto_open=False)
+        del fig
+
+
+def plot_errors_bar(error_on_examples, nbClassifiers, nbExamples, fileName):
+    r"""Used to generate a barplot of the muber of classifiers that failed to classify each examples
+
+    Parameters
+    ----------
+    error_on_examples : np.array of shape `(nbExamples,)`
+        An array counting how many classifiers failed to classifiy each examples.
+    classifiers_names : list of str
+        The names of the classifiers.
+    nbClassifiers : int
+        The number of classifiers.
+    nbExamples : int
+        The number of examples.
+    fileName : str
+        The name of the file in which the figure will be saved ("error_analysis_2D.png" will be added at the end)
+
+    Returns
+    -------
+    """
+    fig, ax = plt.subplots()
+    x = np.arange(nbExamples)
+    plt.bar(x, error_on_examples)
+    plt.ylim([0, nbClassifiers])
+    plt.title("Number of classifiers that failed to classify each example")
+    fig.savefig(fileName + "error_analysis_bar.png", transparent=True)
+    plt.close()
+
+
+def iterCmap(statsIter):
+    r"""Used to generate a colormap that will have a tick for each iteration : the whiter the better.
+
+    Parameters
+    ----------
+    statsIter : int
+        The number of statistical iterations.
+
+    Returns
+    -------
+    cmap : matplotlib.colors.ListedColorMap object
+        The colormap.
+    norm : matplotlib.colors.BoundaryNorm object
+        The bounds for the colormap.
+    """
+    cmapList = ["red", "0.0"] + [str(float((i + 1)) / statsIter) for i in
+                                 range(statsIter)]
+    cmap = mpl.colors.ListedColormap(cmapList)
+    bounds = [-100 * statsIter - 0.5, -0.5]
+    for i in range(statsIter):
+        bounds.append(i + 0.5)
+    bounds.append(statsIter + 0.5)
+    norm = mpl.colors.BoundaryNorm(bounds, cmap.N)
+    return cmap, norm
+
 
 def autolabel(rects, ax, set=1, std=None):
     r"""Used to print the score below the bars.
@@ -97,6 +284,34 @@ def autolabel(rects, ax, set=1, std=None):
                     "%.2f" % height, weight=weight,
                     ha='center', va='bottom', size="small")
 
+def get_fig_size(nb_results, min_size=15, multiplier=1.0, bar_width=0.35):
+    r"""Used to get the image size to save the figure and the bar width, depending on the number of scores to plot.
+
+    Parameters
+    ----------
+    nb_results : int
+        The number of couple of bar to plot.
+    min_size : int
+        The minimum size of the image, if there are few classifiers to plot.
+    multiplier : float
+        The ratio between the image size and the number of classifiers.
+    bar_width : float
+        The width of the bars in the figure. Mainly here to centralize bar_width.
+
+    Returns
+    -------
+    fig_kwargs : dict of arguments
+        The argument restraining the size of the figure, usable directly in the `subplots` function of
+        `matplotlib.pyplot`.
+    bar_width : float
+        The width of the bars in the figure. Mainly here to centralize bar_width.
+    """
+    size = nb_results * multiplier
+    if size < min_size:
+        size = min_size
+    fig_kwargs = {"figsize": (size, size / 3)}
+    return fig_kwargs, bar_width
+
 
 def get_metrics_scores_biclass(metrics, results):
     r"""Used to extract metrics scores in case of biclass classification
@@ -106,7 +321,7 @@ def get_metrics_scores_biclass(metrics, results):
     metrics : list of lists
         The metrics names with configuration metrics[i][0] = name of metric i
     results : list of MonoviewResult and MultiviewResults objects
-        A list containing all the resluts for all the monoview experimentations.
+        A list containing all the results for all the monoview experimentations.
 
     Returns
     -------
@@ -117,25 +332,28 @@ def get_metrics_scores_biclass(metrics, results):
         -`metricScores[metric_name]["train_scores"]` is a list of all the available classifiers scores on the train set,
         -`metricScores[metric_name]["test_scores"]` is a list of all the available classifiers scores on the test set.
     """
-    metrics_scores = {}
+    classifier_names=[]
+    classifier_names = [classifierResult.get_classifier_name()
+                        for classifierResult in results
+                        if classifierResult.get_classifier_name()
+                            not in classifier_names ]
+    metrics_scores = dict((metric[0], pd.DataFrame(data=np.zeros((2,
+                                                                  len(classifier_names))),
+                                                index=["train", "test"],
+                                                columns=classifier_names))
+                          for metric in metrics)
 
     for metric in metrics:
-        classifiers_names = []
-        train_scores = []
-        test_scores = []
-
         for classifierResult in results:
-            train_scores.append(classifierResult.metrics_scores[metric[0]][0])
-            test_scores.append(classifierResult.metrics_scores[metric[0]][1])
-            classifiers_names.append(classifierResult.get_classifier_name())
+            metrics_scores[metric[0]].loc["train", classifierResult.get_classifier_name()] = classifierResult.metrics_scores[metric[0]][0]
+            metrics_scores[metric[0]].loc[
+                "test", classifierResult.get_classifier_name()] = \
+            classifierResult.metrics_scores[metric[0]][1]
 
-        metrics_scores[metric[0]] = {"classifiers_names": classifiers_names,
-                                    "train_scores": train_scores,
-                                    "test_scores": test_scores}
     return metrics_scores
 
 
-def getExampleErrorsBiclass(groud_truth, results):
+def get_example_errors_biclass(groud_truth, results):
     r"""Used to get for each classifier and each example whether the classifier has misclassified the example or not.
 
     Parameters
@@ -154,46 +372,15 @@ def getExampleErrorsBiclass(groud_truth, results):
     """
     example_errors = {}
 
-    for classifierResult in results:
-        error_on_examples = np.equal(classifierResult.full_labels_pred,
+    for classifier_result in results:
+        error_on_examples = np.equal(classifier_result.full_labels_pred,
                                    groud_truth).astype(int)
-        unseenExamples = np.where(groud_truth == -100)[0]
-        error_on_examples[unseenExamples] = -100
-        example_errors[classifierResult.get_classifier_name()] = {
-            "error_on_examples": error_on_examples}
-
+        unseen_examples = np.where(groud_truth == -100)[0]
+        error_on_examples[unseen_examples] = -100
+        example_errors[classifier_result.get_classifier_name()] = error_on_examples
     return example_errors
 
 
-def get_fig_size(nb_results, min_size=15, multiplier=1.0, bar_width=0.35):
-    r"""Used to get the image size to save the figure and the bar width, depending on the number of scores to plot.
-
-    Parameters
-    ----------
-    nb_results : int
-        The number of couple of bar to plot.
-    min_size : int
-        The minimum size of the image, if there are few classifiers to plot.
-    multiplier : float
-        The ratio between the image size and the number of classifiers.
-    bar_width : float
-        The width of the bars in the figure. Mainly here to centralize bar_width.
-
-    Returns
-    -------
-    fig_kwargs : dict of arguments
-        The argument restraining the size of the figure, usable directly in the `subplots` function of
-        `matplotlib.pyplot`.
-    bar_width : float
-        The width of the bars in the figure. Mainly here to centralize bar_width.
-    """
-    size = nb_results * multiplier
-    if size < min_size:
-        size = min_size
-    fig_kwargs = {"figsize": (size, size / 3)}
-    return fig_kwargs, bar_width
-
-
 def sort_by_test_score(train_scores, test_scores, names, train_STDs=None,
                        test_STDs=None):
     r"""Used to sort the results (names and both scores) in descending test score order.
@@ -239,77 +426,7 @@ def sort_by_test_score(train_scores, test_scores, names, train_STDs=None,
     return sorted_names, sorted_train_scores, sorted_test_scores, sorted_train_STDs, sorted_test_STDs
 
 
-def plotMetricScores(train_scores, test_scores, names, nb_results, metric_name,
-                     file_name,
-                     tag="", train_STDs=None, test_STDs=None):
-    r"""Used to plot and save the score barplot for a specific metric.
-
-    Parameters
-    ----------
-    train_scores : list or np.array of floats
-        The scores of each classifier on the training set.
-    test_scores : list or np.array of floats
-        The scores of each classifier on the testing set.
-    names : list or np.array of strs
-        The names of all the classifiers.
-    nb_results: int
-        The number of classifiers to plot.
-    metric_name : str
-        The plotted metric's name
-    file_name : str
-        The name of the file where the figure will be saved.
-    tag : str
-        Some text to personalize the title, must start with a whitespace.
-    train_STDs : np.array of floats or None
-        The array containing the standard deviations for the averaged scores on the training set.
-    test_STDs : np.array of floats or None
-        The array containing the standard deviations for the averaged scores on the testing set.
-
-    Returns
-    -------
-    """
-
-    figKW, barWidth = get_fig_size(nb_results)
 
-    names, train_scores, test_scores, train_STDs, test_STDs = sort_by_test_score(
-        train_scores, test_scores, names,
-        train_STDs, test_STDs)
-
-    f, ax = plt.subplots(nrows=1, ncols=1, **figKW)
-    ax.set_title(metric_name + "\n" + tag + " scores for each classifier")
-
-    rects = ax.bar(range(nb_results), test_scores, barWidth, color="0.1",
-                   yerr=test_STDs)
-    rect2 = ax.bar(np.arange(nb_results) + barWidth, train_scores, barWidth,
-                   color="0.8", yerr=train_STDs)
-    autolabel(rects, ax, set=1, std=test_STDs)
-    autolabel(rect2, ax, set=2, std=train_STDs)
-    print("nb_results", nb_results)
-    ax.legend((rects[0], rect2[0]), ('Test', 'Train'))
-    ax.set_ylim(-0.1, 1.1)
-    ax.set_xticks(np.arange(nb_results) + barWidth)
-    ax.set_xticklabels(names, rotation="vertical")
-
-    try:
-        plt.tight_layout()
-    except:
-        pass
-    f.savefig(file_name + '.png', transparent=True)
-    plt.close()
-    import pandas as pd
-    if train_STDs is None:
-        dataframe = pd.DataFrame(np.transpose(np.concatenate((
-            train_scores.reshape((train_scores.shape[0], 1)),
-            test_scores.reshape((train_scores.shape[0], 1))), axis=1)),
-            columns=names)
-    else:
-        dataframe = pd.DataFrame(np.transpose(np.concatenate((
-            train_scores.reshape((train_scores.shape[0], 1)),
-            train_STDs.reshape((train_scores.shape[0], 1)),
-            test_scores.reshape((train_scores.shape[0], 1)),
-            test_STDs.reshape((train_scores.shape[0], 1))), axis=1)),
-            columns=names)
-    dataframe.to_csv(file_name + ".csv")
 
 
 def publishMetricsGraphs(metrics_scores, directory, database_name, labels_names):
@@ -332,151 +449,40 @@ def publishMetricsGraphs(metrics_scores, directory, database_name, labels_names)
     results
     """
     results=[]
-    for metric_name, metric_scores in metrics_scores.items():
+    for metric_name, metric_dataframe in metrics_scores.items():
         logging.debug(
             "Start:\t Biclass score graph generation for " + metric_name)
-
-        nb_results = len(metric_scores["test_scores"])
-        file_name = directory + time.strftime(
-            "%Y_%m_%d-%H_%M_%S") + "-" + database_name + "-" + "_vs_".join(
-            labels_names) + "-" + metric_name
-
-        plotMetricScores(np.array(metric_scores["train_scores"]),
-                         np.array(metric_scores["test_scores"]),
-                         np.array(metric_scores["classifiers_names"]), nb_results,
-                         metric_name, file_name,
-                         tag=" " + " vs ".join(labels_names))
-
-        logging.debug(
-            "Done:\t Biclass score graph generation for " + metric_name)
-        results+=[[classifiers_name, metric_name, testMean, testSTD]
-                  for classifiers_name, testMean, testSTD in zip(np.array(metric_scores["classifiers_names"]),
-                                                                 np.array(metric_scores["test_scores"]),
-                                                                 np.zeros(len(np.array(metric_scores["test_scores"]))))]
+        train_scores, test_scores, classifier_names, \
+        file_name, nb_results,results = init_plot(results, metric_name,
+                                                  metric_dataframe, directory,
+                                                  database_name, labels_names)
+
+        plot_metric_scores(train_scores, test_scores, classifier_names,
+                           nb_results, metric_name, file_name,
+                           tag=" "+" vs ".join(labels_names))
+        logging.debug("Done:\t Biclass score graph generation for "+metric_name)
     return results
 
-def iterCmap(statsIter):
-    r"""Used to generate a colormap that will have a tick for each iteration : the whiter the better.
-
-    Parameters
-    ----------
-    statsIter : int
-        The number of statistical iterations.
-
-    Returns
-    -------
-    cmap : matplotlib.colors.ListedColorMap object
-        The colormap.
-    norm : matplotlib.colors.BoundaryNorm object
-        The bounds for the colormap.
-    """
-    cmapList = ["red", "0.0"] + [str(float((i + 1)) / statsIter) for i in
-                                 range(statsIter)]
-    cmap = mpl.colors.ListedColormap(cmapList)
-    bounds = [-100 * statsIter - 0.5, -0.5]
-    for i in range(statsIter):
-        bounds.append(i + 0.5)
-    bounds.append(statsIter + 0.5)
-    norm = mpl.colors.BoundaryNorm(bounds, cmap.N)
-    return cmap, norm
-
-
-def publish2Dplot(data, classifiers_names, nbClassifiers, nbExamples, nbCopies,
-                  fileName, minSize=10,
-                  width_denominator=2.0, height_denominator=20.0, stats_iter=1,
-                  use_plotly=False, example_ids=None):
-    r"""Used to generate a 2D plot of the errors.
-
-    Parameters
-    ----------
-    data : np.array of shape `(nbClassifiers, nbExamples)`
-        A matrix with zeros where the classifier failed to classifiy the example, ones where it classified it well
-        and -100 if the example was not classified.
-    classifiers_names : list of str
-        The names of the classifiers.
-    nbClassifiers : int
-        The number of classifiers.
-    nbExamples : int
-        The number of examples.
-    nbCopies : int
-        The number of times the data is copied (classifier wise) in order for the figure to be more readable
-    fileName : str
-        The name of the file in which the figure will be saved ("error_analysis_2D.png" will be added at the end)
-    minSize : int, optinal, default: 10
-        The minimum width and height of the figure.
-    width_denominator : float, optional, default: 1.0
-        To obtain the image width, the number of classifiers will be divided by this number.
-    height_denominator : float, optional, default: 1.0
-        To obtain the image width, the number of examples will be divided by this number.
-    stats_iter : int, optional, default: 1
-        The number of statistical iterations realized.
-
-    Returns
-    -------
-    """
-    figWidth = max(nbClassifiers / width_denominator, minSize)
-    figHeight = max(nbExamples / height_denominator, minSize)
-    print(figHeight, figWidth, nbClassifiers, nbExamples)
-    figKW = {"figsize": (figWidth, figHeight)}
-    fig, ax = plt.subplots(nrows=1, ncols=1,)# **figKW)
-    cmap, norm = iterCmap(stats_iter)
-    cax = plt.imshow(data, cmap=cmap, norm=norm,
-                     aspect='auto')
-    plt.title('Errors depending on the classifier')
-    ticks = np.arange(nbCopies / 2 - 0.5, nbClassifiers * nbCopies, nbCopies)
-    labels = classifiers_names
-    plt.xticks(ticks, labels, rotation="vertical")
-    cbar = fig.colorbar(cax, ticks=[-100 * stats_iter / 2, 0, stats_iter])
-    cbar.ax.set_yticklabels(['Unseen', 'Always Wrong', 'Always Right'])
-    # fig.tight_layout()
-
-    fig.savefig(fileName + "error_analysis_2D.png", bbox_inches="tight", transparent=True)
-    plt.close()
-    ### The following part is used to generate an interactive graph.
-    if use_plotly:
-        import plotly
-        fig = plotly.graph_objs.go.Figure(data=plotly.graph_objs.go.Heatmap(
-            x=classifiers_names,
-            y=example_ids,
-            z=data,
-            colorscale="Greys",
-            ))
-        fig.update_layout(
-            xaxis={"showgrid": False, "showticklabels": False, "ticks": ''},
-            yaxis={"showgrid": False, "showticklabels": False, "ticks": ''})
-        plotly.offline.plot(fig, filename='essai.html', auto_open=False)
-        del fig
 
+def init_plot(results, metric_name, metric_dataframe,
+              directory, database_name, labels_names):
 
-def publishErrorsBarPlot(error_on_examples, nbClassifiers, nbExamples, fileName):
-    r"""Used to generate a barplot of the muber of classifiers that failed to classify each examples
+    train = np.array(metric_dataframe.loc["train"])
+    test = np.array(metric_dataframe.loc["test"])
+    classifier_names = np.array(metric_dataframe.columns)
 
-    Parameters
-    ----------
-    error_on_examples : np.array of shape `(nbExamples,)`
-        An array counting how many classifiers failed to classifiy each examples.
-    classifiers_names : list of str
-        The names of the classifiers.
-    nbClassifiers : int
-        The number of classifiers.
-    nbExamples : int
-        The number of examples.
-    fileName : str
-        The name of the file in which the figure will be saved ("error_analysis_2D.png" will be added at the end)
+    nb_results = metric_dataframe.shape[1]
 
-    Returns
-    -------
-    """
-    fig, ax = plt.subplots()
-    x = np.arange(nbExamples)
-    plt.bar(x, error_on_examples)
-    plt.ylim([0, nbClassifiers])
-    plt.title("Number of classifiers that failed to classify each example")
-    fig.savefig(fileName + "error_analysis_bar.png", transparent=True)
-    plt.close()
+    file_name = directory + time.strftime(
+        "%Y_%m_%d-%H_%M_%S") + "-" + database_name + "-" + "_vs_".join(
+        labels_names) + "-" + metric_name
 
+    results += [[classifiers_name, metric_name, testMean, testSTD]
+                for classifiers_name, testMean, testSTD in
+                zip(classifier_names, test, np.zeros(len(test)))]
+    return train, test, classifier_names, file_name, nb_results, results
 
-def gen_error_data(example_errors, base_file_name, nbCopies=2):
+def gen_error_data(example_errors):
     r"""Used to format the error data in order to plot it efficiently. The data is saves in a `.csv` file.
 
     Parameters
@@ -510,42 +516,38 @@ def gen_error_data(example_errors, base_file_name, nbCopies=2):
     error_on_examples : np.array of shape `(nbExamples,)`
         An array counting how many classifiers failed to classifiy each examples.
     """
-    nbClassifiers = len(example_errors)
-    nbExamples = len(list(example_errors.values())[0]["error_on_examples"])
-    classifiers_names = example_errors.keys()
+    nb_classifiers = len(example_errors)
+    nb_examples = len(list(example_errors.values())[0])
+    classifiers_names = list(example_errors.keys())
 
-    data = np.zeros((nbExamples, nbClassifiers * nbCopies))
-    temp_data = np.zeros((nbExamples, nbClassifiers))
+    data_2d = np.zeros((nb_examples, nb_classifiers))
     for classifierIndex, (classifier_name, error_on_examples) in enumerate(
             example_errors.items()):
-        for iter_index in range(nbCopies):
-            data[:, classifierIndex * nbCopies + iter_index] = error_on_examples[
-                "error_on_examples"]
-            temp_data[:, classifierIndex] = error_on_examples["error_on_examples"]
-    error_on_examples = -1 * np.sum(data, axis=1) / nbCopies + nbClassifiers
-
-    np.savetxt(base_file_name + "2D_plot_data.csv", data, delimiter=",")
-    np.savetxt(base_file_name + "bar_plot_data.csv", temp_data, delimiter=",")
+        data_2d[:, classifierIndex] = error_on_examples
+    error_on_examples = -1 * np.sum(data_2d, axis=1) / nb_classifiers
 
-    return nbClassifiers, nbExamples, nbCopies, classifiers_names, data, error_on_examples
+    return nb_classifiers, nb_examples, classifiers_names, data_2d, error_on_examples
 
 
-def publishExampleErrors(example_errors, directory, databaseName, labels_names):
+def publishExampleErrors(example_errors, directory, databaseName, labels_names, example_ids):
     logging.debug("Start:\t Biclass Label analysis figure generation")
 
     base_file_name = directory + time.strftime(
         "%Y_%m_%d-%H_%M_%S") + "-" + databaseName + "-" + "_vs_".join(
         labels_names) + "-"
 
-    nbClassifiers, nbExamples, nCopies, classifiers_names, data, error_on_examples = gen_error_data(
-        example_errors,
-        base_file_name)
+    nb_classifiers, nb_examples, classifiers_names, \
+    data_2d, error_on_examples = gen_error_data(example_errors)
 
-    publish2Dplot(data, classifiers_names, nbClassifiers, nbExamples, nCopies,
-                  base_file_name)
+    np.savetxt(base_file_name + "2D_plot_data.csv", data_2d, delimiter=",")
+    np.savetxt(base_file_name + "bar_plot_data.csv", error_on_examples,
+               delimiter=",")
+
+    plot_2d(data_2d, classifiers_names, nb_classifiers, nb_examples,
+            base_file_name, example_ids=example_ids)
 
-    publishErrorsBarPlot(error_on_examples, nbClassifiers, nbExamples,
-                         base_file_name)
+    plot_errors_bar(error_on_examples, nb_classifiers, nb_examples,
+                    base_file_name)
 
     logging.debug("Done:\t Biclass Label analysis figures generation")
 
@@ -571,7 +573,7 @@ def get_arguments(benchmark_argument_dictionaries, flag):
             return benchmarkArgumentDictionary
 
 
-def analyze_biclass(results, benchmark_argument_dictionaries, stats_iter, metrics):
+def analyze_biclass(results, benchmark_argument_dictionaries, stats_iter, metrics, example_ids):
     r"""Used to extract and format the results of the different biclass experimentations performed.
 
     Parameters
@@ -598,7 +600,7 @@ def analyze_biclass(results, benchmark_argument_dictionaries, stats_iter, metric
         label combination, regrouping the scores for each metrics and the information useful to plot errors on examples.
     """
     logging.debug("Srart:\t Analzing all biclass resuls")
-    biclass_results = [{} for _ in range(stats_iter)]
+    biclass_results = {}
 
     for flag, result in results:
         iteridex, [classifierPositive, classifierNegative] = flag
@@ -606,7 +608,7 @@ def analyze_biclass(results, benchmark_argument_dictionaries, stats_iter, metric
         arguments = get_arguments(benchmark_argument_dictionaries, flag)
 
         metrics_scores = get_metrics_scores_biclass(metrics, result)
-        example_errors = getExampleErrorsBiclass(arguments["labels"], result)
+        example_errors = get_example_errors_biclass(arguments["labels"], result)
 
         directory = arguments["directory"]
 
@@ -617,12 +619,15 @@ def analyze_biclass(results, benchmark_argument_dictionaries, stats_iter, metric
         results = publishMetricsGraphs(metrics_scores, directory, database_name,
                              labels_names)
         publishExampleErrors(example_errors, directory, database_name,
-                             labels_names)
-
-        biclass_results[iteridex][
-            str(classifierPositive) + str(classifierNegative)] = {
-            "metrics_scores": metrics_scores,
-            "example_errors": example_errors}
+                             labels_names, example_ids)
+        if not str(classifierPositive) + str(classifierNegative) in biclass_results:
+            biclass_results[str(classifierPositive) + str(classifierNegative)] = {}
+            biclass_results[str(classifierPositive) + str(classifierNegative)][
+                "metrics_scores"] = [i for i in range(stats_iter)]
+            biclass_results[str(classifierPositive) + str(classifierNegative)][
+                "example_errors"] = [i for i in range(stats_iter)]
+        biclass_results[str(classifierPositive) + str(classifierNegative)]["metrics_scores"][iteridex] = metrics_scores
+        biclass_results[str(classifierPositive) + str(classifierNegative)]["example_errors"][iteridex] = example_errors
 
     logging.debug("Done:\t Analzing all biclass resuls")
     return results, biclass_results
@@ -702,8 +707,8 @@ def publishMulticlassScores(multiclass_results, metrics, stats_iter, direcories,
                 "%Y_%m_%d-%H_%M_%S") + "-" + databaseName + "-" + metric[
                            0] + ".png"
 
-            plotMetricScores(train_scores, validationScores, classifiers_names,
-                             nbResults, metric[0], fileName, tag=" multiclass")
+            plot_metric_scores(train_scores, validationScores, classifiers_names,
+                               nbResults, metric[0], fileName, tag=" multiclass")
 
             logging.debug(
                 "Done:\t Multiclass score graph generation for " + metric[0])
@@ -712,7 +717,7 @@ def publishMulticlassScores(multiclass_results, metrics, stats_iter, direcories,
 
 
 def publishMulticlassExmapleErrors(multiclass_results, directories,
-                                   databaseName):
+                                   databaseName, example_ids):
     for iter_index, multiclassResult in enumerate(multiclass_results):
         directory = directories[iter_index]
         logging.debug("Start:\t Multiclass Label analysis figure generation")
@@ -724,18 +729,18 @@ def publishMulticlassExmapleErrors(multiclass_results, directories,
             multiclassResult,
             base_file_name)
 
-        publish2Dplot(data, classifiers_names, nbClassifiers, nbExamples,
-                      nCopies, base_file_name)
+        plot_2d(data, classifiers_names, nbClassifiers, nbExamples,
+                nCopies, base_file_name, example_ids=example_ids)
 
-        publishErrorsBarPlot(error_on_examples, nbClassifiers, nbExamples,
-                             base_file_name)
+        plot_errors_bar(error_on_examples, nbClassifiers, nbExamples,
+                        base_file_name)
 
         logging.debug("Done:\t Multiclass Label analysis figure generation")
 
 
 def analyzeMulticlass(results, stats_iter, benchmark_argument_dictionaries,
                       nb_examples, nb_labels, multiclass_labels,
-                      metrics, classification_indices, directories):
+                      metrics, classification_indices, directories, example_ids):
     """Used to transform one versus one results in multiclass results and to publish it"""
     multiclass_results = [{} for _ in range(stats_iter)]
 
@@ -787,7 +792,7 @@ def analyzeMulticlass(results, stats_iter, benchmark_argument_dictionaries,
                             benchmark_argument_dictionaries[0]["args"]["Base"]["name"])
     publishMulticlassExmapleErrors(multiclass_results, directories,
                                    benchmark_argument_dictionaries[0][
-                                       "args"].name)
+                                       "args"].name, example_ids)
     return results, multiclass_results
 
 
@@ -820,9 +825,9 @@ def publish_iter_biclass_metrics_scores(iter_results, directory, labels_dictiona
                 stats_iter) + "_iter-" + metricName + ".png"
             nbResults = names.shape[0]
 
-            plotMetricScores(trainMeans, testMeans, names, nbResults,
-                             metricName, fileName, tag=" averaged",
-                             train_STDs=trainSTDs, test_STDs=testSTDs)
+            plot_metric_scores(trainMeans, testMeans, names, nbResults,
+                               metricName, fileName, tag=" averaged",
+                               train_STDs=trainSTDs, test_STDs=testSTDs)
             results+=[[classifiersName, metricName, testMean, testSTD] for classifiersName, testMean, testSTD in zip(names, testMeans, testSTDs)]
     return results
 
@@ -839,7 +844,7 @@ def gen_error_dat_glob(combi_results, stats_iter, base_file_name):
 
 
 def publish_iter_biclass_example_errors(iter_results, directory, labels_dictionary,
-                                        classifiers_dict, stats_iter, min_size=10):
+                                        classifiers_dict, stats_iter, exmaple_ids, min_size=10):
     for labelsCombination, combiResults in iter_results.items():
         base_file_name = directory + labels_dictionary[
             int(labelsCombination[0])] + "-vs-" + \
@@ -847,18 +852,18 @@ def publish_iter_biclass_example_errors(iter_results, directory, labels_dictiona
                              int(labelsCombination[1])] + "/" + time.strftime(
             "%Y_%m_%d-%H_%M_%S") + "-"
         classifiers_names = [classifier_name for classifier_name in
-                            classifiers_dict.values()]
+                            classifiers_dict.keys()]
         logging.debug(
             "Start:\t Global biclass label analysis figure generation")
 
         nbExamples, nbClassifiers, data, error_on_examples = gen_error_dat_glob(
             combiResults, stats_iter, base_file_name)
 
-        publish2Dplot(data, classifiers_names, nbClassifiers, nbExamples, 1,
-                      base_file_name, stats_iter=stats_iter)
+        plot_2d(data, classifiers_names, nbClassifiers, nbExamples, 1,
+                base_file_name, stats_iter=stats_iter, example_ids=exmaple_ids)
 
-        publishErrorsBarPlot(error_on_examples, nbClassifiers * stats_iter,
-                             nbExamples, base_file_name)
+        plot_errors_bar(error_on_examples, nbClassifiers * stats_iter,
+                        nbExamples, base_file_name)
 
         logging.debug(
             "Done:\t Global biclass label analysis figures generation")
@@ -878,16 +883,16 @@ def publish_iter_multiclass_metrics_scores(iter_multiclass_results, classifiers_
             "%Y_%m_%d-%H_%M_%S") + "-" + data_base_name + "-Mean_on_" + str(
             stats_iter) + "_iter-" + metric_name + ".png"
 
-        plotMetricScores(trainMeans, testMeans, classifiers_names, nb_results,
-                         metric_name, file_name, tag=" averaged multiclass",
-                         train_STDs=trainSTDs, test_STDs=testSTDs)
+        plot_metric_scores(trainMeans, testMeans, classifiers_names, nb_results,
+                           metric_name, file_name, tag=" averaged multiclass",
+                           train_STDs=trainSTDs, test_STDs=testSTDs)
 
         results+=[[classifiers_name, metric_name,testMean, testSTD] for classifiers_name, testMean, testSTD in zip(classifiers_names, testMeans, testSTDs)]
     return results
 
 
 def publish_iter_multiclass_example_errors(iter_multiclass_results, directory,
-                                           classifiers_names, stats_iter, min_size=10):
+                                           classifiers_names, stats_iter, example_ids, min_size=10):
     logging.debug(
         "Start:\t Global multiclass label analysis figures generation")
     base_file_name = directory + time.strftime("%Y_%m_%d-%H_%M_%S") + "-"
@@ -895,11 +900,11 @@ def publish_iter_multiclass_example_errors(iter_multiclass_results, directory,
     nb_examples, nb_classifiers, data, error_on_examples = gen_error_dat_glob(
         iter_multiclass_results, stats_iter, base_file_name)
 
-    publish2Dplot(data, classifiers_names, nb_classifiers, nb_examples, 1,
-                  base_file_name, stats_iter=stats_iter)
+    plot_2d(data, classifiers_names, nb_classifiers, nb_examples, 1,
+            base_file_name, stats_iter=stats_iter, example_ids=example_ids)
 
-    publishErrorsBarPlot(error_on_examples, nb_classifiers * stats_iter, nb_examples,
-                         base_file_name)
+    plot_errors_bar(error_on_examples, nb_classifiers * stats_iter, nb_examples,
+                    base_file_name)
 
     logging.debug("Done:\t Global multiclass label analysis figures generation")
 
@@ -908,8 +913,7 @@ def gen_classifiers_dict(results, metrics):
     classifiers_dict = dict((classifier_name, classifierIndex)
                            for classifierIndex, classifier_name
                            in enumerate(
-        results[0][list(results[0].keys())[0]]["metrics_scores"][metrics[0][0]][
-            "classifiers_names"]))
+        list(results[list(results.keys())[0]]["metrics_scores"][0][metrics[0][0]].columns)))
     return classifiers_dict, len(classifiers_dict)
 
 
@@ -938,12 +942,17 @@ def add_new_metric(iter_biclass_results, metric, labels_combination, nb_classifi
 
 
 def analyzebiclass_iter(biclass_results, metrics, stats_iter, directory,
-                       labels_dictionary, data_base_name, nb_examples):
+                       labels_dictionary, data_base_name, nb_examples, example_ids):
     """Used to format the results in order to plot the mean results on the iterations"""
     iter_biclass_results = {}
     classifiers_dict, nb_classifiers = gen_classifiers_dict(biclass_results,
                                                           metrics)
 
+    for label_combination, biclass_result in biclass_results.items():
+        for iter_index, metric_score in enumerate(biclass_result["metrics_scores"]):
+            print(metric_score)
+
+
     for iter_index, biclass_result in enumerate(biclass_results):
         for labelsComination, results in biclass_result.items():
             for metric in metrics:
@@ -978,11 +987,11 @@ def analyzebiclass_iter(biclass_results, metrics, stats_iter, directory,
         data_base_name, stats_iter)
     publish_iter_biclass_example_errors(iter_biclass_results, directory,
                                         labels_dictionary, classifiers_dict,
-                                        stats_iter)
+                                        stats_iter, example_ids)
     return results
 
 def analyze_iter_multiclass(multiclass_results, directory, stats_iter, metrics,
-                           data_base_name, nb_examples):
+                           data_base_name, nb_examples, example_ids):
     """Used to mean the multiclass results on the iterations executed with different random states"""
 
     logging.debug("Start:\t Getting mean results for multiclass classification")
@@ -1019,19 +1028,19 @@ def analyze_iter_multiclass(multiclass_results, directory, stats_iter, metrics,
         iter_multiclass_results, classifiers_names,
         data_base_name, directory, stats_iter)
     publish_iter_multiclass_example_errors(iter_multiclass_results, directory,
-                                       classifiers_names, stats_iter)
+                                       classifiers_names, stats_iter, example_ids)
     return results
 
 
 def get_results(results, stats_iter, nb_multiclass, benchmark_argument_dictionaries,
                multiclass_labels, metrics,
                classification_indices, directories, directory, labels_dictionary,
-               nb_examples, nb_labels):
+               nb_examples, nb_labels, example_ids):
 
     """Used to analyze the results of the previous benchmarks"""
     data_base_name = benchmark_argument_dictionaries[0]["args"]["Base"]["name"]
     results_means_std, biclass_results = analyze_biclass(results, benchmark_argument_dictionaries,
-                                         stats_iter, metrics)
+                                         stats_iter, metrics, example_ids)
 
     if nb_multiclass > 1:
         results_means_std, multiclass_results = analyzeMulticlass(results, stats_iter,
@@ -1039,12 +1048,12 @@ def get_results(results, stats_iter, nb_multiclass, benchmark_argument_dictionar
                                               nb_examples, nb_labels,
                                               multiclass_labels, metrics,
                                               classification_indices,
-                                              directories)
+                                              directories, example_ids)
     if stats_iter > 1:
         results_means_std = analyzebiclass_iter(
             biclass_results, metrics, stats_iter, directory,
-            labels_dictionary, data_base_name, nb_examples)
+            labels_dictionary, data_base_name, nb_examples, example_ids)
         if nb_multiclass > 1:
             results_means_std = analyze_iter_multiclass(multiclass_results, directory, stats_iter,
-                                  metrics, data_base_name, nb_examples)
+                                  metrics, data_base_name, nb_examples, example_ids)
     return results_means_std
diff --git a/multiview_platform/mono_multi_view_classifiers/utils/dataset.py b/multiview_platform/mono_multi_view_classifiers/utils/dataset.py
index 991ee6a598daedd66db3de25cbebe0a27bccd165..1c3e59615df0fa1065c4c12f79cf77f717fbf4f6 100644
--- a/multiview_platform/mono_multi_view_classifiers/utils/dataset.py
+++ b/multiview_platform/mono_multi_view_classifiers/utils/dataset.py
@@ -66,7 +66,8 @@ class Dataset():
 
     def __init__(self, views=None, labels=None, are_sparse=False,
                  file_name="dataset.hdf5", view_names=None, path="",
-                 hdf5_file=None, labels_names=None, is_temp=False):
+                 hdf5_file=None, labels_names=None, is_temp=False,
+                 example_ids=None):
         self.is_temp = False
         if hdf5_file is not None:
             self.dataset=hdf5_file
@@ -104,6 +105,10 @@ class Dataset():
             meta_data_grp.attrs["datasetLength"] = len(labels)
             dataset_file.close()
             self.update_hdf5_dataset(os.path.join(path, file_name))
+            if example_ids is not None:
+                self.example_ids = example_ids
+            else:
+                self.example_ids = [str(i) for i in range(labels.shape[0])]
 
     def rm(self):
         """
@@ -146,6 +151,10 @@ class Dataset():
         """
         self.nb_view = self.dataset["Metadata"].attrs["nbView"]
         self.view_dict = self.get_view_dict()
+        if "example_ids"  in self.dataset["Metadata"].keys():
+            self.example_ids = self.dataset["Metadata"]["example_ids"]
+        else:
+            self.example_ids = [str(i) for i in range(self.dataset["Labels"].shape[0])]
 
     def get_nb_examples(self):
         """
diff --git a/multiview_platform/mono_multi_view_classifiers/utils/get_multiview_db.py b/multiview_platform/mono_multi_view_classifiers/utils/get_multiview_db.py
index 1e3e6a83d3f9408452794ef1cbd8874c5c5c170b..4ba4e24b5dec76e638cbdbc4267d5a3e88c005dd 100644
--- a/multiview_platform/mono_multi_view_classifiers/utils/get_multiview_db.py
+++ b/multiview_platform/mono_multi_view_classifiers/utils/get_multiview_db.py
@@ -44,6 +44,7 @@ def get_plausible_db_hdf5(features, path, file_name, nb_class=3,
         except OSError as exc:
             if exc.errno != errno.EEXIST:
                 raise
+    example_ids = ["exmaple_id_"+str(i) for i in range(nb_examples)]
     views = []
     view_names = []
     are_sparse = []
@@ -72,10 +73,12 @@ def get_plausible_db_hdf5(features, path, file_name, nb_class=3,
             view_names.append("ViewNumber" + str(view_index))
             are_sparse.append(False)
 
+
+
         dataset = Dataset(views=views, labels=labels,
                               labels_names=label_names, view_names=view_names,
                               are_sparse=are_sparse, file_name="plausible.hdf5",
-                              path=path)
+                              path=path, example_ids=example_ids)
         labels_dictionary = {0: "No", 1: "Yes"}
         return dataset, labels_dictionary, "plausible"
     elif nb_class >= 3:
@@ -114,7 +117,7 @@ def get_plausible_db_hdf5(features, path, file_name, nb_class=3,
                               labels_names=label_names, view_names=view_names,
                               are_sparse=are_sparse,
                               file_name="plausible.hdf5",
-                              path=path)
+                              path=path, example_ids=example_ids)
         labels_dictionary = {0: "No", 1: "Yes", 2: "Maybe"}
         return dataset, labels_dictionary, "plausible"
 
diff --git a/multiview_platform/tests/test_ExecClassif.py b/multiview_platform/tests/test_ExecClassif.py
index abbcd77f933e6c9f49dc74213388551bbe85e61d..ad86757828f53a732ded8785cbf0f199bbbdbc9d 100644
--- a/multiview_platform/tests/test_ExecClassif.py
+++ b/multiview_platform/tests/test_ExecClassif.py
@@ -219,7 +219,7 @@ def fakeBenchmarkExec_monocore(dataset_var=1, a=4, args=1):
 def fakegetResults(results, stats_iter, nb_multiclass,
                    benchmark_arguments_dictionaries, multi_class_labels, metrics,
                    classification_indices, directories, directory,
-                   labels_dictionary, nb_examples, nb_labels):
+                   labels_dictionary, nb_examples, nb_labels, example_ids):
     return 3
 
 
@@ -368,8 +368,7 @@ class Test_execOneBenchmark(unittest.TestCase):
                                                                     1, 2, 1, 1,
                                                                     2, 1, 21]),
                                                       exec_monoview_multicore=fakeExecMono,
-                                                      exec_multiview_multicore=fakeExecMulti,
-                                                      init_multiview_arguments=fakeInitMulti)
+                                                      exec_multiview_multicore=fakeExecMulti,)
 
         cls.assertEqual(flag, None)
         cls.assertEqual(results ,
@@ -428,8 +427,7 @@ class Test_execOneBenchmark_multicore(unittest.TestCase):
             flag=None,
             labels=np.array([0, 1, 2, 3, 4, 2, 2, 12, 1, 2, 1, 1, 2, 1, 21]),
             exec_monoview_multicore=fakeExecMono,
-            exec_multiview_multicore=fakeExecMulti,
-            init_multiview_arguments=fakeInitMulti)
+            exec_multiview_multicore=fakeExecMulti,)
 
         cls.assertEqual(flag, None)
         cls.assertEqual(results ,
diff --git a/multiview_platform/tests/test_ResultAnalysis.py b/multiview_platform/tests/test_ResultAnalysis.py
index bc739072790e9730058d7a9f916f66d512e7c31f..04531a2027d440c8019ab9771e689ec078db5657 100644
--- a/multiview_platform/tests/test_ResultAnalysis.py
+++ b/multiview_platform/tests/test_ResultAnalysis.py
@@ -1,56 +1,179 @@
-# import unittest
-# import numpy as np
-#
-# from ..mono_multi_view_classifiers import ResultAnalysis
-#
-#
-# class Test_getMetricsScoresBiclass(unittest.TestCase):
-#
-#     @classmethod
-#     def setUpClass(cls):
-#         cls.metrics = [["accuracy_score"]]
-#         cls.monoViewResults = [["", ["chicken_is_heaven", ["View0"], {"accuracy_score": [0.5,0.7]}]]]
-#         cls.multiviewResults = [["Mumbo", {"":""}, {"accuracy_score":[0.6,0.8]}]]
-#
-#     def test_simple(cls):
-#         res = ResultAnalysis.getMetricsScoresBiclass(cls.metrics, cls.monoViewResults, cls.multiviewResults)
-#         cls.assertIn("accuracy_score",res)
-#         cls.assertEqual(type(res["accuracy_score"]), dict)
-#         cls.assertEqual(res["accuracy_score"]["classifiers_names"], ["chicken_is_heaven-View0", "Mumbo"])
-#         cls.assertEqual(res["accuracy_score"]["train_scores"], [0.5, 0.6])
-#         cls.assertEqual(res["accuracy_score"]["test_scores"], [0.7, 0.8])
-#
-#     def test_only_multiview(cls):
-#         cls.monoViewResults = []
-#         res = ResultAnalysis.getMetricsScoresBiclass(cls.metrics, cls.monoViewResults, cls.multiviewResults)
-#         cls.assertIn("accuracy_score",res)
-#         cls.assertEqual(type(res["accuracy_score"]), dict)
-#         cls.assertEqual(res["accuracy_score"]["classifiers_names"], ["Mumbo"])
-#         cls.assertEqual(res["accuracy_score"]["train_scores"], [0.6])
-#         cls.assertEqual(res["accuracy_score"]["test_scores"], [0.8])
-#
-#     def test_only_monoview(cls):
-#         cls.multiviewResults = []
-#         res = ResultAnalysis.getMetricsScoresBiclass(cls.metrics, cls.monoViewResults, cls.multiviewResults)
-#         cls.assertIn("accuracy_score",res)
-#         cls.assertEqual(type(res["accuracy_score"]), dict)
-#         cls.assertEqual(res["accuracy_score"]["classifiers_names"], ["chicken_is_heaven-View0"])
-#         cls.assertEqual(res["accuracy_score"]["train_scores"], [0.5])
-#         cls.assertEqual(res["accuracy_score"]["test_scores"], [0.7])
-#
-#
-# class Test_getExampleErrorsBiclass(unittest.TestCase):
-#
-#     @classmethod
-#     def setUpClass(cls):
-#         cls.usedBenchmarkArgumentDictionary = {"labels": np.array([0,1,1,-100,-100,0,1,1,-100])}
-#         cls.monoViewResults = [["", ["chicken_is_heaven", ["View0"], {}, np.array([1,1,1,-100,-100,0,1,1,-100])]]]
-#         cls.multiviewResults = [["Mumbo", {"":""}, {}, np.array([0,0,1,-100,-100,0,1,1,-100])]]
-#
-#     def test_simple(cls):
-#         res = ResultAnalysis.getExampleErrorsBiclass(cls.usedBenchmarkArgumentDictionary, cls.monoViewResults,
-#                                                   cls.multiviewResults)
-#         cls.assertIn("chicken_is_heaven-View0", res)
-#         cls.assertIn("Mumbo", res)
-#         np.testing.assert_array_equal(res["Mumbo"], np.array([1,0,1,-100,-100,1,1,1,-100]))
-#         np.testing.assert_array_equal(res["chicken_is_heaven-View0"], np.array([0,1,1,-100,-100,1,1,1,-100]))
+import unittest
+import numpy as np
+import pandas as pd
+import time
+
+from ..mono_multi_view_classifiers import result_analysis
+from ..mono_multi_view_classifiers.multiview.multiview_utils import MultiviewResult
+from ..mono_multi_view_classifiers.monoview.monoview_utils import MonoviewResult
+
+
+class Test_get_arguments(unittest.TestCase):
+
+    def setUp(self):
+        self.benchamrk_argument_dictionaries = [{"flag":"good_flag", "valid":True},
+                                                {"flag":"bad_flag", "valid":False}]
+
+    def test_benchmark_wanted(self):
+        argument_dict = result_analysis.get_arguments(self.benchamrk_argument_dictionaries, "good_flag")
+        self.assertTrue(argument_dict["valid"])
+
+
+class Test_get_metrics_scores_biclass(unittest.TestCase):
+
+
+    def test_simple(self):
+        metrics = [["accuracy_score"], ["f1_score"]]
+        results = [MonoviewResult(0,
+                                  "ada",
+                                  "0",
+                                  {"accuracy_score":[0.9, 0.95],
+                                   "f1_score":[0.91, 0.96]}
+                                  , "", "", "", "")]
+        metrics_scores = result_analysis.get_metrics_scores_biclass(metrics,
+                                                                    results)
+        self.assertIsInstance(metrics_scores, dict)
+        self.assertIsInstance(metrics_scores["accuracy_score"], pd.DataFrame)
+        np.testing.assert_array_equal(np.array(metrics_scores["accuracy_score"].loc["train"]), np.array([0.9]))
+        np.testing.assert_array_equal(
+            np.array(metrics_scores["accuracy_score"].loc["test"]),
+            np.array([0.95]))
+        np.testing.assert_array_equal(
+            np.array(metrics_scores["f1_score"].loc["train"]),
+            np.array([0.91]))
+        np.testing.assert_array_equal(
+            np.array(metrics_scores["f1_score"].loc["test"]),
+            np.array([0.96]))
+        np.testing.assert_array_equal(np.array(metrics_scores["f1_score"].columns),
+                                      np.array(["ada-0"]))
+
+    def multiple_monoview_classifiers(self):
+        metrics = [["accuracy_score"], ["f1_score"]]
+        results = [MonoviewResult(0,
+                                  "ada",
+                                  "0",
+                                  {"accuracy_score": [0.9, 0.95],
+                                   "f1_score": [0.91, 0.96]}
+                                  , "", "", "", ""),
+                   MonoviewResult(0,
+                                  "dt",
+                                  "1",
+                                  {"accuracy_score": [0.8, 0.85],
+                                   "f1_score": [0.81, 0.86]}
+                                  , "", "", "", "")
+                   ]
+        metrics_scores = result_analysis.get_metrics_scores_biclass(metrics,
+                                                                    results)
+        self.assertIsInstance(metrics_scores, dict)
+        self.assertIsInstance(metrics_scores["accuracy_score"], pd.DataFrame)
+        np.testing.assert_array_equal(
+            np.array(metrics_scores["accuracy_score"].loc["train"]),
+            np.array([0.9, 0.8]))
+        np.testing.assert_array_equal(
+            np.array(metrics_scores["accuracy_score"].loc["test"]),
+            np.array([0.95, 0.85]))
+        np.testing.assert_array_equal(
+            np.array(metrics_scores["f1_score"].loc["train"]),
+            np.array([0.91, 0.81]))
+        np.testing.assert_array_equal(
+            np.array(metrics_scores["f1_score"].loc["test"]),
+            np.array([0.96, 0.86]))
+        np.testing.assert_array_equal(
+            np.array(metrics_scores["f1_score"].columns),
+            np.array(["ada-0", "dt-1"]))
+
+    def mutiview_result(self):
+        metrics = [["accuracy_score"], ["f1_score"]]
+        results = [MultiviewResult("mv", "", {"accuracy_score": [0.7, 0.75],
+                                   "f1_score": [0.71, 0.76]}, "", ""),
+                   MonoviewResult(0,
+                                  "dt",
+                                  "1",
+                                  {"accuracy_score": [0.8, 0.85],
+                                   "f1_score": [0.81, 0.86]}
+                                  , "", "", "", "")
+                   ]
+        metrics_scores = result_analysis.get_metrics_scores_biclass(metrics,
+                                                                    results)
+        self.assertIsInstance(metrics_scores, dict)
+        self.assertIsInstance(metrics_scores["accuracy_score"], pd.DataFrame)
+        np.testing.assert_array_equal(
+            np.array(metrics_scores["accuracy_score"].loc["train"]),
+            np.array([0.7, 0.8]))
+        np.testing.assert_array_equal(
+            np.array(metrics_scores["accuracy_score"].loc["test"]),
+            np.array([0.75, 0.85]))
+        np.testing.assert_array_equal(
+            np.array(metrics_scores["f1_score"].loc["train"]),
+            np.array([0.71, 0.81]))
+        np.testing.assert_array_equal(
+            np.array(metrics_scores["f1_score"].loc["test"]),
+            np.array([0.76, 0.86]))
+        np.testing.assert_array_equal(
+            np.array(metrics_scores["f1_score"].columns),
+            np.array(["mv", "dt-1"]))
+
+class Test_get_example_errors_biclass(unittest.TestCase):
+
+    def test_simple(self):
+        ground_truth = np.array([0,1,0,1,0,1,0,1, -100])
+        results = [MultiviewResult("mv", "", {"accuracy_score": [0.7, 0.75],
+                                              "f1_score": [0.71, 0.76]},
+                                   np.array([0,0,0,0,1,1,1,1,1]),
+                                   ""),
+                   MonoviewResult(0,
+                                  "dt",
+                                  "1",
+                                  {"accuracy_score": [0.8, 0.85],
+                                   "f1_score": [0.81, 0.86]}
+                                  , np.array([0,0,1,1,0,0,1,1,0]), "", "", "")
+                   ]
+        example_errors = result_analysis.get_example_errors_biclass(ground_truth,
+                                                                    results)
+        self.assertIsInstance(example_errors, dict)
+        np.testing.assert_array_equal(example_errors["mv"],
+                                      np.array([1,0,1,0,0,1,0,1,-100]))
+        np.testing.assert_array_equal(example_errors["dt-1"],
+                                      np.array([1, 0, 0, 1, 1, 0, 0, 1,-100]))
+
+
+class Test_init_plot(unittest.TestCase):
+
+    def test_simple(self):
+        results = []
+        metric_name = "acc"
+        data = np.random.RandomState(42).uniform(0,1,(2,2))
+        metric_dataframe = pd.DataFrame(index=["train", "test"], columns=["dt-1", "mv"], data=data)
+        directory = "dir"
+        database_name = 'db'
+        labels_names = ['lb1', "lb2"]
+        train, test, classifier_names, \
+        file_name, nb_results, results = result_analysis.init_plot(results,
+                                                                   metric_name,
+                                                                   metric_dataframe,
+                                                                   directory,
+                                                                   database_name,
+                                                                   labels_names)
+        self.assertEqual(file_name, "dir"+time.strftime(
+            "%Y_%m_%d-%H_%M_%S")+"-db-lb1_vs_lb2-acc")
+        np.testing.assert_array_equal(train, data[0,:])
+        np.testing.assert_array_equal(test, data[1, :])
+        np.testing.assert_array_equal(classifier_names, np.array(["dt-1", "mv"]))
+        self.assertEqual(nb_results, 2)
+        self.assertEqual(results, [["dt-1", "acc", data[1,0], 0], ["mv", "acc", data[1,1], 0]])
+
+class Test_gen_error_data(unittest.TestCase):
+
+    def test_simple(self):
+        random_state = np.random.RandomState(42)
+        ada_data = random_state.randint(0,2,size=7)
+        mv_data = random_state.randint(0, 2, size=7)
+        example_errors = {"ada-1": ada_data,
+                          "mv": mv_data}
+        nb_classifiers, nb_examples, classifiers_names, \
+        data_2d, error_on_examples = result_analysis.gen_error_data(example_errors)
+        self.assertEqual(nb_classifiers, 2)
+        self.assertEqual(nb_examples, 7)
+        self.assertEqual(classifiers_names, ["ada-1", "mv"])
+        np.testing.assert_array_equal(data_2d, np.array([ada_data, mv_data]).transpose())
+        np.testing.assert_array_equal(error_on_examples, -1*(ada_data+mv_data)/nb_classifiers)
\ No newline at end of file
diff --git a/requirements.txt b/requirements.txt
index a99989254c35ff3dfa00bfb97997f888a40caa89..51d86630547f58db44af3f661421c6b5a1edb571 100755
--- a/requirements.txt
+++ b/requirements.txt
@@ -14,4 +14,5 @@ pandas==0.23.3
 m2r==0.2.1
 docutils==0.12
 pyyaml==3.12
-cvxopt==1.2.0
\ No newline at end of file
+cvxopt==1.2.0
+plotly==4.2.1
\ No newline at end of file
diff --git a/setup.py b/setup.py
index 3bc02d0f1fa3a6d2d666ac213262ba4f34a77a6d..885aa563ed0c272941262dd22fa4ef9bd33553f8 100644
--- a/setup.py
+++ b/setup.py
@@ -55,7 +55,7 @@ def setup_package():
     install_requires=['numpy>=1.16', 'scipy>=0.16','scikit-learn==0.19',
                       'matplotlib', 'h5py', 'joblib',
                       'pandas', 'm2r', 'pyyaml', 'pyscm @ git+https://github.com/aldro61/pyscm',
-                      'cvxopt'],
+                      'cvxopt', 'plotly==4.2.1'],
 
     # Il est d'usage de mettre quelques metadata à propos de sa lib
     # Pour que les robots puissent facilement la classer.