Skip to content

Commit

Permalink
Merge b68c4c3 into fee1696
Browse files Browse the repository at this point in the history
  • Loading branch information
philippjfr committed Dec 14, 2018
2 parents fee1696 + b68c4c3 commit ba88f7b
Show file tree
Hide file tree
Showing 2 changed files with 90 additions and 19 deletions.
101 changes: 83 additions & 18 deletions examples/user_guide/11-Responding_to_Events.ipynb
Expand Up @@ -15,6 +15,8 @@
"source": [
"import numpy as np\n",
"import holoviews as hv\n",
"from holoviews import opts\n",
"\n",
"hv.extension('bokeh')"
]
},
Expand All @@ -37,11 +39,16 @@
"outputs": [],
"source": [
"# Styles and plot options used in this user guide\n",
"%opts Ellipse [bgcolor='white'] (color='black')\n",
"%opts Image (cmap='viridis')\n",
"%opts VLine HLine (color='red' line_width=2)\n",
"%opts Path [show_grid=False bgcolor='white'] (color='black' line_dash='dashdot')\n",
"%opts Area (fill_color='cornsilk' line_width=2 line_color='black')"
"\n",
"opts.defaults(\n",
" opts.Area(fill_color='cornsilk', line_width=2,\n",
" line_color='black'),\n",
" opts.Ellipse(bgcolor='white', color='black'),\n",
" opts.HLine(color='red', line_width=2),\n",
" opts.Image(cmap='viridis'),\n",
" opts.Path(bgcolor='white', color='black', line_dash='dashdot',\n",
" padding=0.1, show_grid=False),\n",
" opts.VLine(color='red', line_width=2))"
]
},
{
Expand All @@ -55,7 +62,7 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"Before introducing streams, let us declare a simple ``DynamicMap`` of the sort discussed in the [Live Data](06-Live_Data.ipynb) user guide. This example consists of a ``Curve`` element showing a [Lissajous curve](https://en.wikipedia.org/wiki/Lissajous_curve) with ``VLine`` and ``HLine`` annotations to form a crosshair:"
"Before introducing streams, let us declare a simple ``DynamicMap`` of the sort discussed in the [Live Data](06-Live_Data.ipynb) user guide. This example consists of a ``Path`` element showing a [Lissajous curve](https://en.wikipedia.org/wiki/Lissajous_curve) with ``VLine`` and ``HLine`` annotations to form a crosshair:"
]
},
{
Expand All @@ -66,14 +73,18 @@
"source": [
"lin = np.linspace(-np.pi,np.pi,300)\n",
"\n",
"def lissajous(t, a,b, delta):\n",
"def lissajous(t, a=3, b=5, delta=np.pi/2.):\n",
" return (np.sin(a * t + delta), np.sin(b * t))\n",
"\n",
"def lissajous_curve(t, a=3,b=5, delta=np.pi/2):\n",
"def lissajous_crosshair(t, a=3, b=5, delta=np.pi/2):\n",
" (x,y) = lissajous(t,a,b,delta)\n",
" return hv.Path(lissajous(lin,a,b,delta)) * hv.VLine(x) * hv.HLine(y)\n",
" return hv.VLine(x) * hv.HLine(y)\n",
"\n",
"crosshair = hv.DynamicMap(lissajous_crosshair, kdims='t').redim.range(t=(-3.,3.))\n",
"\n",
"hv.DynamicMap(lissajous_curve, kdims='t').redim.range(t=(-3.,3.))"
"path = hv.Path(lissajous(lin))\n",
"\n",
"path * crosshair"
]
},
{
Expand All @@ -95,7 +106,7 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"The core concept behind a stream is simple: it is a parameter that can change over time that automatically refreshes code depending on those parameter values. \n",
"The core concept behind a stream is simple: it defines one or more parameters that can change over time that automatically refreshes code depending on those parameter values. \n",
"\n",
"Like all objects in HoloViews, these parameters are declared using [param](https://ioam.github.io/param) and streams are defined as a parameterized subclass of the ``holoviews.streams.Stream``. A more convenient way is to use the ``Stream.define`` classmethod:"
]
Expand Down Expand Up @@ -195,7 +206,7 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"We can now supply this streams object to a ``DynamicMap`` using the same ``lissajous_curve`` callback above by adding it to the ``streams`` list:"
"We can now supply this streams object to a ``DynamicMap`` using the same ``lissajous_crosshair`` callback from above by adding it to the ``streams`` list:"
]
},
{
Expand All @@ -204,8 +215,8 @@
"metadata": {},
"outputs": [],
"source": [
"dmap = hv.DynamicMap(lissajous_curve, streams=[time])\n",
"dmap + lissajous_curve(t=np.pi/4)"
"dmap = hv.DynamicMap(lissajous_crosshair, streams=[time])\n",
"path * dmap + path * lissajous_crosshair(t=np.pi/4.)"
]
},
{
Expand All @@ -223,7 +234,7 @@
"metadata": {},
"outputs": [],
"source": [
"dmap.event( t=0.2)"
"dmap.event(t=0.2)"
]
},
{
Expand Down Expand Up @@ -279,10 +290,11 @@
"XY = Stream.define('XY',x=0.0,y=0.0)\n",
"\n",
"def marker(x,y):\n",
" return hv.Image(np.sin(xx)*np.cos(yy)) * hv.VLine(x) * hv.HLine(y)\n",
" return hv.VLine(x) * hv.HLine(y)\n",
"\n",
"image = hv.Image(np.sin(xx)*np.cos(yy))\n",
"dmap = hv.DynamicMap(marker, streams=[XY()])\n",
"dmap"
"image * dmap"
]
},
{
Expand Down Expand Up @@ -310,12 +322,65 @@
"```python\n",
"X = Stream.define('X',x=0.0)\n",
"Y = Stream.define('Y',y=0.0)\n",
"hv.DynamicMap(marker, streams=[X(),Y()])\n",
"hv.DynamicMap(marker, streams=[X(), Y()])\n",
"```\n",
"\n",
"The reason why you might want to list multiple streams instead of always defining a single stream containing all the required stream parameters will be made clear in the [Custom Interactivity](./12-Custom_Interactivity.ipynb) guide."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Using Parameterized classes as a stream\n",
"\n",
"Creating a custom ``Stream`` class is one easy way to declare parameters, however in many cases you may have already expressed your domain knowledge on a ``Parameterized`` class. A ``DynamicMap`` can easily be linked to the parameters of the class using a so called ``Params`` stream, let's define a simple example which will let use dynamically alter the style applied to the ``Image`` from the previous example. We define a ``Style`` class with two parameters, one to control the colormap and another to vary the number of color levels:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from holoviews.streams import Params\n",
"\n",
"class Style(param.Parameterized):\n",
"\n",
" cmap = param.ObjectSelector(default='viridis', objects=['viridis', 'plasma', 'magma'])\n",
"\n",
" color_levels = param.Integer(default=255, bounds=(1, 255))\n",
"\n",
"style = Style()\n",
"stream = Params(style)\n",
"\n",
"hv.DynamicMap(image.opts, streams=[stream]).opts(colorbar=True, width=400)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Instead of providing a custom callback function we supplied the ``image.opts`` method, which applies the parameters directly as options. Unlike a regular streams class the plot will update whenever a parameter on the instance or class changes, e.g. we can update set the ``cmap`` and ``color_level`` parameters and watch the plot update in response:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"style.color_levels = 10\n",
"style.cmap = 'plasma'"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"This is a powerful pattern to link parameters to a plot, particularly when combined with the [Panel](http://panel.pyviz.org/) library, which makes it easy to generate a set of widgets from a Parameterized class. To see how this works in practice see the [Dashboards user guide](./16-Dashboards.ipynb)."
]
},
{
"cell_type": "markdown",
"metadata": {},
Expand Down
8 changes: 7 additions & 1 deletion holoviews/util/__init__.py
Expand Up @@ -9,7 +9,7 @@
from ..core.operation import OperationCallable
from ..core.spaces import Callable
from ..core import util
from ..streams import Stream
from ..streams import Stream, ParamMethod
from .settings import OutputSettings, list_formats, list_backends

Store.output_settings = OutputSettings
Expand Down Expand Up @@ -720,6 +720,12 @@ def _get_streams(self, map_obj, watch=True):
added to the list.
"""
streams = []

# If callback is a parameterized method and watch is disabled add as stream
param_watch_support = util.param_version >= '1.8.0'
if util.is_param_method(self.p.operation) and param_watch_support:
streams.append(ParamMethod(self.p.operation))

for stream in self.p.streams:
if inspect.isclass(stream) and issubclass(stream, Stream):
stream = stream()
Expand Down

0 comments on commit ba88f7b

Please sign in to comment.