{
 "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> QuadMesh Element</dd>\n",
    "  <dt>Dependencies</dt> <dd>Bokeh</dd>\n",
    "  <dt>Backends</dt> <dd><a href='./QuadMesh.ipynb'>Bokeh</a></dd> <dd><a href='../matplotlib/QuadMesh.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",
    "hv.extension('bokeh')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The basic ``QuadMesh`` is a 2D grid of bins specified as x-/y-values specifying a regular sampling or edges, with arbitrary sampling and an associated 2D array containing the bin values. Here is a simple ``QuadMesh`` with logarithmic sampling along the 'x' dimensions:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "n = 8  # Number of bins in each direction\n",
    "xs = np.logspace(1, 3, n)\n",
    "ys = np.linspace(1, 10, n)\n",
    "zs = np.arange((n-1)**2).reshape(n-1, n-1)\n",
    "hv.QuadMesh((xs, ys, zs))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The coordinate system of a ``QuadMesh`` is defined by the bin edges, therefore any index falling into a binned region will return the appropriate value. ``QuadMesh`` supports inspection of values using the Bokeh hover tools and because the bin edges have continuous values, you can use non-linear axes such as log axes:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%%opts QuadMesh [tools=['hover'] xticks=[10, 100,1000]] QuadMesh.LogScale [logx=True]\n",
    "hv.QuadMesh((xs, ys, zs), group='LinearScale') + hv.QuadMesh((xs, ys, zs), group='LogScale')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Unlike ``Image`` objects, slices must be inclusive of the bin edges but otherwise the slicing semantics are the same. The reason for this difference is that ``QuadMesh`` is really a two-dimensional histogram and when slicing, you only want to see the bins that fall within the specified slice ranges.\n",
    "\n",
    "In the next example, we specify a slice along the x- and y-axis to extract the lower corner and we set the z-dimension range to maintain the full color range of the colormap:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "qmesh = hv.QuadMesh((xs, ys, zs))\n",
    "qmesh[20:400, :8].redim.range(z=qmesh.range('z'))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "As ``QuadMesh`` supports the Bokeh hover tool while ``Image`` does not, we can get use a simple trick to enable hover information: overlay the image with an invisible ``QuadMesh`` cast from the same image. We can set the ``QuadMesh`` alpha to zero while keeping an opaque hover line color:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%%opts QuadMesh [tools=['hover']] (alpha=0 hover_line_alpha=1 hover_line_color='black')\n",
    "img = hv.Image(np.random.rand(10,10))\n",
    "img * hv.QuadMesh(img)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Now when you hover over this visualization, you can see the sample value as well as an outline of the selected bin.\n",
    "\n",
    "For full documentation and the available style and plot options, use ``hv.help(hv.QuadMesh).``"
   ]
  }
 ],
 "metadata": {
  "language_info": {
   "name": "python",
   "pygments_lexer": "ipython3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
