{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### **Title**: Bars Element\n",
    "\n",
    "**Dependencies**: Plotly\n",
    "\n",
    "**Backends**: [Bokeh](../bokeh/Bars.ipynb), [Matplotlib](../matplotlib/Bars.ipynb), [Plotly](./Bars.ipynb)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import holoviews as hv\n",
    "hv.extension('plotly')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The ``Bars`` Element uses bars to show discrete, numerical comparisons across categories. One axis of the chart shows the specific categories being compared and the other axis represents a continuous value.\n",
    "\n",
    "Bars may also be grouped or stacked by supplying a second key dimension representing sub-categories. Therefore the ``Bars`` Element expects a tabular data format with one or two key dimensions (``kdims``) and one or more value dimensions (``vdims``). See the [Tabular Datasets](../../../user_guide/08-Tabular_Datasets.ipynb) user guide for supported data formats, which include arrays, pandas dataframes and dictionaries of arrays."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "data = [('one',8),('two', 10), ('three', 16), ('four', 8), ('five', 4), ('six', 1)]\n",
    "\n",
    "bars = hv.Bars(data, hv.Dimension('Car occupants'), 'Count')\n",
    "\n",
    "bars"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "A ``Bars`` element can be sliced and selecting on like any other element:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "bars[['one', 'two', 'three']] + bars[['four', 'five', 'six']]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "It is possible to define an explicit ordering for a set of Bars by explicit declaring `Dimension.values` either in the Dimension constructor or using the `.redim.values()` approach:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "occupants = hv.Dimension('Car occupants', values=['three', 'two', 'four', 'one', 'five', 'six'])\n",
    "\n",
    "# or using .redim.values(**{'Car Occupants': ['three', 'two', 'four', 'one', 'five', 'six']})\n",
    "\n",
    "hv.Bars(data, occupants, 'Count')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "``Bars`` support nested categorical groupings, e.g. here we will create a random sample of pets sub-divided by male and female:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "samples = 100\n",
    "\n",
    "pets = ['Cat', 'Dog', 'Hamster', 'Rabbit']\n",
    "genders = ['Female', 'Male']\n",
    "\n",
    "pets_sample = np.random.choice(pets, samples)\n",
    "gender_sample = np.random.choice(genders, samples)\n",
    "\n",
    "bars = hv.Bars((pets_sample, gender_sample, np.ones(samples)), ['Pets', 'Gender']).aggregate(function=np.sum)\n",
    "\n",
    "bars.opts(width=1000)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Just as before we can provide an explicit ordering by declaring the `Dimension.values`. Alternatively we can also make use of the `.sort` method, internally `Bars` will use topological sorting to ensure consistent ordering."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "bars.redim.values(Pets=pets, Gender=genders) + bars.sort()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "To drop the second level of tick labels we can set `multi_level=False`, which will indicate the groupings using a legend instead:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "bars.sort() + bars.clone().opts(multi_level=False)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Lastly, Bars can be also be stacked by setting `stacked=True`:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "bars.opts(stacked=True)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "For full documentation and the available style and plot options, use ``hv.help(hv.Bars).``"
   ]
  }
 ],
 "metadata": {
  "language_info": {
   "name": "python",
   "pygments_lexer": "ipython3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
