From aff5715b2d43d706f98c6990c8a8e5fd9832c8d5 Mon Sep 17 00:00:00 2001 From: Philipp Rudiger Date: Sat, 15 Jul 2017 17:02:07 -0500 Subject: [PATCH] Added a groupby argument to the histogram operation (#1725) * Added a groupby argument to the histogram operation * Added examples for grouped histograms --- .../demos/bokeh/autompg_histogram.ipynb | 66 +++++++++++++++++++ .../demos/matplotlib/autompg_histogram.ipynb | 66 +++++++++++++++++++ holoviews/operation/element.py | 14 +++- 3 files changed, 144 insertions(+), 2 deletions(-) create mode 100644 examples/gallery/demos/bokeh/autompg_histogram.ipynb create mode 100644 examples/gallery/demos/matplotlib/autompg_histogram.ipynb diff --git a/examples/gallery/demos/bokeh/autompg_histogram.ipynb b/examples/gallery/demos/bokeh/autompg_histogram.ipynb new file mode 100644 index 0000000000..4b5003d03f --- /dev/null +++ b/examples/gallery/demos/bokeh/autompg_histogram.ipynb @@ -0,0 +1,66 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Most examples work across multiple plotting backends, this example is also available for:\n", + "\n", + "* [Matplotlib - autompg_histogram](../matplotlib/autompg_histogram.ipynb)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as np\n", + "import pandas as pd\n", + "import holoviews as hv\n", + "hv.extension('bokeh','matplotlib')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Declaring data" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "from bokeh.sampledata.autompg import autompg\n", + "\n", + "autompg_ds = hv.Dataset(autompg)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Plot" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%%opts Histogram (alpha=0.9) [width=600]\n", + "autompg_ds.hist(dimension='mpg', groupby='cyl', adjoin=False)" + ] + } + ], + "metadata": { + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/examples/gallery/demos/matplotlib/autompg_histogram.ipynb b/examples/gallery/demos/matplotlib/autompg_histogram.ipynb new file mode 100644 index 0000000000..6cc3796ca8 --- /dev/null +++ b/examples/gallery/demos/matplotlib/autompg_histogram.ipynb @@ -0,0 +1,66 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Most examples work across multiple plotting backends, this example is also available for:\n", + "\n", + "* [Bokeh - autompg_histogram](../bokeh/autompg_histogram.ipynb)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as np\n", + "import pandas as pd\n", + "import holoviews as hv\n", + "hv.extension('matplotlib')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Declaring data" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "from bokeh.sampledata.autompg import autompg\n", + "\n", + "autompg_ds = hv.Dataset(autompg)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Plot" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%%opts Histogram [fig_size=200 aspect=2]\n", + "autompg_ds.hist(dimension='mpg', groupby='cyl', adjoin=False)" + ] + } + ], + "metadata": { + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/holoviews/operation/element.py b/holoviews/operation/element.py index d9d323f250..69f4b2423f 100644 --- a/holoviews/operation/element.py +++ b/holoviews/operation/element.py @@ -9,9 +9,9 @@ from param import _is_number from ..core import (Operation, NdOverlay, Overlay, GridMatrix, - HoloMap, Dataset, Element, Collator) + HoloMap, Dataset, Element, Collator, Dimension) from ..core.data import ArrayInterface, DictInterface -from ..core.util import find_minmax, group_sanitizer, label_sanitizer, pd +from ..core.util import find_minmax, group_sanitizer, label_sanitizer, pd, basestring from ..element.chart import Histogram, Scatter from ..element.raster import Raster, Image, RGB, QuadMesh from ..element.path import Contours, Polygons @@ -471,6 +471,9 @@ class histogram(Operation): dimension = param.String(default=None, doc=""" Along which dimension of the Element to compute the histogram.""") + groupby = param.ClassSelector(default=None, class_=(basestring, Dimension), doc=""" + Defines a dimension to group the Histogram returning an NdOverlay of Histograms.""") + individually = param.Boolean(default=True, doc=""" Specifies whether the histogram will be rescaled for each Element in a UniformNdMapping.""") @@ -496,6 +499,13 @@ class histogram(Operation): Used for setting a common style for histograms in a HoloMap or AdjointLayout.""") def _process(self, view, key=None): + if self.p.groupby: + if not isinstance(view, Dataset): + raise ValueError('Cannot use histogram groupby on non-Dataset Element') + grouped = view.groupby(self.p.groupby, group_type=Dataset, container_type=NdOverlay) + self.p.groupby = None + return grouped.map(self._process, Dataset) + if self.p.dimension: selected_dim = self.p.dimension else: