{
 "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> Spikes Element</dd>\n",
    "  <dt>Dependencies</dt> <dd>Bokeh</dd>\n",
    "  <dt>Backends</dt> <dd><a href='./Spikes.ipynb'>Bokeh</a></dd> <dd><a href='../matplotlib/Spikes.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": [
    "Spikes represent any number of horizontal or vertical line segments with fixed or variable heights. There are a number of different uses for this type.  First of all, they may be used as a rugplot to give an overview of a one-dimensional distribution. They may also be useful in more domain-specific cases, such as visualizing spike trains for neurophysiology or spectrograms in physics and chemistry applications.\n",
    "\n",
    "In the simplest case, a Spikes object represents coordinates in a 1D distribution. Here we set the alpha of the spikes to `0.4` using `line_alpha` and the height of the spikes to `0.1` using `spike_length`:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "xs = np.random.rand(50)\n",
    "spikes = hv.Spikes(xs)\n",
    "spikes.opts(line_alpha=0.4, spike_length=0.1)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We can overlay ``Spikes`` on top of other ``Chart`` elements (such as ``Points`` or ``Curve``) if we want to draw attention to where samples are along the x-axis:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "ys = np.random.rand(50)\n",
    "points = hv.Points((xs, ys))\n",
    "spikes = hv.Spikes(xs)\n",
    "points.opts(color='red') * spikes"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "When supplying a second dimension to the ``Spikes`` element as a value dimension, these additional values will be mapped onto the line height. Optionally, it is also possible to map dimensions to style options. This way we can, for example, plot a [mass spectrogram](https://en.wikipedia.org/wiki/Mass_spectrometry):"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "spikes = hv.Spikes(np.random.rand(20, 2), 'Mass', 'Intensity')\n",
    "spikes.opts(cmap='Reds', color='Intensity')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Another possibility is to draw a set of Spikes offset by a position, which can be useful for plotting discrete events like neurons firing. Here we generate 10 separate random spike trains and distribute them evenly across the space by setting their ``position``. By declaring some ``yticks``, each spike train can be labeled individually:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "overlay = hv.NdOverlay({i: hv.Spikes(np.random.randint(0, 100, 10), kdims='Time').opts(position=0.1*i)\n",
    "                       for i in range(10)}).opts(yticks=[((i+1)*0.1-0.05, i) for i in range(10)])\n",
    "overlay.opts(\n",
    "    opts.Spikes(spike_length=0.1),\n",
    "    opts.NdOverlay(show_legend=False))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Finally, we may use ``Spikes`` to visualize marginal distributions as adjoined plots using the ``<<`` adjoin operator:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "points = hv.Points(np.random.randn(500, 2))\n",
    "composition = points << hv.Spikes(points['y']) << hv.Spikes(points['x'])\n",
    "composition.opts(\n",
    "    opts.Spikes(line_alpha=0.2))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "For full documentation and the available style and plot options, use ``hv.help(hv.Spikes).``"
   ]
  }
 ],
 "metadata": {
  "language_info": {
   "name": "python",
   "pygments_lexer": "ipython3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
