<commit_before>"""
Chart
-----

Tools for making nice and readable plots using matplotlib

"""

# imports
import numpy as np
import matplotlib.pyplot as plt
from functools import wraps

__all__ = ['plotwrapper',  'image', 'hist', 'hist2d', 'errorplot',
           'setfontsize', 'noticks', 'nospines', 'breathe']


def plotwrapper(fun):
    """
    Decorator that adds sane plotting defaults to the kwargs of a function
    """

    @wraps(fun)
    def wrapper(*args, **kwargs):

        if 'ax' not in kwargs:

            if 'fig' not in kwargs:
                kwargs['fig'] = plt.figure()

            kwargs['ax'] = kwargs['fig'].add_subplot(111)

        else:

            if 'fig' not in kwargs:
                kwargs['fig'] = kwargs['ax'].get_figure()

        res = fun(*args, **kwargs)
        plt.show()
        plt.draw()
        return res

    return wrapper


def axwrapper(fun):
    """
    Decorator that adds axis arguments
    """

    @wraps(fun)
    def wrapper(*args, **kwargs):

        if 'ax' not in kwargs:

            if 'fig' not in kwargs:
                kwargs['fig'] = plt.gcf()

            kwargs['ax'] = plt.gca()

        else:

            if 'fig' not in kwargs:
                kwargs['fig'] = kwargs['ax'].get_figure()

        res = fun(*args, **kwargs)
        plt.show()
        plt.draw()
        return res

    return wrapper


@plotwrapper
def image(img, symmetric=True, cmap='seismic', **kwargs):
    """
    Visualize a matrix as an image

    Parameters
    ----------
    img : array_like
        The matrix to visualize

    symmetric : boolean, optional
        Whether or not to scale the colormap range so that it is symmetric
        about the image mean (default: true).

    cmap : string, optional
        A matplotlib colormap to use (default: 'seismic').

    ax : matplotlib axes handle, optional
        A handle to a matplotlib axes to use for plotting

    """

    # image mean
    mu = np.mean(img)

    # image bounds
    img_min = np.min(img - mu)
    img_max = np.max(img - mu)
    abs_max = np.max(np.abs(img - mu))
    vmin, vmax = (-abs_max, abs_max) if symmetric else (img_min, img_max)

    # make the image
    kwargs['ax'].imshow(img, cmap=cmap, interpolation=None,
                        vmin=vmin, vmax=vmax, aspect='equal')

    # clear ticks
    noticks(ax=kwargs['ax'])
    noticks(kwargs['ax'])

    # display
    plt.show()
    plt.draw()


@plotwrapper
def hist(*args, **kwargs):
    """
    Wrapper for matplotlib.hist function

    """

    # remove kwargs that are filled in manually
    kwargs.pop('alpha', None)
    kwargs.pop('histtype', None)
    kwargs.pop('normed', None)

    # get the axis and figure handles
    ax = kwargs.pop('ax')

    return ax.hist(*args, histtype='stepfilled', alpha=0.85,
                   normed=True, **kwargs)


@plotwrapper
def hist2d(x, y, bins=None, range=None, cmap='hot', **kwargs):
    """
    Function for visualizing a 2D histogram by binning given data

    Parameters
    ----------
    x : array_like
        The x-value of the data points to bin

    y : array_like
        The y-value of the data points to bin

    bins : array_like, optional
        Either the number of bins to use in each dimension, or the actual bin
        edges to use

    cmap : string
        A matplotlib colormap to use when generating the plot

    """

    # parse inputs
    if range is None:
        range = np.array([[np.min(x), np.max(x)], [np.min(y), np.max(y)]])

    if bins is None:
        bins = 25

    # compute the histogram
    cnt, xe, ye = np.histogram2d(x, y, bins=bins, normed=True, range=range)

    # generate the plot
    ax = kwargs['ax']
    ax.pcolor(xe, ye, cnt.T, cmap=cmap)
    ax.set_xlim(xe[0], xe[-1])
    ax.set_ylim(ye[0], ye[-1])
    ax.set_aspect('equal')
    setfontsize()


@plotwrapper
def errorplot(x, y, ye, color='k', xscale='linear', fmt='-', **kwargs):
    """
    Plot a line with error bars

    """

    ax = kwargs['ax']
    ax.plot(x, y, fmt, color=color)
    ax.plot(x, y+ye, '+')
    ax.plot(x, y-ye, '+')
    for i, xi in enumerate(x):
        ax.plot(np.array([xi, xi]), np.array([y[i]-ye[i], y[i]+ye[i]]), '-',
                color=color, linewidth=4)

    ax.set_xscale(xscale)

    return ax


@plotwrapper
def setfontsize(size=18, **kwargs):
    """
    Sets the font size of the x- and y- tick labels of the current axes

    Parameters
    ----------
    size : int
        The font size to use

    """

    ax = kwargs['ax']
    ax.set_xticklabels(ax.get_xticks(), fontsize=size)
    ax.set_yticklabels(ax.get_yticks(), fontsize=size)


@axwrapper
def noticks(**kwargs):
    """
    Clears tick marks (useful for images)
    """

    ax = kwargs['ax']
    ax.set_xticks([])
    ax.set_yticks([])
    return ax


@axwrapper
def nospines(**kwargs):
    """
    Hides the top and rightmost axis spines
    """

    ax = kwargs['ax']

    # disable spines
    ax.spines['right'].set_color('none')
    ax.spines['top'].set_color('none')

    # disable ticks
    ax.yaxis.set_ticks_position('left')
    ax.xaxis.set_ticks_position('bottom')

    return ax


@axwrapper
def breathe(factor=0.05, **kwargs):
    ax = kwargs['ax']

    if ax.spines['bottom'].get_bounds():
        xa, xb = ax.spines['bottom'].get_bounds()
    else:
        xa, xb = ax.get_xlim()

    xrng = xb - xa
    ax.set_xlim(xa - factor * xrng, xb + factor * xrng)
    ax.spines['bottom'].set_bounds(xa, xb)

    if ax.spines['left'].get_bounds():
        ya, yb = ax.spines['left'].get_bounds()
    else:
        ya, yb = ax.get_ylim()

    yrng = yb - ya
    ax.set_ylim(ya - factor * yrng, yb + factor * yrng)
    ax.spines['left'].set_bounds(ya, yb)

    nospines(**kwargs)
    return ax
<commit_msg>bugfix<commit_after>"""
Chart
-----

Tools for making nice and readable plots using matplotlib

"""

# imports
import numpy as np
import matplotlib.pyplot as plt
from functools import wraps

__all__ = ['plotwrapper',  'image', 'hist', 'hist2d', 'errorplot',
           'setfontsize', 'noticks', 'nospines', 'breathe']


def plotwrapper(fun):
    """
    Decorator that adds sane plotting defaults to the kwargs of a function
    """

    @wraps(fun)
    def wrapper(*args, **kwargs):

        if 'ax' not in kwargs:

            if 'fig' not in kwargs:
                kwargs['fig'] = plt.figure()

            kwargs['ax'] = kwargs['fig'].add_subplot(111)

        else:

            if 'fig' not in kwargs:
                kwargs['fig'] = kwargs['ax'].get_figure()

        res = fun(*args, **kwargs)
        plt.show()
        plt.draw()
        return res

    return wrapper


def axwrapper(fun):
    """
    Decorator that adds axis arguments
    """

    @wraps(fun)
    def wrapper(*args, **kwargs):

        if 'ax' not in kwargs:

            if 'fig' not in kwargs:
                kwargs['fig'] = plt.gcf()

            kwargs['ax'] = plt.gca()

        else:

            if 'fig' not in kwargs:
                kwargs['fig'] = kwargs['ax'].get_figure()

        res = fun(*args, **kwargs)
        plt.show()
        plt.draw()
        return res

    return wrapper


@plotwrapper
def image(img, symmetric=True, cmap='seismic', **kwargs):
    """
    Visualize a matrix as an image

    Parameters
    ----------
    img : array_like
        The matrix to visualize

    symmetric : boolean, optional
        Whether or not to scale the colormap range so that it is symmetric
        about the image mean (default: true).

    cmap : string, optional
        A matplotlib colormap to use (default: 'seismic').

    ax : matplotlib axes handle, optional
        A handle to a matplotlib axes to use for plotting

    """

    # image mean
    mu = np.mean(img)

    # image bounds
    img_min = np.min(img - mu)
    img_max = np.max(img - mu)
    abs_max = np.max(np.abs(img - mu))
    vmin, vmax = (-abs_max, abs_max) if symmetric else (img_min, img_max)

    # make the image
    kwargs['ax'].imshow(img, cmap=cmap, interpolation=None,
                        vmin=vmin, vmax=vmax, aspect='equal')

    # clear ticks
    noticks(ax=kwargs['ax'])

    # display
    plt.show()
    plt.draw()


@plotwrapper
def hist(*args, **kwargs):
    """
    Wrapper for matplotlib.hist function

    """

    # remove kwargs that are filled in manually
    kwargs.pop('alpha', None)
    kwargs.pop('histtype', None)
    kwargs.pop('normed', None)

    # get the axis and figure handles
    ax = kwargs.pop('ax')

    return ax.hist(*args, histtype='stepfilled', alpha=0.85,
                   normed=True, **kwargs)


@plotwrapper
def hist2d(x, y, bins=None, range=None, cmap='hot', **kwargs):
    """
    Function for visualizing a 2D histogram by binning given data

    Parameters
    ----------
    x : array_like
        The x-value of the data points to bin

    y : array_like
        The y-value of the data points to bin

    bins : array_like, optional
        Either the number of bins to use in each dimension, or the actual bin
        edges to use

    cmap : string
        A matplotlib colormap to use when generating the plot

    """

    # parse inputs
    if range is None:
        range = np.array([[np.min(x), np.max(x)], [np.min(y), np.max(y)]])

    if bins is None:
        bins = 25

    # compute the histogram
    cnt, xe, ye = np.histogram2d(x, y, bins=bins, normed=True, range=range)

    # generate the plot
    ax = kwargs['ax']
    ax.pcolor(xe, ye, cnt.T, cmap=cmap)
    ax.set_xlim(xe[0], xe[-1])
    ax.set_ylim(ye[0], ye[-1])
    ax.set_aspect('equal')
    setfontsize()


@plotwrapper
def errorplot(x, y, ye, color='k', xscale='linear', fmt='-', **kwargs):
    """
    Plot a line with error bars

    """

    ax = kwargs['ax']
    ax.plot(x, y, fmt, color=color)
    ax.plot(x, y+ye, '+')
    ax.plot(x, y-ye, '+')
    for i, xi in enumerate(x):
        ax.plot(np.array([xi, xi]), np.array([y[i]-ye[i], y[i]+ye[i]]), '-',
                color=color, linewidth=4)

    ax.set_xscale(xscale)

    return ax


@plotwrapper
def setfontsize(size=18, **kwargs):
    """
    Sets the font size of the x- and y- tick labels of the current axes

    Parameters
    ----------
    size : int
        The font size to use

    """

    ax = kwargs['ax']
    ax.set_xticklabels(ax.get_xticks(), fontsize=size)
    ax.set_yticklabels(ax.get_yticks(), fontsize=size)


@axwrapper
def noticks(**kwargs):
    """
    Clears tick marks (useful for images)
    """

    ax = kwargs['ax']
    ax.set_xticks([])
    ax.set_yticks([])
    return ax


@axwrapper
def nospines(**kwargs):
    """
    Hides the top and rightmost axis spines
    """

    ax = kwargs['ax']

    # disable spines
    ax.spines['right'].set_color('none')
    ax.spines['top'].set_color('none')

    # disable ticks
    ax.yaxis.set_ticks_position('left')
    ax.xaxis.set_ticks_position('bottom')

    return ax


@axwrapper
def breathe(factor=0.05, **kwargs):
    ax = kwargs['ax']

    if ax.spines['bottom'].get_bounds():
        xa, xb = ax.spines['bottom'].get_bounds()
    else:
        xa, xb = ax.get_xlim()

    xrng = xb - xa
    ax.set_xlim(xa - factor * xrng, xb + factor * xrng)
    ax.spines['bottom'].set_bounds(xa, xb)

    if ax.spines['left'].get_bounds():
        ya, yb = ax.spines['left'].get_bounds()
    else:
        ya, yb = ax.get_ylim()

    yrng = yb - ya
    ax.set_ylim(ya - factor * yrng, yb + factor * yrng)
    ax.spines['left'].set_bounds(ya, yb)

    nospines(**kwargs)
    return ax

{'fraction_non_alphanumeric': 0.14262052131461947, 'fraction_numerical': 0.003835759741957981, 'mean_word_length': 2.2758423757852655, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, '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': '7082423', 'n_tokens_mistral': 4021, 'n_tokens_neox': 3824, 'n_words': 1073}