예제 #1
0
    def _update_plots(self, sample_id, data_buffer):
        self._sample_ids.append(sample_id)
        memory_time = {}
        for metric_id, data_ids in data_buffer.data_dict.items():
            # update_xy_limits = True
            update_xy_limits = metric_id not in [
                constants.RUNNING_TIME, constants.MODEL_SIZE
            ]
            y_min = 0.0
            y_max = 1.0
            pad = 0.1  # Default padding to set above and bellow plots
            plot_tracker = self._plot_trackers[metric_id]
            if metric_id == constants.TRUE_VS_PREDICTED:
                # Process true values
                data_id = constants.Y_TRUE
                plot_tracker.data[data_id].append(
                    data_buffer.get_data(metric_id=metric_id, data_id=data_id))
                plot_tracker.line_objs[data_id].set_data(
                    self._sample_ids, plot_tracker.data[data_id])
                # Process predicted values
                data_id = constants.Y_PRED
                data = data_buffer.get_data(metric_id=metric_id,
                                            data_id=data_id)
                for i in range(self.n_models):
                    plot_tracker.data[data_id][i].append(data[i])
                    plot_tracker.line_objs[data_id][i].set_data(
                        self._sample_ids, plot_tracker.data[data_id][i])
                    y_min = min([
                        plot_tracker.data[data_id][i][-1],
                        plot_tracker.data[constants.Y_TRUE][-1], y_min
                    ])
                    y_max = max([
                        plot_tracker.data[data_id][i][-1],
                        plot_tracker.data[constants.Y_TRUE][-1], y_max
                    ])
            elif metric_id == constants.DATA_POINTS:
                update_xy_limits = False
                # Process features
                data_id = 'X'
                features_dict = data_buffer.get_data(metric_id=metric_id,
                                                     data_id=data_id)
                feature_indices = list(features_dict.keys())
                feature_indices.sort()
                # Store tuple of feature values into the buffer, sorted by index
                plot_tracker.data[data_id].add_element([[
                    features_dict[feature_indices[0]],
                    features_dict[feature_indices[1]]
                ]])

                plot_tracker.sub_plot_obj.set_xlabel('Feature {}'.format(
                    feature_indices[0]))
                plot_tracker.sub_plot_obj.set_ylabel('Feature {}'.format(
                    feature_indices[1]))
                # TODO consider a fading/update strategy instead
                plot_tracker.sub_plot_obj.clear()
                X1 = plot_tracker.data[data_id].get_queue()[-1][0]
                X2 = plot_tracker.data[data_id].get_queue()[-1][1]

                # Process target values
                data_id = 'target_values'
                plot_tracker.data[data_id] = data_buffer.get_data(
                    metric_id=metric_id, data_id=data_id)
                if not plot_tracker.data['clusters_initialized']:
                    for j in range(len(plot_tracker.data[data_id])):
                        plot_tracker.data['clusters'].append(
                            FastBuffer(plot_tracker.data['buffer_size']))

                # Process predictions
                data_id = 'predictions'
                plot_tracker.data[data_id].add_element([
                    data_buffer.get_data(metric_id=metric_id, data_id=data_id)
                ])

                for k, cluster in enumerate(plot_tracker.data['clusters']):
                    if plot_tracker.data[data_id].get_queue()[-1] == k:
                        plot_tracker.data['clusters'][k].add_element([(X1, X2)
                                                                      ])
                        # TODO confirm buffer update inside the loop
                    if cluster.get_queue():
                        temp = cluster.get_queue()
                        plot_tracker.sub_plot_obj.scatter(
                            *zip(*temp), label="Class {k}".format(k=k))
                plot_tracker.sub_plot_obj.legend(loc=2,
                                                 bbox_to_anchor=(1.01, 1.))
            elif metric_id == constants.RUNNING_TIME:
                # Only the current time measurement must be saved
                for data_id in data_ids:
                    plot_tracker.data[data_id] = data_buffer.get_data(
                        metric_id=metric_id, data_id=data_id)
                memory_time.update(plot_tracker.data)

            elif metric_id == constants.MODEL_SIZE:
                plot_tracker.data['model_size'] = data_buffer.get_data(
                    metric_id=metric_id, data_id='model_size')
                memory_time['model_size'] = plot_tracker.data['model_size']
            else:
                # Default case, 'mean' and 'current' performance
                for data_id in data_ids:
                    # Buffer data
                    data = data_buffer.get_data(metric_id=metric_id,
                                                data_id=data_id)
                    for i in range(self.n_models):
                        plot_tracker.data[data_id][i].append(data[i])
                        plot_tracker.line_objs[data_id][i].set_data(
                            self._sample_ids, plot_tracker.data[data_id][i])
                # Process data
                for i in range(self.n_models):
                    # Update annotations
                    self._update_annotations(
                        i, plot_tracker.sub_plot_obj, self.model_names[i],
                        plot_tracker.data[constants.MEAN][i][-1],
                        plot_tracker.data[constants.CURRENT][i][-1])
                    # Update plot limits
                    if metric_id in [constants.KAPPA_T, constants.KAPPA_M]:
                        y_min = min([
                            plot_tracker.data[constants.MEAN][i][-1],
                            plot_tracker.data[constants.CURRENT][i][-1], y_min
                        ])
                    if metric_id in [
                            constants.MSE, constants.MAE, constants.AMSE,
                            constants.AMAE, constants.ARMSE
                    ]:
                        y_min = -1
                        y_max = max([
                            plot_tracker.data[constants.MEAN][i][-1],
                            plot_tracker.data[constants.CURRENT][i][-1], y_max
                        ])
                        pad = 0.5 * y_max  # Padding bellow and above thresholds
            if update_xy_limits:
                plot_tracker.sub_plot_obj.set_ylim((y_min - pad, y_max + pad))
                plot_tracker.sub_plot_obj.set_xlim(0, self._sample_ids[-1])
        if constants.RUNNING_TIME in self.metrics or \
                constants.MODEL_SIZE in self.metrics:
            self._update_time_and_memory_annotations(memory_time)
예제 #2
0
 def __configure(self):
     self.window = FastBuffer(max_size=self.window_size)
예제 #3
0
    def __configure(self):
        """  This function will verify which subplots should be create. Initializing
        all relevant objects to keep track of the plotting points.
        
        Basic structures needed to keep track of plot values (for each subplot) 
        are: lists of values and matplot line objects.
        
        The __configure function will also initialize each subplot with the 
        correct name and setup the axis.
        
        The subplot size will self adjust to each screen size, so that data can 
        be better viewed in different contexts.

        """
        font_size_small = 8
        font_size_medium = 10
        font_size_large = 12

        plt.rc('font', size=font_size_small)  # controls default text sizes
        plt.rc('axes',
               titlesize=font_size_medium)  # font size of the axes title
        plt.rc('axes',
               labelsize=font_size_small)  # font size of the x and y labels
        plt.rc('xtick',
               labelsize=font_size_small)  # font size of the tick labels
        plt.rc('ytick',
               labelsize=font_size_small)  # font size of the tick labels
        plt.rc('legend', fontsize=font_size_small)  # legend font size
        plt.rc('figure',
               titlesize=font_size_large)  # font size of the figure title

        warnings.filterwarnings("ignore", ".*GUI is implemented.*")
        warnings.filterwarnings("ignore", ".*left==right.*")
        warnings.filterwarnings("ignore", ".*Passing 1d.*")

        self._sample_ids = []
        memory_time = {}

        plt.ion()
        self.fig = plt.figure(figsize=(9, 5))
        self.fig.suptitle(self.dataset_name)
        plot_metrics = [
            m for m in self.metrics
            if m not in [constants.RUNNING_TIME, constants.MODEL_SIZE]
        ]
        base = 11 + len(
            plot_metrics
        ) * 100  # 3-digit integer describing the position of the subplot.
        self.fig.canvas.set_window_title('scikit-multiflow')

        # Subplots handler
        for metric_id in self.metrics:
            data_ids = self._data_dict[metric_id]
            self._plot_trackers[metric_id] = PlotDataTracker(data_ids)
            plot_tracker = self._plot_trackers[metric_id]
            if metric_id not in [constants.RUNNING_TIME, constants.MODEL_SIZE]:
                plot_tracker.sub_plot_obj = self.fig.add_subplot(base)
            base += 1
            if metric_id == constants.TRUE_VS_PREDICTED:
                handle = []
                plot_tracker.sub_plot_obj.set_prop_cycle(
                    cycler('color', ['c', 'm', 'y', 'k']))
                for data_id in data_ids:
                    if data_id == constants.Y_TRUE:
                        # True data
                        plot_tracker.data[data_id] = []
                        label = 'True value'
                        line_style = '--'
                        line_obj = plot_tracker.line_objs
                        if self.task_type == constants.CLASSIFICATION:
                            line_obj[
                                data_id], = plot_tracker.sub_plot_obj.step(
                                    self._sample_ids,
                                    plot_tracker.data[data_id],
                                    label=label,
                                    linestyle=line_style)
                        else:
                            line_obj[
                                data_id], = plot_tracker.sub_plot_obj.plot(
                                    self._sample_ids,
                                    plot_tracker.data[data_id],
                                    label=label,
                                    linestyle=line_style)
                        handle.append(line_obj[data_id])
                    else:
                        # Predicted data
                        plot_tracker.data[data_id] = [
                            [] for _ in range(self.n_models)
                        ]
                        plot_tracker.line_objs[data_id] = [
                            None for _ in range(self.n_models)
                        ]
                        line_obj = plot_tracker.line_objs[data_id]
                        for i in range(self.n_models):
                            label = 'Predicted {}'.format(self.model_names[i])
                            line_style = '--'
                            if self.task_type == constants.CLASSIFICATION:
                                line_obj[i], = plot_tracker.sub_plot_obj.step(
                                    self._sample_ids,
                                    plot_tracker.data[data_id][i],
                                    label=label,
                                    linestyle=line_style)
                            else:
                                line_obj[i], = plot_tracker.sub_plot_obj.plot(
                                    self._sample_ids,
                                    plot_tracker.data[data_id][i],
                                    label=label,
                                    linestyle=line_style)
                            handle.append(line_obj[i])
                plot_tracker.sub_plot_obj.legend(handles=handle,
                                                 loc=2,
                                                 bbox_to_anchor=(1.01, 1.))
                plot_tracker.sub_plot_obj.set_title('True vs Predicted')
                plot_tracker.sub_plot_obj.set_ylabel('y')

            elif metric_id == constants.DATA_POINTS:
                plot_tracker.data['buffer_size'] = 100
                plot_tracker.data['X'] = FastBuffer(
                    plot_tracker.data['buffer_size'])
                plot_tracker.data['target_values'] = None
                plot_tracker.data['predictions'] = FastBuffer(
                    plot_tracker.data['buffer_size'])
                plot_tracker.data['clusters'] = []
                plot_tracker.data['clusters_initialized'] = False

            elif metric_id == constants.RUNNING_TIME:
                # Only the current time measurement must be saved
                for data_id in data_ids:
                    plot_tracker.data[data_id] = [
                        0.0 for _ in range(self.n_models)
                    ]
                # To make the annotations
                memory_time.update(plot_tracker.data)

            elif metric_id == constants.MODEL_SIZE:
                plot_tracker.data['model_size'] = [
                    0.0 for _ in range(self.n_models)
                ]

                memory_time['model_size'] = plot_tracker.data['model_size']
            else:
                # Default case, 'mean' and 'current' performance
                handle = []
                sorted_data_ids = data_ids.copy()
                sorted_data_ids.sort(
                )  # For better usage of the color cycle, start with 'current' data
                for data_id in sorted_data_ids:
                    plot_tracker.data[data_id] = [[]
                                                  for _ in range(self.n_models)
                                                  ]
                    plot_tracker.line_objs[data_id] = [
                        None for _ in range(self.n_models)
                    ]
                    line_obj = plot_tracker.line_objs[data_id]
                    for i in range(self.n_models):
                        if data_id == constants.CURRENT:
                            label = '{}  (current, {} samples)'.format(
                                self.model_names[i], self.n_wait)
                            line_style = '-'
                        else:
                            label = '{} (mean)'.format(self.model_names[i])
                            line_style = ':'
                        line_obj[i], = plot_tracker.sub_plot_obj.plot(
                            self._sample_ids,
                            plot_tracker.data[data_id][i],
                            label=label,
                            linestyle=line_style)
                        handle.append(line_obj[i])
                self._set_fig_legend(handle)

                if metric_id == constants.ACCURACY:
                    plot_tracker.sub_plot_obj.set_title('Accuracy')
                    plot_tracker.sub_plot_obj.set_ylabel('acc')
                elif metric_id == constants.KAPPA:
                    plot_tracker.sub_plot_obj.set_title('Kappa')
                    plot_tracker.sub_plot_obj.set_ylabel('kappa')
                elif metric_id == constants.KAPPA_T:
                    plot_tracker.sub_plot_obj.set_title('Kappa T')
                    plot_tracker.sub_plot_obj.set_ylabel('kappa t')
                elif metric_id == constants.KAPPA_M:
                    plot_tracker.sub_plot_obj.set_title('Kappa M')
                    plot_tracker.sub_plot_obj.set_ylabel('kappa m')
                elif metric_id == constants.HAMMING_SCORE:
                    plot_tracker.sub_plot_obj.set_title('Hamming score')
                    plot_tracker.sub_plot_obj.set_ylabel('hamming score')
                elif metric_id == constants.HAMMING_LOSS:
                    plot_tracker.sub_plot_obj.set_title('Hamming loss')
                    plot_tracker.sub_plot_obj.set_ylabel('hamming loss')
                elif metric_id == constants.EXACT_MATCH:
                    plot_tracker.sub_plot_obj.set_title('Exact Match')
                    plot_tracker.sub_plot_obj.set_ylabel('exact match')
                elif metric_id == constants.J_INDEX:
                    plot_tracker.sub_plot_obj.set_title('Jaccard Index')
                    plot_tracker.sub_plot_obj.set_ylabel('j-index')
                elif metric_id == constants.MSE:
                    plot_tracker.sub_plot_obj.set_title('Mean Squared Error')
                    plot_tracker.sub_plot_obj.set_ylabel('mse')
                elif metric_id == constants.MAE:
                    plot_tracker.sub_plot_obj.set_title('Mean Absolute Error')
                    plot_tracker.sub_plot_obj.set_ylabel('mae')
                elif metric_id == constants.AMSE:
                    plot_tracker.sub_plot_obj.set_title(
                        'Average Mean Squared Error')
                    plot_tracker.sub_plot_obj.set_ylabel('amse')
                elif metric_id == constants.AMAE:
                    plot_tracker.sub_plot_obj.set_title(
                        'Average Mean Absolute Error')
                    plot_tracker.sub_plot_obj.set_ylabel('amae')
                elif metric_id == constants.ARMSE:
                    plot_tracker.sub_plot_obj.set_title(
                        'Average Root Mean Squared Error')
                    plot_tracker.sub_plot_obj.set_ylabel('armse')
                elif metric_id == constants.DATA_POINTS:
                    plot_tracker.sub_plot_obj.set_title('')
                    plot_tracker.sub_plot_obj.set_xlabel('Feature x')
                    plot_tracker.sub_plot_obj.set_ylabel('Feature y')
                else:
                    plot_tracker.sub_plot_obj.set_title('Unknown metric')
                    plot_tracker.sub_plot_obj.set_ylabel('')

        if constants.DATA_POINTS not in self.metrics:
            plt.xlabel('Samples')
        if constants.RUNNING_TIME in self.metrics or \
                constants.MODEL_SIZE in self.metrics:
            self._update_time_and_memory_annotations(memory_time)

        self.fig.subplots_adjust(hspace=.5)
        self.fig.tight_layout(rect=[0, .04, 1, 0.98],
                              pad=2.6,
                              w_pad=0.4,
                              h_pad=1.0)
    def _update_metrics(self):
        """ _update_metrics

        Updates the metrics of interest. This function creates a metrics dictionary,
        which will be sent to _update_outputs, in order to save the data (if configured)

        Creates/updates a dictionary of new evaluation points. The keys of this dictionary are
        the metrics to keep track of, and the values are two element lists, or tuples, containing
        each metric's global value and their partial value (measured from the last n_wait samples).

        If more than one learner is evaluated at once, the value from the dictionary
        will be a list of lists, or tuples, containing the global metric value and
        the partial metric value, for each of the learners.

        """
        new_points_dict = {}
        if self.PERFORMANCE in self.metrics:
            new_points_dict[self.PERFORMANCE] = [[self.global_classification_metrics[i].get_performance(),
                                                  self.partial_classification_metrics[i].get_performance()]
                                                 for i in range(self.n_models)]

        if self.KAPPA in self.metrics:
            new_points_dict[self.KAPPA] = [[self.global_classification_metrics[i].get_kappa(),
                                            self.partial_classification_metrics[i].get_kappa()]
                                           for i in range(self.n_models)]

        if self.KAPPA_T in self.metrics:
            new_points_dict[self.KAPPA_T] = [[self.global_classification_metrics[i].get_kappa_t(),
                                              self.partial_classification_metrics[i].get_kappa_t()]
                                             for i in range(self.n_models)]

        if self.KAPPA_M in self.metrics:
            new_points_dict[self.KAPPA_M] = [[self.global_classification_metrics[i].get_kappa_m(),
                                              self.partial_classification_metrics[i].get_kappa_m()]
                                             for i in range(self.n_models)]

        if self.HAMMING_SCORE in self.metrics:
            new_points_dict[self.HAMMING_SCORE] = [[self.global_classification_metrics[i].get_hamming_score(),
                                                    self.partial_classification_metrics[i].get_hamming_score()]
                                                   for i in range(self.n_models)]

        if self.HAMMING_LOSS in self.metrics:
            new_points_dict[self.HAMMING_LOSS] = [[self.global_classification_metrics[i].get_hamming_loss(),
                                                   self.partial_classification_metrics[i].get_hamming_loss()]
                                                  for i in range(self.n_models)]

        if self.EXACT_MATCH in self.metrics:
            new_points_dict[self.EXACT_MATCH] = [[self.global_classification_metrics[i].get_exact_match(),
                                                  self.partial_classification_metrics[i].get_exact_match()]
                                                 for i in range(self.n_models)]

        if self.J_INDEX in self.metrics:
            new_points_dict[self.J_INDEX] = [[self.global_classification_metrics[i].get_j_index(),
                                              self.partial_classification_metrics[i].get_j_index()]
                                             for i in range(self.n_models)]

        if self.MSE in self.metrics:
            new_points_dict[self.MSE] = [[self.global_classification_metrics[i].get_mean_square_error(),
                                          self.partial_classification_metrics[i].get_mean_square_error()]
                                         for i in range(self.n_models)]

        if self.MAE in self.metrics:
            new_points_dict[self.MAE] = [[self.global_classification_metrics[i].get_average_error(),
                                          self.partial_classification_metrics[i].get_average_error()]
                                         for i in range(self.n_models)]

        if self.TRUE_VS_PREDICTED in self.metrics:
            true, pred = [], []
            for i in range(self.n_models):
                t, p = self.global_classification_metrics[i].get_last()
                true.append(t)
                pred.append(p)
            new_points_dict[self.TRUE_VS_PREDICTED] = [[true[i], pred[i]] for i in range(self.n_models)]

        if self.DATA_POINTS in self.metrics:

            targets = self.stream.target_values
            pred = []
            samples = FastBuffer(5000)

            for i in range(self.n_models):
                _, p = self.global_classification_metrics[i].get_last()
                X = self.global_classification_metrics[i].get_last_sample()

                pred.append(p)
                samples.add_element([X])

            new_points_dict[self.DATA_POINTS] = [[[samples.get_queue()[i]], targets, pred[i]]
                                                 for i in range(self.n_models)]

        shift = 0
        if self._method == 'prequential':
            shift = -self.batch_size   # Adjust index due to training after testing
        self._update_outputs(self.global_sample_count + shift, new_points_dict)
 def __configure(self):
     if self.strategy in ['mean', 'median', 'mode']:
         self.window = FastBuffer(max_size=self.window_size)
예제 #6
0
    def draw(self, train_step, metrics_dict):
        """ draw
        
        Updates and redraws the plot.
        
        Parameters
        ----------
        train_step: int
            The number of samples processed to this moment.
        
        metrics_dict: dictionary
            A dictionary containing tuples, where the first element is the 
            string that identifies one of the plot's subplot names, and the 
            second element is its numerical value.
             
        """

        self.sample_id.append(train_step)

        self._clear_annotations()

        if constants.ACCURACY in self.plots:
            for i in range(self.n_learners):
                self.mean_accuracy[i].append(
                    metrics_dict[constants.ACCURACY][i][0])
                self.current_accuracy[i].append(
                    metrics_dict[constants.ACCURACY][i][1])
                self.line_mean_accuracy[i].set_data(self.sample_id,
                                                    self.mean_accuracy[i])
                self.line_current_accuracy[i].set_data(
                    self.sample_id, self.current_accuracy[i])

                self._update_annotations(i, self.subplot_accuracy,
                                         self.model_names[i],
                                         self.mean_accuracy[i][-1],
                                         self.current_accuracy[i][-1])

            self.subplot_accuracy.set_xlim(0, self.sample_id[-1])
            self.subplot_accuracy.set_ylim(0, 1)

        if constants.KAPPA in self.plots:
            for i in range(self.n_learners):
                self.mean_kappa[i].append(metrics_dict[constants.KAPPA][i][0])
                self.current_kappa[i].append(
                    metrics_dict[constants.KAPPA][i][1])
                self.line_mean_kappa[i].set_data(self.sample_id,
                                                 self.mean_kappa[i])
                self.line_current_kappa[i].set_data(self.sample_id,
                                                    self.current_kappa[i])

                self._update_annotations(i, self.subplot_kappa,
                                         self.model_names[i],
                                         self.mean_kappa[i][-1],
                                         self.current_kappa[i][-1])

            self.subplot_kappa.set_xlim(0, self.sample_id[-1])
            self.subplot_kappa.set_ylim(0, 1)

        if constants.KAPPA_T in self.plots:
            minimum = -1.
            for i in range(self.n_learners):
                self.mean_kappa_t[i].append(
                    metrics_dict[constants.KAPPA_T][i][0])
                self.current_kappa_t[i].append(
                    metrics_dict[constants.KAPPA_T][i][1])
                self.line_mean_kappa_t[i].set_data(self.sample_id,
                                                   self.mean_kappa_t[i])
                self.line_current_kappa_t[i].set_data(self.sample_id,
                                                      self.current_kappa_t[i])

                self._update_annotations(i, self.subplot_kappa_t,
                                         self.model_names[i],
                                         self.mean_kappa_t[i][-1],
                                         self.current_kappa_t[i][-1])

                minimum = min(min(minimum, min(self.mean_kappa_t[i])),
                              min(minimum, min(self.current_kappa_t[i])))

            self.subplot_kappa_t.set_xlim(0, self.sample_id[-1])
            self.subplot_kappa_t.set_ylim([minimum, 1.])

        if constants.KAPPA_M in self.plots:
            minimum = -1.
            for i in range(self.n_learners):
                self.mean_kappa_m[i].append(
                    metrics_dict[constants.KAPPA_M][i][0])
                self.current_kappa_m[i].append(
                    metrics_dict[constants.KAPPA_M][i][1])
                self.line_mean_kappa_m[i].set_data(self.sample_id,
                                                   self.mean_kappa_m[i])
                self.line_current_kappa_m[i].set_data(self.sample_id,
                                                      self.current_kappa_m[i])

                self._update_annotations(i, self.subplot_kappa_m,
                                         self.model_names[i],
                                         self.mean_kappa_m[i][-1],
                                         self.current_kappa_m[i][-1])

                minimum = min(min(minimum, min(self.mean_kappa_m[i])),
                              min(minimum, min(self.current_kappa_m[i])))

            self.subplot_kappa_m.set_xlim(0, self.sample_id[-1])
            self.subplot_kappa_m.set_ylim(minimum, 1.)

        if constants.HAMMING_SCORE in self.plots:
            for i in range(self.n_learners):
                self.mean_hamming_score[i].append(
                    metrics_dict[constants.HAMMING_SCORE][i][0])
                self.current_hamming_score[i].append(
                    metrics_dict[constants.HAMMING_SCORE][i][1])
                self.line_mean_hamming_score[i].set_data(
                    self.sample_id, self.mean_hamming_score[i])
                self.line_current_hamming_score[i].set_data(
                    self.sample_id, self.current_hamming_score[i])

                self._update_annotations(i, self.subplot_hamming_score,
                                         self.model_names[i],
                                         self.mean_hamming_score[i][-1],
                                         self.current_hamming_score[i][-1])

            self.subplot_hamming_score.set_xlim(0, self.sample_id[-1])
            self.subplot_hamming_score.set_ylim(0, 1)

        if constants.HAMMING_LOSS in self.plots:
            for i in range(self.n_learners):
                self.mean_hamming_loss[i].append(
                    metrics_dict[constants.HAMMING_LOSS][i][0])
                self.current_hamming_loss[i].append(
                    metrics_dict[constants.HAMMING_LOSS][i][1])
                self.line_mean_hamming_loss[i].set_data(
                    self.sample_id, self.mean_hamming_loss[i])
                self.line_current_hamming_loss[i].set_data(
                    self.sample_id, self.current_hamming_loss[i])

                self._update_annotations(i, self.subplot_hamming_loss,
                                         self.model_names[i],
                                         self.mean_hamming_loss[i][-1],
                                         self.current_hamming_loss[i][-1])

            self.subplot_hamming_loss.set_xlim(0, self.sample_id[-1])
            self.subplot_hamming_loss.set_ylim(0, 1)

        if constants.EXACT_MATCH in self.plots:
            for i in range(self.n_learners):
                self.mean_exact_match[i].append(
                    metrics_dict[constants.EXACT_MATCH][i][0])
                self.current_exact_match[i].append(
                    metrics_dict[constants.EXACT_MATCH][i][1])
                self.line_mean_exact_match[i].set_data(
                    self.sample_id, self.mean_exact_match[i])
                self.line_current_exact_match[i].set_data(
                    self.sample_id, self.current_exact_match[i])

                self._update_annotations(i, self.subplot_exact_match,
                                         self.model_names[i],
                                         self.mean_exact_match[i][-1],
                                         self.current_exact_match[i][-1])

            self.subplot_exact_match.set_xlim(0, self.sample_id[-1])
            self.subplot_exact_match.set_ylim(0, 1)

        if constants.J_INDEX in self.plots:
            for i in range(self.n_learners):
                self.mean_j_index[i].append(
                    metrics_dict[constants.J_INDEX][i][0])
                self.current_j_index[i].append(
                    metrics_dict[constants.J_INDEX][i][1])
                self.line_mean_j_index[i].set_data(self.sample_id,
                                                   self.mean_j_index[i])
                self.line_current_j_index[i].set_data(self.sample_id,
                                                      self.current_j_index[i])

                self._update_annotations(i, self.subplot_j_index,
                                         self.model_names[i],
                                         self.mean_j_index[i][-1],
                                         self.current_j_index[i][-1])

            self.subplot_j_index.set_xlim(0, self.sample_id[-1])
            self.subplot_j_index.set_ylim(0, 1)

        if constants.MSE in self.plots:
            minimum = -1
            maximum = 0
            for i in range(self.n_learners):
                self.mean_mse[i].append(metrics_dict[constants.MSE][i][0])
                self.current_mse[i].append(metrics_dict[constants.MSE][i][1])
                self.line_mean_mse[i].set_data(self.sample_id,
                                               self.mean_mse[i])
                self.line_current_mse[i].set_data(self.sample_id,
                                                  self.current_mse[i])

                self._update_annotations(i, self.subplot_mse,
                                         self.model_names[i],
                                         self.mean_mse[i][-1],
                                         self.current_mse[i][-1])

                # minimum = min([min(self.mean_mse[i]), min(self.current_mse[i]), minimum])
                maximum = max(
                    [max(self.mean_mse[i]),
                     max(self.current_mse[i]), maximum])

            self.subplot_mse.set_xlim(0, self.sample_id[-1])
            self.subplot_mse.set_ylim(minimum, 1.2 * maximum)

        if constants.MAE in self.plots:
            minimum = -1
            maximum = 0
            for i in range(self.n_learners):
                self.mean_mae[i].append(metrics_dict[constants.MAE][i][0])
                self.current_mae[i].append(metrics_dict[constants.MAE][i][1])
                self.line_mean_mae[i].set_data(self.sample_id,
                                               self.mean_mae[i])
                self.line_current_mae[i].set_data(self.sample_id,
                                                  self.current_mae[i])

                self._update_annotations(i, self.subplot_mae,
                                         self.model_names[i],
                                         self.mean_mae[i][-1],
                                         self.current_mae[i][-1])

                # minimum = min([min(self.mean_mae[i]), min(self.current_mae[i]), minimum])
                maximum = max(
                    [max(self.mean_mae[i]),
                     max(self.current_mae[i]), maximum])

            self.subplot_mae.set_xlim(0, self.sample_id[-1])
            self.subplot_mae.set_ylim(minimum, 1.2 * maximum)

        if constants.TRUE_VS_PREDICTED in self.plots:
            self.true_values.append(
                metrics_dict[constants.TRUE_VS_PREDICTED][0][0])
            self.line_true.set_data(self.sample_id, self.true_values)
            minimum = 0
            maximum = 0
            for i in range(self.n_learners):
                self.pred_values[i].append(
                    metrics_dict[constants.TRUE_VS_PREDICTED][i][1])
                self.line_pred[i].set_data(self.sample_id, self.pred_values[i])
                minimum = min(
                    [min(self.pred_values[i]),
                     min(self.true_values), minimum])
                maximum = max(
                    [max(self.pred_values[i]),
                     max(self.true_values), maximum])

            self.subplot_true_vs_predicted.set_xlim(0, self.sample_id[-1])
            self.subplot_true_vs_predicted.set_ylim(minimum - 1, maximum + 1)

            self.subplot_true_vs_predicted.legend(loc=2,
                                                  bbox_to_anchor=(1.01, 1.))

        if constants.DATA_POINTS in self.plots:
            self.X.add_element(metrics_dict[constants.DATA_POINTS][0][0])

            self.targets = metrics_dict[constants.DATA_POINTS][0][1]
            if self.n_learners > 1:
                raise ValueError(
                    "you can not compare classifiers in this type of plot.")
            else:

                self.prediction.append(
                    metrics_dict[constants.DATA_POINTS][0][2])
                if self.Flag is True:
                    for j in range(len(self.targets)):
                        self.clusters.append(FastBuffer(100))
                self.Flag = False

                self.subplot_scatter_points.clear()

                self.subplot_scatter_points.set_ylabel('X2')
                self.subplot_scatter_points.set_xlabel('X1')
                X1 = self.X.get_queue()[-1][0]
                X2 = self.X.get_queue()[-1][1]

                for k, cluster in enumerate(self.clusters):
                    if self.prediction[-1] == k:
                        self.clusters[k].add_element([(X1, X2)])
                    if cluster.get_queue():
                        temp = cluster.get_queue()
                        self.subplot_scatter_points.scatter(
                            *zip(*temp), label="class {k}".format(k=k))
                        self.subplot_scatter_points.legend(loc="best")

        if self._draw_cnt == 4:  # Refresh rate to mitigate re-drawing overhead for small changes
            plt.subplots_adjust(
                right=0.72)  # Adjust subplots to include metrics
            self.fig.canvas.draw()
            plt.pause(1e-9)
            self._draw_cnt = 0
        else:
            self._draw_cnt += 1
예제 #7
0
    def __configure(self, n_sliding, dataset_name, plots, n_learners):
        """ __configure
        
        This function will verify which subplots it should create. For each one 
        of those, it will initialize all relevant objects to keep track of the 
        plotting points.
        
        Basic structures needed to keep track of plot values (for each subplot) 
        are: lists of values and matplot line objects.
        
        The __configure function will also initialize each subplot with the 
        correct name and setup the axis.
        
        The subplot size will self adjust to each screen size, so that data can 
        be better viewed in different contexts.
        
        Parameters
        ----------
        n_sliding: int
            The number of samples in the sliding window to track recent performance.
    
        dataset_name: string (Default: 'Unnamed graph')
            The title of the plot. Algorithmically it's not important.
    
        plots: list
            A list containing all the subplots to plot. Can be any of: 
            'accuracy', 'kappa', 'scatter', 'hamming_score', 'hamming_loss',
            'exact_match', 'j_index', 'mean_square_error', 'mean_absolute_error', 
            'true_vs_predicted', 'kappa_t', 'kappa_m'
        
        n_learners: int
            The number of learners to compare.
         
        """
        data_points = False
        font_size_small = 8
        font_size_medium = 10
        font_size_large = 12

        plt.rc('font', size=font_size_small)  # controls default text sizes
        plt.rc('axes',
               titlesize=font_size_medium)  # font size of the axes title
        plt.rc('axes',
               labelsize=font_size_small)  # font size of the x and y labels
        plt.rc('xtick',
               labelsize=font_size_small)  # font size of the tick labels
        plt.rc('ytick',
               labelsize=font_size_small)  # font size of the tick labels
        plt.rc('legend', fontsize=font_size_small)  # legend font size
        plt.rc('figure',
               titlesize=font_size_large)  # font size of the figure title

        warnings.filterwarnings("ignore", ".*GUI is implemented.*")
        warnings.filterwarnings("ignore", ".*left==right.*")
        warnings.filterwarnings("ignore", ".*Passing 1d.*")

        self.n_sliding = n_sliding
        self.dataset_name = dataset_name
        self.plots = plots
        self.n_learners = n_learners
        self.sample_id = []

        plt.ion()
        self.fig = plt.figure(figsize=(9, 5))
        self.fig.suptitle(dataset_name)
        self.num_plots = len(self.plots)
        base = 11 + self.num_plots * 100  # 3-digit integer describing the position of the subplot.
        self.fig.canvas.set_window_title('scikit-multiflow')

        if constants.ACCURACY in self.plots:
            self.current_accuracy = [[] for _ in range(self.n_learners)]
            self.mean_accuracy = [[] for _ in range(self.n_learners)]

            self.subplot_accuracy = self.fig.add_subplot(base)
            self.subplot_accuracy.set_title('Accuracy')
            self.subplot_accuracy.set_ylabel('Accuracy')
            base += 1

            self.line_current_accuracy = [None for _ in range(self.n_learners)]
            self.line_mean_accuracy = [None for _ in range(self.n_learners)]
            handle = []

            for i in range(self.n_learners):
                self.line_current_accuracy[i], = self.subplot_accuracy.plot(
                    self.sample_id,
                    self.current_accuracy[i],
                    label='{}  (sliding {} samples)'.format(
                        self.model_names[i], self.n_sliding))
                self.line_mean_accuracy[i], = self.subplot_accuracy.plot(
                    self.sample_id,
                    self.mean_accuracy[i],
                    label='{} (global)'.format(self.model_names[i]),
                    linestyle='dotted')
                handle.append(self.line_current_accuracy[i])
                handle.append(self.line_mean_accuracy[i])

            self._set_fig_legend(handle)
            self.subplot_accuracy.set_ylim(0, 1)

        if constants.KAPPA in self.plots:
            self.current_kappa = [[] for _ in range(self.n_learners)]
            self.mean_kappa = [[] for _ in range(self.n_learners)]

            self.subplot_kappa = self.fig.add_subplot(base)
            self.subplot_kappa.set_title('Kappa')
            self.subplot_kappa.set_ylabel('Kappa')
            base += 1

            self.line_current_kappa = [None for _ in range(self.n_learners)]
            self.line_mean_kappa = [None for _ in range(self.n_learners)]
            handle = []

            for i in range(self.n_learners):
                self.line_current_kappa[i], = self.subplot_kappa.plot(
                    self.sample_id,
                    self.current_kappa[i],
                    label='Model {}  (sliding {} samples)'.format(
                        self.model_names[i], self.n_sliding))
                self.line_mean_kappa[i], = self.subplot_kappa.plot(
                    self.sample_id,
                    self.mean_kappa[i],
                    label='Model {} (global)'.format(self.model_names[i]),
                    linestyle='dotted')
                handle.append(self.line_current_kappa[i])
                handle.append(self.line_mean_kappa[i])

            self._set_fig_legend(handle)
            self.subplot_kappa.set_ylim(-1, 1)

        if constants.KAPPA_T in self.plots:
            self.current_kappa_t = [[] for _ in range(self.n_learners)]
            self.mean_kappa_t = [[] for _ in range(self.n_learners)]

            self.subplot_kappa_t = self.fig.add_subplot(base)
            self.subplot_kappa_t.set_title('Kappa T')
            self.subplot_kappa_t.set_ylabel('Kappa T')
            base += 1

            self.line_current_kappa_t = [None for _ in range(self.n_learners)]
            self.line_mean_kappa_t = [None for _ in range(self.n_learners)]
            handle = []

            for i in range(self.n_learners):
                self.line_current_kappa_t[i], = self.subplot_kappa_t.plot(
                    self.sample_id,
                    self.current_kappa_t[i],
                    label='Model {}  (sliding {} samples)'.format(
                        self.model_names[i], self.n_sliding))
                self.line_mean_kappa_t[i], = self.subplot_kappa_t.plot(
                    self.sample_id,
                    self.mean_kappa_t[i],
                    label='Model {} (global)'.format(self.model_names[i]),
                    linestyle='dotted')
                handle.append(self.line_current_kappa_t[i])
                handle.append(self.line_mean_kappa_t[i])

            self._set_fig_legend(handle)
            self.subplot_kappa_t.set_ylim(-1, 1)

        if constants.KAPPA_M in self.plots:
            self.current_kappa_m = [[] for _ in range(self.n_learners)]
            self.mean_kappa_m = [[] for _ in range(self.n_learners)]

            self.subplot_kappa_m = self.fig.add_subplot(base)
            self.subplot_kappa_m.set_title('Kappa M')
            self.subplot_kappa_m.set_ylabel('Kappa M')
            base += 1

            self.line_current_kappa_m = [None for _ in range(self.n_learners)]
            self.line_mean_kappa_m = [None for _ in range(self.n_learners)]
            handle = []

            for i in range(self.n_learners):
                self.line_current_kappa_m[i], = self.subplot_kappa_m.plot(
                    self.sample_id,
                    self.current_kappa_m[i],
                    label='Model {}  (sliding {} samples)'.format(
                        self.model_names[i], self.n_sliding))
                self.line_mean_kappa_m[i], = self.subplot_kappa_m.plot(
                    self.sample_id,
                    self.mean_kappa_m[i],
                    label='Model {} (global)'.format(self.model_names[i]),
                    linestyle='dotted')
                handle.append(self.line_current_kappa_m[i])
                handle.append(self.line_mean_kappa_m[i])

            self._set_fig_legend(handle)
            self.subplot_kappa_m.set_ylim(-1, 1)

        if constants.HAMMING_SCORE in self.plots:
            self.mean_hamming_score = [[] for _ in range(self.n_learners)]
            self.current_hamming_score = [[] for _ in range(self.n_learners)]

            self.subplot_hamming_score = self.fig.add_subplot(base)
            self.subplot_hamming_score.set_title('Hamming score')
            self.subplot_hamming_score.set_ylabel('Hamming score')
            base += 1

            self.line_current_hamming_score = [
                None for _ in range(self.n_learners)
            ]
            self.line_mean_hamming_score = [
                None for _ in range(self.n_learners)
            ]
            handle = []

            for i in range(self.n_learners):
                self.line_current_hamming_score[
                    i], = self.subplot_hamming_score.plot(
                        self.sample_id,
                        self.current_hamming_score[i],
                        label='Model {}  (sliding {} samples)'.format(
                            self.model_names[i], self.n_sliding))
                self.line_mean_hamming_score[
                    i], = self.subplot_hamming_score.plot(
                        self.sample_id,
                        self.mean_hamming_score[i],
                        label='Model {} (global)'.format(self.model_names[i]),
                        linestyle='dotted')
                handle.append(self.line_current_hamming_score[i])
                handle.append(self.line_mean_hamming_score[i])

            self._set_fig_legend(handle)
            self.subplot_hamming_score.set_ylim(0, 1)

        if constants.HAMMING_LOSS in self.plots:
            self.mean_hamming_loss = [[] for _ in range(self.n_learners)]
            self.current_hamming_loss = [[] for _ in range(self.n_learners)]

            self.subplot_hamming_loss = self.fig.add_subplot(base)
            self.subplot_hamming_loss.set_title('Hamming loss')
            self.subplot_hamming_loss.set_ylabel('Hamming loss')
            base += 1

            self.line_current_hamming_loss = [
                None for _ in range(self.n_learners)
            ]
            self.line_mean_hamming_loss = [
                None for _ in range(self.n_learners)
            ]
            handle = []

            for i in range(self.n_learners):
                self.line_current_hamming_loss[
                    i], = self.subplot_hamming_loss.plot(
                        self.sample_id,
                        self.current_hamming_loss[i],
                        label='Model {}  (sliding {} samples)'.format(
                            self.model_names[i], self.n_sliding))
                self.line_mean_hamming_loss[
                    i], = self.subplot_hamming_loss.plot(
                        self.sample_id,
                        self.mean_hamming_loss[i],
                        label='Model {} (global)'.format(self.model_names[i]),
                        linestyle='dotted')
                handle.append(self.line_current_hamming_loss[i])
                handle.append(self.line_mean_hamming_loss[i])

            self._set_fig_legend(handle)
            self.subplot_hamming_loss.set_ylim(0, 1)

        if constants.EXACT_MATCH in self.plots:
            self.mean_exact_match = [[] for _ in range(self.n_learners)]
            self.current_exact_match = [[] for _ in range(self.n_learners)]

            self.subplot_exact_match = self.fig.add_subplot(base)
            self.subplot_exact_match.set_title('Exact matches')
            self.subplot_exact_match.set_ylabel('Exact matches')
            base += 1

            self.line_current_exact_match = [
                None for _ in range(self.n_learners)
            ]
            self.line_mean_exact_match = [None for _ in range(self.n_learners)]
            handle = []

            for i in range(self.n_learners):
                self.line_current_exact_match[
                    i], = self.subplot_exact_match.plot(
                        self.sample_id,
                        self.current_exact_match[i],
                        label='Model {}  (sliding {} samples)'.format(
                            self.model_names[i], self.n_sliding))
                self.line_mean_exact_match[i], = self.subplot_exact_match.plot(
                    self.sample_id,
                    self.mean_exact_match[i],
                    label='Model {} (global)'.format(self.model_names[i]),
                    linestyle='dotted')
                handle.append(self.line_current_exact_match[i])
                handle.append(self.line_mean_exact_match[i])

            self._set_fig_legend(handle)
            self.subplot_exact_match.set_ylim(0, 1)

        if constants.J_INDEX in self.plots:
            self.mean_j_index = [[] for _ in range(self.n_learners)]
            self.current_j_index = [[] for _ in range(self.n_learners)]

            self.subplot_j_index = self.fig.add_subplot(base)
            self.subplot_j_index.set_title('Jaccard index')
            self.subplot_j_index.set_ylabel('Jaccard index')
            base += 1

            self.line_current_j_index = [None for _ in range(self.n_learners)]
            self.line_mean_j_index = [None for _ in range(self.n_learners)]
            handle = []

            for i in range(self.n_learners):
                self.line_current_j_index[i], = self.subplot_j_index.plot(
                    self.sample_id,
                    self.current_j_index[i],
                    label='Model {}  (sliding {} samples)'.format(
                        self.model_names[i], self.n_sliding))
                self.line_mean_j_index[i], = self.subplot_j_index.plot(
                    self.sample_id,
                    self.mean_j_index[i],
                    label='Model {} (global)'.format(self.model_names[i]),
                    linestyle='dotted')
                handle.append(self.line_current_j_index[i])
                handle.append(self.line_mean_j_index[i])

            self._set_fig_legend(handle)
            self.subplot_j_index.set_ylim(0, 1)

        if constants.MSE in self.plots:
            self.mean_mse = [[] for _ in range(self.n_learners)]
            self.current_mse = [[] for _ in range(self.n_learners)]

            self.subplot_mse = self.fig.add_subplot(base)
            self.subplot_mse.set_title('Mean Squared Error')
            self.subplot_mse.set_ylabel('MSE')
            base += 1

            self.line_current_mse = [None for _ in range(self.n_learners)]
            self.line_mean_mse = [None for _ in range(self.n_learners)]
            handle = []

            for i in range(self.n_learners):
                self.line_current_mse[i], = self.subplot_mse.plot(
                    self.sample_id,
                    self.current_mse[i],
                    label='Model {}  (sliding {} samples)'.format(
                        self.model_names[i], self.n_sliding))
                self.line_mean_mse[i], = self.subplot_mse.plot(
                    self.sample_id,
                    self.mean_mse[i],
                    label='Model {} (global)'.format(self.model_names[i]),
                    linestyle='dotted')
                handle.append(self.line_current_mse[i])
                handle.append(self.line_mean_mse[i])

            self._set_fig_legend(handle)
            self.subplot_mse.set_ylim(0, 1)

        if constants.MAE in self.plots:
            self.mean_mae = [[] for _ in range(self.n_learners)]
            self.current_mae = [[] for _ in range(self.n_learners)]

            self.subplot_mae = self.fig.add_subplot(base)
            self.subplot_mae.set_title('Mean Absolute Error')
            self.subplot_mae.set_ylabel('MAE')
            base += 1

            self.line_current_mae = [None for _ in range(self.n_learners)]
            self.line_mean_mae = [None for _ in range(self.n_learners)]
            handle = []

            for i in range(self.n_learners):
                self.line_current_mae[i], = self.subplot_mae.plot(
                    self.sample_id,
                    self.current_mae[i],
                    label='Model {}  (sliding {} samples)'.format(
                        self.model_names[i], self.n_sliding))
                self.line_mean_mae[i], = self.subplot_mae.plot(
                    self.sample_id,
                    self.mean_mae[i],
                    label='Model {} (global)'.format(self.model_names[i]),
                    linestyle='dotted')
                handle.append(self.line_current_mae[i])
                handle.append(self.line_mean_mae[i])

            self._set_fig_legend(handle)
            self.subplot_mae.set_ylim(0, 1)

        if constants.TRUE_VS_PREDICTED in self.plots:
            self.true_values = []
            self.pred_values = [[] for _ in range(self.n_learners)]

            self.subplot_true_vs_predicted = self.fig.add_subplot(base)
            self.subplot_true_vs_predicted.set_title('True vs Predicted')
            self.subplot_true_vs_predicted.set_ylabel('y')
            self.subplot_true_vs_predicted.set_prop_cycle(
                cycler('color', ['c', 'm', 'y', 'k']))
            base += 1

            if self.task_type == constants.CLASSIFICATION:
                self.line_true, = self.subplot_true_vs_predicted.step(
                    self.sample_id, self.true_values, label='True value')
            else:
                self.line_true, = self.subplot_true_vs_predicted.plot(
                    self.sample_id, self.true_values, label='True value')
            handle = [self.line_true]

            self.line_pred = [None for _ in range(self.n_learners)]

            for i in range(self.n_learners):
                if self.task_type == constants.CLASSIFICATION:
                    self.line_pred[i], = self.subplot_true_vs_predicted.step(
                        self.sample_id,
                        self.pred_values[i],
                        label='Model {} (global)'.format(self.model_names[i]),
                        linestyle='dotted')
                else:
                    self.line_pred[i], = self.subplot_true_vs_predicted.plot(
                        self.sample_id,
                        self.pred_values[i],
                        label='Model {} (global)'.format(self.model_names[i]),
                        linestyle='dotted')
                handle.append(self.line_pred[i])

            self.subplot_true_vs_predicted.legend(handles=handle)
            self.subplot_true_vs_predicted.set_ylim(0, 1)

        if constants.DATA_POINTS in self.plots:

            data_points = True
            self.Flag = True
            self.X = FastBuffer(5000)
            self.targets = []
            self.prediction = []
            self.clusters = []
            self.subplot_scatter_points = self.fig.add_subplot(base)
            base += 1

        if data_points:
            plt.xlabel('X1')
        else:
            plt.xlabel('Samples')

        self.fig.subplots_adjust(hspace=.5)
        self.fig.tight_layout(rect=[0, .04, 1, 0.98],
                              pad=2.6,
                              w_pad=0.5,
                              h_pad=1.0)
    def draw(self, train_step, metrics_dict):
        """ draw
        
        Updates and redraws the plot.
        
        Parameters
        ----------
        train_step: int
            The number of samples processed to this moment.
        
        metrics_dict: dictionary
            A dictionary containing tuples, where the first element is the 
            string that identifies one of the plot's subplot names, and the 
            second element is its numerical value.
             
        """

        self.sample_id.append(train_step)

        self._clear_annotations()

        if 'performance' in self.plots:
            for i in range(self.n_learners):
                self.global_performance[i].append(
                    metrics_dict['performance'][i][0])
                self.partial_performance[i].append(
                    metrics_dict['performance'][i][1])
                self.line_global_performance[i].set_data(
                    self.sample_id, self.global_performance[i])
                self.line_partial_performance[i].set_data(
                    self.sample_id, self.partial_performance[i])

                self._update_annotations(i, self.subplot_performance,
                                         self.model_names[i],
                                         self.global_performance[i][-1],
                                         self.partial_performance[i][-1])

            self.subplot_performance.set_xlim(0, self.sample_id[-1])
            self.subplot_performance.set_ylim(0, 1)

        if 'kappa' in self.plots:
            for i in range(self.n_learners):
                self.global_kappa[i].append(metrics_dict['kappa'][i][0])
                self.partial_kappa[i].append(metrics_dict['kappa'][i][1])
                self.line_global_kappa[i].set_data(self.sample_id,
                                                   self.global_kappa[i])
                self.line_partial_kappa[i].set_data(self.sample_id,
                                                    self.partial_kappa[i])

                self._update_annotations(i, self.subplot_kappa,
                                         self.model_names[i],
                                         self.global_kappa[i][-1],
                                         self.partial_kappa[i][-1])

            self.subplot_kappa.set_xlim(0, self.sample_id[-1])
            self.subplot_kappa.set_ylim(0, 1)

        if 'kappa_t' in self.plots:
            minimum = -1.
            for i in range(self.n_learners):
                self.global_kappa_t[i].append(metrics_dict['kappa_t'][i][0])
                self.partial_kappa_t[i].append(metrics_dict['kappa_t'][i][1])
                self.line_global_kappa_t[i].set_data(self.sample_id,
                                                     self.global_kappa_t[i])
                self.line_partial_kappa_t[i].set_data(self.sample_id,
                                                      self.partial_kappa_t[i])

                self._update_annotations(i, self.subplot_kappa_t,
                                         self.model_names[i],
                                         self.global_kappa_t[i][-1],
                                         self.partial_kappa_t[i][-1])

                minimum = min(min(minimum, min(self.global_kappa_t[i])),
                              min(minimum, min(self.partial_kappa_t[i])))

            self.subplot_kappa_t.set_xlim(0, self.sample_id[-1])
            self.subplot_kappa_t.set_ylim([minimum, 1.])

        if 'kappa_m' in self.plots:
            minimum = -1.
            for i in range(self.n_learners):
                self.global_kappa_m[i].append(metrics_dict['kappa_m'][i][0])
                self.partial_kappa_m[i].append(metrics_dict['kappa_m'][i][1])
                self.line_global_kappa_m[i].set_data(self.sample_id,
                                                     self.global_kappa_m[i])
                self.line_partial_kappa_m[i].set_data(self.sample_id,
                                                      self.partial_kappa_m[i])

                self._update_annotations(i, self.subplot_kappa_m,
                                         self.model_names[i],
                                         self.global_kappa_m[i][-1],
                                         self.partial_kappa_m[i][-1])

                minimum = min(min(minimum, min(self.global_kappa_m[i])),
                              min(minimum, min(self.partial_kappa_m[i])))

            self.subplot_kappa_m.set_xlim(0, self.sample_id[-1])
            self.subplot_kappa_m.set_ylim(minimum, 1.)

        if 'hamming_score' in self.plots:
            for i in range(self.n_learners):
                self.global_hamming_score[i].append(
                    metrics_dict['hamming_score'][i][0])
                self.partial_hamming_score[i].append(
                    metrics_dict['hamming_score'][i][1])
                self.line_global_hamming_score[i].set_data(
                    self.sample_id, self.global_hamming_score[i])
                self.line_partial_hamming_score[i].set_data(
                    self.sample_id, self.partial_hamming_score[i])

                self._update_annotations(i, self.subplot_hamming_score,
                                         self.model_names[i],
                                         self.global_hamming_score[i][-1],
                                         self.partial_hamming_score[i][-1])

            self.subplot_hamming_score.set_xlim(0, self.sample_id[-1])
            self.subplot_hamming_score.set_ylim(0, 1)

        if 'hamming_loss' in self.plots:
            for i in range(self.n_learners):
                self.global_hamming_loss[i].append(
                    metrics_dict['hamming_loss'][i][0])
                self.partial_hamming_loss[i].append(
                    metrics_dict['hamming_loss'][i][1])
                self.line_global_hamming_loss[i].set_data(
                    self.sample_id, self.global_hamming_loss[i])
                self.line_partial_hamming_loss[i].set_data(
                    self.sample_id, self.partial_hamming_loss[i])

                self._update_annotations(i, self.subplot_hamming_loss,
                                         self.model_names[i],
                                         self.global_hamming_loss[i][-1],
                                         self.partial_hamming_loss[i][-1])

            self.subplot_hamming_loss.set_xlim(0, self.sample_id[-1])
            self.subplot_hamming_loss.set_ylim(0, 1)

        if 'exact_match' in self.plots:
            for i in range(self.n_learners):
                self.global_exact_match[i].append(
                    metrics_dict['exact_match'][i][0])
                self.partial_exact_match[i].append(
                    metrics_dict['exact_match'][i][1])
                self.line_global_exact_match[i].set_data(
                    self.sample_id, self.global_exact_match[i])
                self.line_partial_exact_match[i].set_data(
                    self.sample_id, self.partial_exact_match[i])

                self._update_annotations(i, self.subplot_exact_match,
                                         self.model_names[i],
                                         self.global_exact_match[i][-1],
                                         self.partial_exact_match[i][-1])

            self.subplot_exact_match.set_xlim(0, self.sample_id[-1])
            self.subplot_exact_match.set_ylim(0, 1)

        if 'j_index' in self.plots:
            for i in range(self.n_learners):
                self.global_j_index[i].append(metrics_dict['j_index'][i][0])
                self.partial_j_index[i].append(metrics_dict['j_index'][i][1])
                self.line_global_j_index[i].set_data(self.sample_id,
                                                     self.global_j_index[i])
                self.line_partial_j_index[i].set_data(self.sample_id,
                                                      self.partial_j_index[i])

                self._update_annotations(i, self.subplot_j_index,
                                         self.model_names[i],
                                         self.global_j_index[i][-1],
                                         self.partial_j_index[i][-1])

            self.subplot_j_index.set_xlim(0, self.sample_id[-1])
            self.subplot_j_index.set_ylim(0, 1)

        if 'mean_square_error' in self.plots:
            minimum = -1
            maximum = 0
            for i in range(self.n_learners):
                self.global_mse[i].append(
                    metrics_dict['mean_square_error'][i][0])
                self.partial_mse[i].append(
                    metrics_dict['mean_square_error'][i][1])
                self.line_global_mse[i].set_data(self.sample_id,
                                                 self.global_mse[i])
                self.line_partial_mse[i].set_data(self.sample_id,
                                                  self.partial_mse[i])

                self._update_annotations(i, self.subplot_mse,
                                         self.model_names[i],
                                         self.global_mse[i][-1],
                                         self.partial_mse[i][-1])

                # minimum = min([min(self.global_mse[i]), min(self.partial_mse[i]), minimum])
                maximum = max([
                    max(self.global_mse[i]),
                    max(self.partial_mse[i]), maximum
                ])

            self.subplot_mse.set_xlim(0, self.sample_id[-1])
            self.subplot_mse.set_ylim(minimum, 1.2 * maximum)

        if 'mean_absolute_error' in self.plots:
            minimum = -1
            maximum = 0
            for i in range(self.n_learners):
                self.global_mae[i].append(
                    metrics_dict['mean_absolute_error'][i][0])
                self.partial_mae[i].append(
                    metrics_dict['mean_absolute_error'][i][1])
                self.line_global_mae[i].set_data(self.sample_id,
                                                 self.global_mae[i])
                self.line_partial_mae[i].set_data(self.sample_id,
                                                  self.partial_mae[i])

                self._update_annotations(i, self.subplot_mae,
                                         self.model_names[i],
                                         self.global_mae[i][-1],
                                         self.partial_mae[i][-1])

                # minimum = min([min(self.global_mae[i]), min(self.partial_mae[i]), minimum])
                maximum = max([
                    max(self.global_mae[i]),
                    max(self.partial_mae[i]), maximum
                ])

            self.subplot_mae.set_xlim(0, self.sample_id[-1])
            self.subplot_mae.set_ylim(minimum, 1.2 * maximum)

        if 'true_vs_predicted' in self.plots:
            self.true_values.append(metrics_dict['true_vs_predicted'][0][0])
            self.line_true.set_data(self.sample_id, self.true_values)
            minimum = 0
            maximum = 0
            for i in range(self.n_learners):
                self.pred_values[i].append(
                    metrics_dict['true_vs_predicted'][i][1])
                self.line_pred[i].set_data(self.sample_id, self.pred_values[i])
                minimum = min(
                    [min(self.pred_values[i]),
                     min(self.true_values), minimum])
                maximum = max(
                    [max(self.pred_values[i]),
                     max(self.true_values), maximum])

            self.subplot_true_vs_predicted.set_xlim(0, self.sample_id[-1])
            self.subplot_true_vs_predicted.set_ylim(minimum - 1, maximum + 1)

            self.subplot_true_vs_predicted.legend(loc=2,
                                                  bbox_to_anchor=(1.01, 1.))

        if 'data_points' in self.plots:
            self.X.add_element(metrics_dict['data_points'][0][0])

            self.targets = metrics_dict['data_points'][0][1]
            if self.n_learners > 1:
                raise ValueError(
                    "you can not compare classifiers in this type of plot.")
            else:

                self.prediction.append(metrics_dict['data_points'][0][2])
                if self.Flag is True:
                    for j in range(len(self.targets)):
                        self.clusters.append(FastBuffer(100))
                self.Flag = False

                self.subplot_scatter_points.clear()

                self.subplot_scatter_points.set_ylabel('X2')
                self.subplot_scatter_points.set_xlabel('X1')
                X1 = self.X.get_queue()[-1][0]
                X2 = self.X.get_queue()[-1][1]

                for k, cluster in enumerate(self.clusters):
                    if self.prediction[-1] == k:
                        self.clusters[k].add_element([(X1, X2)])
                    if cluster.get_queue():
                        temp = cluster.get_queue()
                        self.subplot_scatter_points.scatter(
                            *zip(*temp), label="class {k}".format(k=k))
                        self.subplot_scatter_points.legend(loc="best")

        if self._draw_cnt == 4:  # Refresh rate to mitigate re-drawing overhead for small changes
            plt.subplots_adjust(
                right=0.72)  # Adjust subplots to include metrics
            self.fig.canvas.draw()
            plt.pause(1e-9)
            self._draw_cnt = 0
        else:
            self._draw_cnt += 1