<commit_before>from numbers import Number
import numpy as np

import param

from .dimension import Dimension, ViewableElement
from .layout import Composable, Layout, AdjointLayout, NdLayout
from .ndmapping import OrderedDict, UniformNdMapping
from .overlay import Overlayable, NdOverlay, Overlay, CompositeOverlay
from .util import find_minmax


class Element(ViewableElement, Composable, Overlayable):
    """
    Element is the baseclass for all ViewableElement types, with an x- and
    y-dimension. Subclasses should define the data storage in the
    constructor, as well as methods and properties, which define how
    the data maps onto the x- and y- and value dimensions.
    """

    value = param.String(default='Element')

    def hist(self, dimension=None, num_bins=20, bin_range=None,
             adjoin=True, individually=True, **kwargs):
        """
        The hist method generates a histogram to be adjoined to the
        Element in an AdjointLayout. By default the histogram is
        computed along the first value dimension of the Element,
        however any dimension may be selected. The number of bins and
        the bin_ranges and any kwargs to be passed to the histogram
        operation may also be supplied.
        """
        from ..operation import histogram
        return histogram(self, num_bins=num_bins, bin_range=bin_range, adjoin=adjoin,
                         individually=individually, **kwargs)


    ########################
    # Subclassable methods #
    ########################

    def __init__(self, data, **params):
        super(Element, self).__init__(data, **params)


    def __getitem__(self, key):
        if key is ():
            return self
        else:
            raise NotImplementedError("%s currently does not support getitem" %
                                      type(self).__name__)


    @classmethod
    def collapse_data(cls, data, function=None, **kwargs):
        """
        Class method to collapse a list of data matching the
        data format of the Element type. By implementing this
        method HoloMap can collapse multiple Elements of the
        same type. The kwargs are passed to the collapse
        function. The collapse function must support the numpy
        style axis selection. Valid function include:
        np.mean, np.sum, np.product, np.std,
        scipy.stats.kurtosis etc.
        """
        raise NotImplementedError("Collapsing not implemented for %s." % cls.__name__)


    def closest(self, coords):
        """
        Class method that returns the exact keys for a given list of
        coordinates. The supplied bounds defines the extent within
        which the samples are drawn and the optional shape argument is
        the shape of the numpy array (typically the shape of the .data
        attribute) when applicable.
        """
        return coords


    def sample(self, **samples):
        """
        Base class signature to demonstrate API for sampling Views.
        To sample a ViewableElement kwargs, where the keyword matches a Dimension
        in the ViewableElement and the value matches a corresponding entry in the
        data.
        """
        raise NotImplementedError


    def reduce(self, **reduce_map):
        """
        Base class signature to demonstrate API for reducing Elements,
        using some reduce function, e.g. np.mean, which is applied
        along a particular Dimension. The dimensions and reduce functions
        should be passed as keyword arguments.
        """
        raise NotImplementedError


    def table(self, **kwargs):
        """
        This method transforms any ViewableElement type into a Table
        as long as it implements a dimension_values method.
        """
        from ..element import Table
        keys = zip(*[self.dimension_values(dim.name)
                 for dim in self.key_dimensions])
        values = zip(*[self.dimension_values(dim.name)
                       for dim in self.value_dimensions])
        params = dict(key_dimensions=self.key_dimensions,
                      value_dimensions=self.value_dimensions,
                      label=self.label, value=self.value, **kwargs)
        return Table(zip(keys, values), **params)


    def dframe(self):
        import pandas
        column_names = self.dimensions(label=True)
        dim_vals = np.vstack([self.dimension_values(dim) for dim in column_names]).T
        return pandas.DataFrame(dim_vals, columns=column_names)



class Element2D(Element):

    def __init__(self, data, extents=None, **params):
        self._xlim = None if extents is None else (extents[0], extents[2])
        self._ylim = None if extents is None else (extents[1], extents[3])
        super(Element2D, self).__init__(data, **params)

    @property
    def xlabel(self):
        return self.get_dimension(0).pprint_label

    @property
    def ylabel(self):
        return self.get_dimension(1).pprint_label

    @property
    def xlim(self):
        if self._xlim and None not in self._xlim:
            return self._xlim
        else:
            return self.range(0)

    @xlim.setter
    def xlim(self, limits):
        if limits is None or (isinstance(limits, tuple) and len(limits) == 2):
            self._xlim = limits
        else:
            raise ValueError('xlim needs to be a length two tuple or None.')

    @property
    def ylim(self):
        if self._ylim and None not in self._ylim:
            return self._ylim
        else:
            return self.range(1)

    @ylim.setter
    def ylim(self, limits):
        if limits is None or (isinstance(limits, tuple) and len(limits) == 2):
            self._ylim = limits
        else:
            raise ValueError('xlim needs to be a length two tuple or None.')

    @property
    def extents(self):
        """"
        For Element2D the extents is the 4-tuple (left, bottom, right, top).
        """
        l, r = self.xlim if self.xlim else (np.NaN, np.NaN)
        b, t = self.ylim if self.ylim else (np.NaN, np.NaN)
        return l, b, r, t


    @extents.setter
    def extents(self, extents):
        l, b, r, t = extents
        self.xlim, self.ylim = (l, r), (b, t)


class Element3D(Element2D):


    def __init__(self, data, extents=None, **params):
        if extents is not None:
            self._zlim = (extents[2], extents[5])
            extents = (extents[0], extents[1], extents[3], extents[4])
        else:
            self._zlim = None
        super(Element3D, self).__init__(data, extents=extents, **params)

    @property
    def extents(self):
        """"
        For Element3D the extents is the 6-tuple (left, bottom, -z, right, top, +z) using<commit_msg>Made extent property on Element2D general<commit_after>from numbers import Number
import numpy as np

import param

from .dimension import Dimension, ViewableElement
from .layout import Composable, Layout, AdjointLayout, NdLayout
from .ndmapping import OrderedDict, UniformNdMapping
from .overlay import Overlayable, NdOverlay, Overlay, CompositeOverlay
from .util import find_minmax


class Element(ViewableElement, Composable, Overlayable):
    """
    Element is the baseclass for all ViewableElement types, with an x- and
    y-dimension. Subclasses should define the data storage in the
    constructor, as well as methods and properties, which define how
    the data maps onto the x- and y- and value dimensions.
    """

    value = param.String(default='Element')

    def hist(self, dimension=None, num_bins=20, bin_range=None,
             adjoin=True, individually=True, **kwargs):
        """
        The hist method generates a histogram to be adjoined to the
        Element in an AdjointLayout. By default the histogram is
        computed along the first value dimension of the Element,
        however any dimension may be selected. The number of bins and
        the bin_ranges and any kwargs to be passed to the histogram
        operation may also be supplied.
        """
        from ..operation import histogram
        return histogram(self, num_bins=num_bins, bin_range=bin_range, adjoin=adjoin,
                         individually=individually, **kwargs)


    ########################
    # Subclassable methods #
    ########################

    def __init__(self, data, **params):
        super(Element, self).__init__(data, **params)


    def __getitem__(self, key):
        if key is ():
            return self
        else:
            raise NotImplementedError("%s currently does not support getitem" %
                                      type(self).__name__)


    @classmethod
    def collapse_data(cls, data, function=None, **kwargs):
        """
        Class method to collapse a list of data matching the
        data format of the Element type. By implementing this
        method HoloMap can collapse multiple Elements of the
        same type. The kwargs are passed to the collapse
        function. The collapse function must support the numpy
        style axis selection. Valid function include:
        np.mean, np.sum, np.product, np.std,
        scipy.stats.kurtosis etc.
        """
        raise NotImplementedError("Collapsing not implemented for %s." % cls.__name__)


    def closest(self, coords):
        """
        Class method that returns the exact keys for a given list of
        coordinates. The supplied bounds defines the extent within
        which the samples are drawn and the optional shape argument is
        the shape of the numpy array (typically the shape of the .data
        attribute) when applicable.
        """
        return coords


    def sample(self, **samples):
        """
        Base class signature to demonstrate API for sampling Views.
        To sample a ViewableElement kwargs, where the keyword matches a Dimension
        in the ViewableElement and the value matches a corresponding entry in the
        data.
        """
        raise NotImplementedError


    def reduce(self, **reduce_map):
        """
        Base class signature to demonstrate API for reducing Elements,
        using some reduce function, e.g. np.mean, which is applied
        along a particular Dimension. The dimensions and reduce functions
        should be passed as keyword arguments.
        """
        raise NotImplementedError


    def table(self, **kwargs):
        """
        This method transforms any ViewableElement type into a Table
        as long as it implements a dimension_values method.
        """
        from ..element import Table
        keys = zip(*[self.dimension_values(dim.name)
                 for dim in self.key_dimensions])
        values = zip(*[self.dimension_values(dim.name)
                       for dim in self.value_dimensions])
        params = dict(key_dimensions=self.key_dimensions,
                      value_dimensions=self.value_dimensions,
                      label=self.label, value=self.value, **kwargs)
        return Table(zip(keys, values), **params)


    def dframe(self):
        import pandas
        column_names = self.dimensions(label=True)
        dim_vals = np.vstack([self.dimension_values(dim) for dim in column_names]).T
        return pandas.DataFrame(dim_vals, columns=column_names)



class Element2D(Element):

    def __init__(self, data, extents=None, **params):
        self._xlim = None if extents is None else (extents[0], extents[2])
        self._ylim = None if extents is None else (extents[1], extents[3])
        super(Element2D, self).__init__(data, **params)

    @property
    def xlabel(self):
        return self.get_dimension(0).pprint_label

    @property
    def ylabel(self):
        return self.get_dimension(1).pprint_label

    @property
    def xlim(self):
        if self._xlim and None not in self._xlim:
            return self._xlim
        else:
            return self.range(0)

    @xlim.setter
    def xlim(self, limits):
        if limits is None or (isinstance(limits, tuple) and len(limits) == 2):
            self._xlim = limits
        else:
            raise ValueError('xlim needs to be a length two tuple or None.')

    @property
    def ylim(self):
        if self._ylim and None not in self._ylim:
            return self._ylim
        else:
            return self.range(1)

    @ylim.setter
    def ylim(self, limits):
        if limits is None or (isinstance(limits, tuple) and len(limits) == 2):
            self._ylim = limits
        else:
            raise ValueError('xlim needs to be a length two tuple or None.')

    @property
    def extents(self):
        """"
        The extent on Element2D types and its subclasses are a tuple
        of all the dimension lower bounds followed by the upper bounds.
        In case of a simple Element2D this takes the form (l, b, r, t).
        """
        lbound, ubound = [], []
        for kd in self._cached_index_names:
            drange = self.range(kd)
            lower, upper = drange if drange else (np.NaN, np.NaN)
            lbound.append(lower)
            ubound.append(upper)
        return tuple(lbound+ubound)


    @extents.setter
    def extents(self, extents):
        l, b, r, t = extents
        self.xlim, self.ylim = (l, r), (b, t)


class Element3D(Element2D):


    def __init__(self, data, extents=None, **params):
        if extents is not None:
            self._zlim = (extents[2], extents[5])
            extents = (extents[0], extents[1], extents[3], extents[4])
        else:
            self._zlim = None
        super(Element3D, self).__init__(data, extents=extents, **params)

    @property
    def extents(self):
        """"
        For Element3D the extents is the 6-tuple (left, bottom, -z, right, top, +z) using
{'fraction_non_alphanumeric': 0.08771161704611792, 'fraction_numerical': 0.004013426736719206, 'mean_word_length': 2.346764346764347, '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': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7287689', 'n_tokens_mistral': 3792, 'n_tokens_neox': 3655, 'n_words': 1352}