<commit_before>import math

import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from sklearn.metrics import confusion_matrix


class Displayer(object):
    def __init__(self, **kwargs):
        self.aspect = kwargs.pop('aspect', (20, -40))
        self.parameters = ', '.join(['%s: %s' % (k, str(v)) for k, v in kwargs.items()])
        self.items = []

    def load(self, data, color=None, title=None):
        # Always copy the data, and, of course, only the first three dimensions.
        self.items.append((data[:, :3], color, title))

        return self

    def render(self):
        # Assert that there is at least one graph to show.
        assert self.items, 'nothing graphs to render.'

        fig = plt.figure(figsize=(16, 9))
        plt.suptitle(self.parameters)

        count = len(self.items)
        items_in_row = math.ceil(math.sqrt(count))
        rows_count = math.ceil(count / items_in_row)

        for i, item in enumerate(self.items):
            data, color, title = item
            samples, dimension = data.shape

            # Grab data set components. It necessarily has 3 dimensions, as it was cut during load().
            components = [data[:, i] for i in range(dimension)]

            if dimension == 1:
                components.append(np.zeros((samples, 1)))

            if color is None:
                color = np.zeros(samples)

            kwargs = {'projection': '3d'} if dimension > 2 else {}

            ax = fig.add_subplot(
                rows_count * 100 +
                items_in_row * 10 +
                1 + i, **kwargs)

            ax.scatter(*components, **{
                'c': color,
                's': 50,
                'cmap': plt.cm.rainbow
            })

            if title:
                plt.title(title)

            plt.axis('tight')

            if dimension > 2:
                ax.view_init(*self.aspect)

        plt.show()

        return self

    @classmethod
    def confusion_matrix_for(cls, target_test, target_predicted, title='Confusion matrix'):
        cm = confusion_matrix(target_test, target_predicted)
        np.set_printoptions(precision=2)

        plt.figure()
        plt.imshow(cm, interpolation='nearest', cmap=plt.cm.Blues)
        plt.title(title)
        plt.colorbar()
        plt.tight_layout()
        plt.ylabel('True label')
        plt.xlabel('Predicted label')

        plt.show()
<commit_msg> Update Displayer    Add .save(name=None) method.<commit_after>import math
import datetime

import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from sklearn.metrics import confusion_matrix


class Displayer(object):
    def __init__(self, **kwargs):
        self.aspect = kwargs.pop('aspect', (20, -40))
        self.rows = kwargs.pop('rows', None)
        self.columns = kwargs.pop('columns', None)

        self.parameters = ', '.join(['%s: %s' % (k, str(v)) for k, v in kwargs.items()])
        self.items = []

    def load(self, data, color=None, title=None):
        # Always copy the data, and, of course, only the first three dimensions.
        self.items.append((data[:, :3], color, title))

        return self

    def render(self):
        self._process_figure()
        plt.show()

        return self

    def save(self, name=None):
        figure = self._process_figure()

        name = name or '%s.png' % str(datetime.datetime.now()).replace(':', '.')
        plt.savefig(name, bbox_inches='tight')
        plt.close(figure)

        return self

    def _process_figure(self):
        # Assert that there is at least one graph to show.
        assert self.items, 'nothing graphs to render.'

        figure = plt.figure(figsize=(16, 9))
        plt.suptitle(self.parameters)

        count = len(self.items)
        columns = self.columns or math.ceil(math.sqrt(count))
        rows = self.rows or math.ceil(count / columns)

        for i, item in enumerate(self.items):
            data, color, title = item
            samples, dimension = data.shape

            # Grab data set components. It necessarily has 3 dimensions, as it was cut during load().
            components = [data[:, i] for i in range(dimension)]

            if dimension == 1:
                components.append(np.zeros((samples, 1)))

            if color is None:
                color = np.zeros(samples)

            kwargs = {'projection': '3d'} if dimension > 2 else {}

            ax = figure.add_subplot(
                rows * 100 +
                columns * 10 +
                1 + i, **kwargs)

            ax.scatter(*components, **{
                'c': color,
                's': 50,
                'cmap': plt.cm.rainbow
            })

            if title:
                plt.title(title)

            plt.axis('tight')

            if dimension > 2:
                ax.view_init(*self.aspect)

        return figure

    def dispose(self):
        self.items = []

        return self

    @classmethod
    def confusion_matrix_for(cls, target_test, target_predicted, title='Confusion matrix'):
        cm = confusion_matrix(target_test, target_predicted)
        np.set_printoptions(precision=2)

        plt.figure()
        plt.imshow(cm, interpolation='nearest', cmap=plt.cm.Blues)
        plt.title(title)
        plt.colorbar()
        plt.tight_layout()
        plt.ylabel('True label')
        plt.xlabel('Predicted label')

        plt.show()

{'fraction_non_alphanumeric': 0.11705440556878549, 'fraction_numerical': 0.009159186664224217, 'mean_word_length': 1.930756843800322, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3814433', 'n_tokens_mistral': 1661, 'n_tokens_neox': 1556, 'n_words': 426}