Source code for holoviews.element.stats

import numpy as np
import param

from ..core.data import Dataset
from ..core.dimension import Dimension, process_dimensions
from ..core.element import Element, Element2D
from ..core.util import get_param_values, unique_iterator
from .selection import Selection1DExpr, Selection2DExpr


[docs]class StatisticsElement(Dataset, Element2D): """ StatisticsElement provides a baseclass for Element types that compute statistics based on the input data, usually a density. The value dimension of such elements are therefore usually virtual and not computed until the element is plotted. """ __abstract = True # Ensure Interface does not add an index _auto_indexable_1d = False def __init__(self, data, kdims=None, vdims=None, **params): if (isinstance(data, Element) and data.interface.datatype != "dataframe"): params.update(get_param_values(data)) kdims = kdims or data.dimensions()[:len(self.kdims)] data = tuple(data.dimension_values(d) for d in kdims) params.update(dict(kdims=kdims, vdims=[], _validate_vdims=False)) super().__init__(data, **params) if not vdims: self.vdims = [Dimension('Density')] elif len(vdims) > 1: raise ValueError(f"{type(self).__name__} expects at most one vdim.") else: self.vdims = process_dimensions(None, vdims)['vdims'] @property def dataset(self): """ The Dataset that this object was created from """ from . import Dataset if self._dataset is None: datatype = list(unique_iterator(self.datatype+Dataset.datatype)) dataset = Dataset(self, dataset=None, pipeline=None, transforms=None, vdims=[], datatype=datatype) return dataset elif not isinstance(self._dataset, Dataset): return Dataset(self, _validate_vdims=False, **self._dataset) return self._dataset
[docs] def range(self, dim, data_range=True, dimension_range=True): """Return the lower and upper bounds of values along dimension. Args: dimension: The dimension to compute the range on. data_range (bool): Compute range from data values dimension_range (bool): Include Dimension ranges Whether to include Dimension range and soft_range in range calculation Returns: Tuple containing the lower and upper bound """ iskdim = self.get_dimension(dim) not in self.vdims return super().range(dim, iskdim, dimension_range)
[docs] def dimension_values(self, dim, expanded=True, flat=True): """Return the values along the requested dimension. Args: dimension: The dimension to return values for expanded (bool, optional): Whether to expand values Whether to return the expanded values, behavior depends on the type of data: * Columnar: If false returns unique values * Geometry: If false returns scalar values per geometry * Gridded: If false returns 1D coordinates flat (bool, optional): Whether to flatten array Returns: NumPy array of values along the requested dimension """ dim = self.get_dimension(dim, strict=True) if dim in self.vdims: return np.full(len(self), np.nan) return self.interface.values(self, dim, expanded, flat)
[docs] def get_dimension_type(self, dim): """Get the type of the requested dimension. Type is determined by Dimension.type attribute or common type of the dimension values, otherwise None. Args: dimension: Dimension to look up by name or by index Returns: Declared type of values along the dimension """ dim = self.get_dimension(dim) if dim is None: return None elif dim.type is not None: return dim.type elif dim in self.vdims: return np.float64 return self.interface.dimension_type(self, dim)
[docs] def dframe(self, dimensions=None, multi_index=False): """Convert dimension values to DataFrame. Returns a pandas dataframe of columns along each dimension, either completely flat or indexed by key dimensions. Args: dimensions: Dimensions to return as columns multi_index: Convert key dimensions to (multi-)index Returns: DataFrame of columns corresponding to each dimension """ if dimensions: dimensions = [self.get_dimension(d, strict=True) for d in dimensions] else: dimensions = self.kdims vdims = [d for d in dimensions if d in self.vdims] if vdims: raise ValueError('{} element does not hold data for value ' 'dimensions. Could not return data for {} ' 'dimension(s).'.format(type(self).__name__, ', '.join([d.name for d in vdims]))) return super().dframe(dimensions, False)
[docs] def columns(self, dimensions=None): """Convert dimension values to a dictionary. Returns a dictionary of column arrays along each dimension of the element. Args: dimensions: Dimensions to return as columns Returns: Dictionary of arrays for each dimension """ if dimensions is None: dimensions = self.kdims else: dimensions = [self.get_dimension(d, strict=True) for d in dimensions] vdims = [d for d in dimensions if d in self.vdims] if vdims: raise ValueError('{} element does not hold data for value ' 'dimensions. Could not return data for {} ' 'dimension(s).'.format(type(self).__name__, ', '.join([d.name for d in vdims]))) return dict([(d.name, self.dimension_values(d)) for d in dimensions])
[docs]class Bivariate(Selection2DExpr, StatisticsElement): """ Bivariate elements are containers for two dimensional data, which is to be visualized as a kernel density estimate. The data should be supplied in a tabular format of x- and y-columns. """ group = param.String(default="Bivariate", constant=True) kdims = param.List(default=[Dimension('x'), Dimension('y')], bounds=(2, 2)) vdims = param.List(default=[Dimension('Density')], bounds=(0,1))
[docs]class Distribution(Selection1DExpr, StatisticsElement): """ Distribution elements provides a representation for a one-dimensional distribution which can be visualized as a kernel density estimate. The data should be supplied in a tabular format and will use the first column. """ group = param.String(default='Distribution', constant=True) kdims = param.List(default=[Dimension('Value')], bounds=(1, 1)) vdims = param.List(default=[Dimension('Density')], bounds=(0, 1))
[docs]class BoxWhisker(Selection1DExpr, Dataset, Element2D): """ BoxWhisker represent data as a distributions highlighting the median, mean and various percentiles. It may have a single value dimension and any number of key dimensions declaring the grouping of each violin. """ group = param.String(default='BoxWhisker', constant=True) kdims = param.List(default=[], bounds=(0, None)) vdims = param.List(default=[Dimension('y')], bounds=(1,1)) _inverted_expr = True
[docs]class Violin(BoxWhisker): """ Violin elements represent data as 1D distributions visualized as a kernel-density estimate. It may have a single value dimension and any number of key dimensions declaring the grouping of each violin. """ group = param.String(default='Violin', constant=True)
[docs]class HexTiles(Selection2DExpr, Dataset, Element2D): """ HexTiles is a statistical element with a visual representation that renders a density map of the data values as a hexagonal grid. Before display the data is aggregated either by counting the values in each hexagonal bin or by computing aggregates. """ group = param.String(default='HexTiles', constant=True) kdims = param.List(default=[Dimension('x'), Dimension('y')], bounds=(2, 2))