{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<div class=\"contentcontainer med left\" style=\"margin-left: -50px;\">\n",
    "<dl class=\"dl-horizontal\">\n",
    "  <dt>Title</dt> <dd> Contours Element</dd>\n",
    "  <dt>Dependencies</dt> <dd>Bokeh</dd>\n",
    "  <dt>Backends</dt> <dd><a href='./Contours.ipynb'>Bokeh</a></dd> <dd><a href='../matplotlib/Contours.ipynb'>Matplotlib</a></dd>\n",
    "</dl>\n",
    "</div>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import holoviews as hv\n",
    "from holoviews import opts\n",
    "hv.extension('bokeh')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "A ``Contours`` object is similar to a ``Path`` element but allows each individual path to be associated with one or more scalar values declared as value dimensions (``vdims``), which can be used to apply colormapping the ``Contours``. Just like the ``Path`` element ``Contours`` will accept a list of arrays, dataframes, a dictionaries of columns (or any of the other literal formats including tuples of columns and lists of tuples). In order to efficiently represent the scalar values associated with each path the dictionary format is preferable since it can store the scalar values without expanding them into a whole column. For a full description of the path geometry data model see the [Geometry Data User Guide](../user_guide/Geometry_Data.ipynb).\n",
    "\n",
    "To see the effect we will create a number of concentric rings with increasing radii and define a colormap to apply color the circles: "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def circle(radius):\n",
    "    angles = np.linspace(0, 2*np.pi, 100)\n",
    "    return {'x': radius*np.sin(angles), 'y': radius*np.cos(angles), 'radius': radius}\n",
    "\n",
    "hv.Contours([circle(i) for i in np.linspace(0, 1, 10)], vdims='radius')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Often ``Contours`` will be directly computed from an underlying ``Image``, which is made easy using the ``contours`` operation. The operation accepts an ``Image`` type as input and will return ``Contours`` containing iso-contours for each of the specified ``levels``. We will declare an ``Image`` of sine rings\n",
    "and then compute ``Contours`` at 5 levels spaced linearly over the range of values in the Image:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "x,y = np.mgrid[-50:51, -50:51] * 0.05\n",
    "img = hv.Image(np.sin(x**2+y**3))\n",
    "example = img + hv.operation.contours(img, levels=5)\n",
    "example.opts(opts.Contours(cmap='fire', colorbar=True, tools=['hover'], width=325))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "For full documentation and the available style and plot options, use ``hv.help(hv.Contours).``"
   ]
  }
 ],
 "metadata": {
  "language_info": {
   "name": "python",
   "pygments_lexer": "ipython3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
