From be3128262d8d184f50811f6abe1dfc22ef558d93 Mon Sep 17 00:00:00 2001 From: Philipp Rudiger Date: Thu, 1 Jun 2017 00:46:31 +0100 Subject: [PATCH] Add example notebooks for Elements (#1476) --- examples/elements/bokeh/Area.ipynb | 131 ++++++++++++++ examples/elements/bokeh/Bars.ipynb | 116 +++++++++++++ examples/elements/bokeh/Bounds.ipynb | 89 ++++++++++ examples/elements/bokeh/Box.ipynb | 91 ++++++++++ examples/elements/bokeh/BoxWhisker.ipynb | 99 +++++++++++ examples/elements/bokeh/Contours.ipynb | 99 +++++++++++ examples/elements/bokeh/Curve.ipynb | 106 ++++++++++++ examples/elements/bokeh/Ellipse.ipynb | 77 +++++++++ examples/elements/bokeh/ErrorBars.ipynb | 108 ++++++++++++ examples/elements/bokeh/HLine.ipynb | 72 ++++++++ examples/elements/bokeh/HSV.ipynb | 115 +++++++++++++ examples/elements/bokeh/HeatMap.ipynb | 113 +++++++++++++ examples/elements/bokeh/Histogram.ipynb | 119 +++++++++++++ examples/elements/bokeh/Image.ipynb | 131 ++++++++++++++ examples/elements/bokeh/ItemTable.ipynb | 70 ++++++++ examples/elements/bokeh/Path.ipynb | 125 ++++++++++++++ examples/elements/bokeh/Points.ipynb | 133 +++++++++++++++ examples/elements/bokeh/Polygons.ipynb | 99 +++++++++++ examples/elements/bokeh/QuadMesh.ipynb | 140 +++++++++++++++ examples/elements/bokeh/RGB.ipynb | 136 +++++++++++++++ examples/elements/bokeh/Raster.ipynb | 78 +++++++++ examples/elements/bokeh/Scatter.ipynb | 137 +++++++++++++++ examples/elements/bokeh/Spikes.ipynb | 152 +++++++++++++++++ examples/elements/bokeh/Spline.ipynb | 78 +++++++++ examples/elements/bokeh/Spread.ipynb | 112 ++++++++++++ examples/elements/bokeh/Table.ipynb | 155 +++++++++++++++++ examples/elements/bokeh/Text.ipynb | 71 ++++++++ examples/elements/bokeh/VLine.ipynb | 72 ++++++++ examples/elements/bokeh/VectorField.ipynb | 160 ++++++++++++++++++ examples/elements/matplotlib/Area.ipynb | 131 ++++++++++++++ examples/elements/matplotlib/Arrow.ipynb | 72 ++++++++ examples/elements/matplotlib/Bars.ipynb | 109 ++++++++++++ examples/elements/matplotlib/Bounds.ipynb | 89 ++++++++++ examples/elements/matplotlib/Box.ipynb | 91 ++++++++++ examples/elements/matplotlib/BoxWhisker.ipynb | 99 +++++++++++ examples/elements/matplotlib/Contours.ipynb | 99 +++++++++++ examples/elements/matplotlib/Curve.ipynb | 106 ++++++++++++ examples/elements/matplotlib/Ellipse.ipynb | 77 +++++++++ examples/elements/matplotlib/ErrorBars.ipynb | 108 ++++++++++++ examples/elements/matplotlib/HLine.ipynb | 72 ++++++++ examples/elements/matplotlib/HSV.ipynb | 115 +++++++++++++ examples/elements/matplotlib/HeatMap.ipynb | 113 +++++++++++++ examples/elements/matplotlib/Histogram.ipynb | 119 +++++++++++++ examples/elements/matplotlib/Image.ipynb | 131 ++++++++++++++ examples/elements/matplotlib/ItemTable.ipynb | 69 ++++++++ examples/elements/matplotlib/Path.ipynb | 125 ++++++++++++++ examples/elements/matplotlib/Points.ipynb | 133 +++++++++++++++ examples/elements/matplotlib/Polygons.ipynb | 99 +++++++++++ examples/elements/matplotlib/QuadMesh.ipynb | 120 +++++++++++++ examples/elements/matplotlib/RGB.ipynb | 136 +++++++++++++++ examples/elements/matplotlib/Raster.ipynb | 78 +++++++++ examples/elements/matplotlib/Scatter.ipynb | 137 +++++++++++++++ examples/elements/matplotlib/Spikes.ipynb | 152 +++++++++++++++++ examples/elements/matplotlib/Spline.ipynb | 78 +++++++++ examples/elements/matplotlib/Spread.ipynb | 111 ++++++++++++ examples/elements/matplotlib/Table.ipynb | 153 +++++++++++++++++ examples/elements/matplotlib/Text.ipynb | 71 ++++++++ examples/elements/matplotlib/VLine.ipynb | 72 ++++++++ .../elements/matplotlib/VectorField.ipynb | 160 ++++++++++++++++++ holoviews/element/chart.py | 4 +- holoviews/operation/element.py | 9 - tests/testoperation.py | 9 +- 62 files changed, 6415 insertions(+), 16 deletions(-) create mode 100644 examples/elements/bokeh/Area.ipynb create mode 100644 examples/elements/bokeh/Bars.ipynb create mode 100644 examples/elements/bokeh/Bounds.ipynb create mode 100644 examples/elements/bokeh/Box.ipynb create mode 100644 examples/elements/bokeh/BoxWhisker.ipynb create mode 100644 examples/elements/bokeh/Contours.ipynb create mode 100644 examples/elements/bokeh/Curve.ipynb create mode 100644 examples/elements/bokeh/Ellipse.ipynb create mode 100644 examples/elements/bokeh/ErrorBars.ipynb create mode 100644 examples/elements/bokeh/HLine.ipynb create mode 100644 examples/elements/bokeh/HSV.ipynb create mode 100644 examples/elements/bokeh/HeatMap.ipynb create mode 100644 examples/elements/bokeh/Histogram.ipynb create mode 100644 examples/elements/bokeh/Image.ipynb create mode 100644 examples/elements/bokeh/ItemTable.ipynb create mode 100644 examples/elements/bokeh/Path.ipynb create mode 100644 examples/elements/bokeh/Points.ipynb create mode 100644 examples/elements/bokeh/Polygons.ipynb create mode 100644 examples/elements/bokeh/QuadMesh.ipynb create mode 100644 examples/elements/bokeh/RGB.ipynb create mode 100644 examples/elements/bokeh/Raster.ipynb create mode 100644 examples/elements/bokeh/Scatter.ipynb create mode 100644 examples/elements/bokeh/Spikes.ipynb create mode 100644 examples/elements/bokeh/Spline.ipynb create mode 100644 examples/elements/bokeh/Spread.ipynb create mode 100644 examples/elements/bokeh/Table.ipynb create mode 100644 examples/elements/bokeh/Text.ipynb create mode 100644 examples/elements/bokeh/VLine.ipynb create mode 100644 examples/elements/bokeh/VectorField.ipynb create mode 100644 examples/elements/matplotlib/Area.ipynb create mode 100644 examples/elements/matplotlib/Arrow.ipynb create mode 100644 examples/elements/matplotlib/Bars.ipynb create mode 100644 examples/elements/matplotlib/Bounds.ipynb create mode 100644 examples/elements/matplotlib/Box.ipynb create mode 100644 examples/elements/matplotlib/BoxWhisker.ipynb create mode 100644 examples/elements/matplotlib/Contours.ipynb create mode 100644 examples/elements/matplotlib/Curve.ipynb create mode 100644 examples/elements/matplotlib/Ellipse.ipynb create mode 100644 examples/elements/matplotlib/ErrorBars.ipynb create mode 100644 examples/elements/matplotlib/HLine.ipynb create mode 100644 examples/elements/matplotlib/HSV.ipynb create mode 100644 examples/elements/matplotlib/HeatMap.ipynb create mode 100644 examples/elements/matplotlib/Histogram.ipynb create mode 100644 examples/elements/matplotlib/Image.ipynb create mode 100644 examples/elements/matplotlib/ItemTable.ipynb create mode 100644 examples/elements/matplotlib/Path.ipynb create mode 100644 examples/elements/matplotlib/Points.ipynb create mode 100644 examples/elements/matplotlib/Polygons.ipynb create mode 100644 examples/elements/matplotlib/QuadMesh.ipynb create mode 100644 examples/elements/matplotlib/RGB.ipynb create mode 100644 examples/elements/matplotlib/Raster.ipynb create mode 100644 examples/elements/matplotlib/Scatter.ipynb create mode 100644 examples/elements/matplotlib/Spikes.ipynb create mode 100644 examples/elements/matplotlib/Spline.ipynb create mode 100644 examples/elements/matplotlib/Spread.ipynb create mode 100644 examples/elements/matplotlib/Table.ipynb create mode 100644 examples/elements/matplotlib/Text.ipynb create mode 100644 examples/elements/matplotlib/VLine.ipynb create mode 100644 examples/elements/matplotlib/VectorField.ipynb diff --git a/examples/elements/bokeh/Area.ipynb b/examples/elements/bokeh/Area.ipynb new file mode 100644 index 0000000000..5c49345324 --- /dev/null +++ b/examples/elements/bokeh/Area.ipynb @@ -0,0 +1,131 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
\n", + "
\n", + "
Title
Area Element
\n", + "
Dependencies
Bokeh
\n", + "
Backends
[Bokeh](./Area.ipynb)
[Matplotlib](../matplotlib/Area.ipynb)
\n", + "
\n", + "
" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "import numpy as np\n", + "import holoviews as hv\n", + "hv.notebook_extension('bokeh')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "``Area`` elements are ``Curve`` elements where the area below the line is filled. Like ``Curve`` elements, ``Area`` elements are used to display the development of quantitative values over an interval or time period. ``Area`` Elements may also be stacked to display multiple data series in a cumulative fashion over the value dimension.\n", + "\n", + "The data of an ``Area`` Element should be tabular with one key dimension representing the samples over the interval or the timeseries and one or two value dimensions. A single value dimension will fill the area between the curve and the x-axis, while two value dimensions will fill the area between the curves. See the [Columnar Data Tutorial](../Tutorials/Columnar_Data.ipynb) for supported data formats, which include arrays, pandas dataframes and dictionaries of arrays." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Area under the curve\n", + "\n", + "By default the Area Element draws just the area under the curve, i.e. the region between the curve and the origin." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "xs = np.linspace(0, np.pi*4, 40)\n", + "hv.Area((xs, np.sin(xs)))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Area between curves\n", + "\n", + "When supplied a second value dimension the area is defined as the area between two curves." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "X = np.linspace(0,3,200)\n", + "Y = X**2 + 3\n", + "Y2 = np.exp(X) + 2\n", + "Y3 = np.cos(X)\n", + "hv.Area((X, Y, Y2), vdims=['y', 'y2']) * hv.Area((X, Y, Y3), vdims=['y', 'y3'])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Stacked areas \n", + "\n", + "Areas are also useful to visualize multiple variables changing over time, but in order to be able to compare them the areas need to be stacked. To do this, use the ``Area.stack`` classmethod to stack multiple ``Area`` elements in an (Nd)Overlay.\n", + "\n", + "In this example we will generate a set of 5 arrays representing percentages and create an ``Overlay`` of them. Then we simply call the ``stack`` method with this overlay to get a stacked area chart.\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "values = np.random.rand(5, 20)\n", + "percentages = (values/values.sum(axis=0)).T*100\n", + "\n", + "overlay = hv.Overlay([hv.Area(percentages[:, i], vdims=[hv.Dimension('value', unit='%')]) for i in range(5)])\n", + "overlay + hv.Area.stack(overlay)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python [conda env:science]", + "language": "python", + "name": "conda-env-science-py" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 2 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython2", + "version": "2.7.13" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/examples/elements/bokeh/Bars.ipynb b/examples/elements/bokeh/Bars.ipynb new file mode 100644 index 0000000000..b8d9352803 --- /dev/null +++ b/examples/elements/bokeh/Bars.ipynb @@ -0,0 +1,116 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
\n", + "
\n", + "
Title
Bars Element
\n", + "
Dependencies
Bokeh
\n", + "
Backends
[Bokeh](./Bars.ipynb)
[Matplotlib](../matplotlib/Bars.ipynb)
\n", + "
\n", + "
" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "import numpy as np\n", + "import holoviews as hv\n", + "hv.notebook_extension('bokeh')" + ] + }, + { + "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 stacked by supplying a second key dimensions representing sub-categories. Therefore the ``Bars`` Element expects a tabular data format with one or two key dimensions and one value dimension. See the [Columnar Data Tutorial](../Tutorials/Columnar_Data.ipynb) for supported data formats, which include arrays, pandas dataframes and dictionaries of arrays." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "data = [('one',8),('two', 10), ('three', 16), ('four', 8), ('five', 4), ('six', 1)]\n", + "bars = hv.Bars(data, kdims=[hv.Dimension('Car occupants')], vdims=['Count'])\n", + "bars" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "You can 'slice' a ``Bars`` element by selecting categories as follows:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "bars[['one', 'two', 'three']] + bars[['four', 'five', 'six']]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "``Bars`` support stacking just like the ``Area`` element as well as grouping by a second key dimension. To activate grouping and stacking set the ``group_index`` or ``stack_index`` to the dimension name or dimension index:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "%%opts Bars.Grouped [group_index='Group'] Bars.Stacked [stack_index='Group']\n", + "from itertools import product\n", + "np.random.seed(3)\n", + "index, groups = ['A', 'B'], ['a', 'b']\n", + "keys = product(index, groups)\n", + "bars = hv.Bars([k+(np.random.rand()*100.,) for k in keys],\n", + " kdims=['Index', 'Group'], vdims=['Count'])\n", + "bars.relabel(group='Grouped') + bars.relabel(group='Stacked')" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python [conda env:science]", + "language": "python", + "name": "conda-env-science-py" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 2 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython2", + "version": "2.7.13" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/examples/elements/bokeh/Bounds.ipynb b/examples/elements/bokeh/Bounds.ipynb new file mode 100644 index 0000000000..8919a4e00e --- /dev/null +++ b/examples/elements/bokeh/Bounds.ipynb @@ -0,0 +1,89 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
\n", + "
\n", + "
Title
Bounds Element
\n", + "
Dependencies
Bokeh
\n", + "
Backends
[Bokeh](./Bounds.ipynb)
[Matplotlib](../matplotlib/Bounds.ipynb)
\n", + "
\n", + "
" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "import numpy as np\n", + "import holoviews as hv\n", + "hv.notebook_extension('bokeh')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "A ``Bounds`` element is an box shaped annotation that is specified as a tuple in (left, bottom, right, top) format:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "%%opts Bounds (color='orange' line_width=6)\n", + "penguins = hv.RGB.load_image('../../../doc/assets/penguins.png')\n", + "penguins * hv.Bounds((-0.15, -0.4, 0.2, 0))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "It is useful for denoting a region of interest defined by some bounds (such as a slice) which is unlike the [``Box``](./Box.ipynb) element which is useful for drawing a box at a specific location. Here we show the a slice of the ``RGB`` element (green channel only) outlined by the bounds. Note that the values in the ``Bounds`` tuple are the same ones as used in the slice:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "penguins * penguins[-0.15:0.2, -0.4:0, 'G'] * hv.Bounds((-0.15, -0.4, 0.2, 0))" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 2", + "language": "python", + "name": "python2" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 2 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython2", + "version": "2.7.13" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/examples/elements/bokeh/Box.ipynb b/examples/elements/bokeh/Box.ipynb new file mode 100644 index 0000000000..3f9fb9c25d --- /dev/null +++ b/examples/elements/bokeh/Box.ipynb @@ -0,0 +1,91 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
\n", + "
\n", + "
Title
Box Element
\n", + "
Dependencies
Bokeh
\n", + "
Backends
[Bokeh](./Box.ipynb)
[Matplotlib](../matplotlib/Box.ipynb)
\n", + "
\n", + "
" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "import numpy as np\n", + "import holoviews as hv\n", + "hv.notebook_extension('bokeh')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "A ``Box`` is an annotation that takes a center x-position, a center y-position and a width:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "%%opts Box (line_width=5 color='purple') Image (cmap='gray')\n", + "data = np.sin(np.mgrid[0:100,0:100][1]/10.0)\n", + "data[range(30, 70), range(30, 70)] = -3\n", + "hv.Image(data) * hv.Box(-0, 0, 0.5 )" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "In addition to these arguments, it supports an optional ``aspect ratio``:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "%%opts Box (line_width=5 color='purple') Image (cmap='gray')\n", + "hv.Image(data) * hv.Box(-0, 0, 0.25, aspect=3)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 2", + "language": "python", + "name": "python2" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 2 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython2", + "version": "2.7.13" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/examples/elements/bokeh/BoxWhisker.ipynb b/examples/elements/bokeh/BoxWhisker.ipynb new file mode 100644 index 0000000000..cc9d6b92ea --- /dev/null +++ b/examples/elements/bokeh/BoxWhisker.ipynb @@ -0,0 +1,99 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
\n", + "
\n", + "
Title
BoxWhisker Element
\n", + "
Dependencies
Bokeh
\n", + "
Backends
[Bokeh](./BoxWhisker.ipynb)
[Matplotlib](../matplotlib/BoxWhisker.ipynb)
\n", + "
\n", + "
" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "import numpy as np\n", + "import holoviews as hv\n", + "hv.notebook_extension('bokeh')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "A ``BoxWhisker`` Element is a quick way of visually summarizing one or more groups of numerical data through their quartiles. \n", + "\n", + "The data of a ``BoxWhisker`` Element may have any number of key dimensions representing the grouping of the value dimension and a single value dimensions representing the distribution of values within each group. See the [Columnar Data Tutorial](../Tutorials/Columnar_Data.ipynb) for supported data formats, which include arrays, pandas dataframes and dictionaries of arrays." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Without any groups a BoxWhisker Element represents a single distribution of values:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "hv.BoxWhisker(np.random.randn(1000), vdims=['Value'])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "By supplying key dimensions we can compare our distributions across multiple variables." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "%%opts BoxWhisker [width=600 height=400 show_legend=False] (whisker_color='gray' color='white')\n", + "groups = [chr(65+g) for g in np.random.randint(0, 3, 200)]\n", + "hv.BoxWhisker((groups, np.random.randint(0, 5, 200), np.random.randn(200)),\n", + " kdims=['Group', 'Category'], vdims=['Value']).sort()" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python [conda env:science]", + "language": "python", + "name": "conda-env-science-py" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 2 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython2", + "version": "2.7.13" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/examples/elements/bokeh/Contours.ipynb b/examples/elements/bokeh/Contours.ipynb new file mode 100644 index 0000000000..3e6190f59c --- /dev/null +++ b/examples/elements/bokeh/Contours.ipynb @@ -0,0 +1,99 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
\n", + "
\n", + "
Title
Contours Element
\n", + "
Dependencies
Bokeh
\n", + "
Backends
[Bokeh](./Contours.ipynb)
[Matplotlib](../matplotlib/Contours.ipynb)
\n", + "
\n", + "
" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "import numpy as np\n", + "import holoviews as hv\n", + "hv.notebook_extension('bokeh')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "A ``Contours`` object is similar to ``Path`` object except it may be associated with a numeric value (the ``level``), which can be used to apply colormapping the ``Contours``. To see the effect of this we can create a number of ``Contours`` with varying shapes and ``level`` values. In this case we will create a number of concentric rings with increasing radii and level values and colormap the ``Contours`` with the viridis colormap:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "%%opts Contours (cmap='viridis')\n", + "\n", + "def circle(radius, x=0, y=0):\n", + " angles = np.linspace(0, 2*np.pi, 100)\n", + " return np.array(list(zip(x+radius*np.sin(angles), y+radius*np.cos(angles))))\n", + "\n", + "hv.Overlay([hv.Contours([circle(i+0.05)], level=i) for i in np.linspace(0, 1, 10)])" + ] + }, + { + "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 compute an ``NdOverlay`` containing a ``Contours`` Element 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": { + "collapsed": false + }, + "outputs": [], + "source": [ + "%%opts Contours [show_legend=False colorbar=True width=325] (cmap='fire')\n", + "x,y = np.mgrid[-50:51, -50:51] * 0.05\n", + "img = hv.Image(np.sin(x**2+y**3))\n", + "\n", + "z0, z1 = img.range('z')\n", + "img + hv.operation.contours(img, levels=np.linspace(z0, z1, 5), overlaid=False)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 2", + "language": "python", + "name": "python2" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 2 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython2", + "version": "2.7.13" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/examples/elements/bokeh/Curve.ipynb b/examples/elements/bokeh/Curve.ipynb new file mode 100644 index 0000000000..68ce8c9735 --- /dev/null +++ b/examples/elements/bokeh/Curve.ipynb @@ -0,0 +1,106 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
\n", + "
\n", + "
Title
Curve Element
\n", + "
Dependencies
Bokeh
\n", + "
Backends
[Bokeh](./Curve.ipynb)
[Matplotlib](../matplotlib/Curve.ipynb)
\n", + "
\n", + "
" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "import numpy as np\n", + "import holoviews as hv\n", + "hv.notebook_extension('bokeh')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "``Curve`` Elements are used to display quantitative values over a continuous interval or time span. They accept tabular data with one key dimension representing the samples along the x-axis and one value dimension of the height of the curve at for each sample. See the [Columnar Data Tutorial](../Tutorials/Columnar_Data.ipynb) for supported data formats, which include arrays, pandas dataframes and dictionaries of arrays." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Simple Curve\n", + "\n", + "A ``Curve`` is a set of values provided for some set of keys from a [continuously indexable 1D coordinate system](Continuous_Coordinates.ipynb), where the plotted values will be connected up because they are assumed to be samples from a continuous relation." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "points = [(0.1*i, np.sin(0.1*i)) for i in range(100)]\n", + "hv.Curve(points)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Interpolation" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The ``Curve`` also supports the ``interpolation`` plot option to determine whether to linearly interpolate the curve values or to draw discrete steps:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "%%opts Curve [width=600] NdOverlay [legend_position='right']\n", + "hv.NdOverlay({interp: hv.Curve(points[::8])(plot=dict(interpolation=interp))\n", + " for interp in ['linear', 'steps-mid', 'steps-pre', 'steps-post']})" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python [conda env:science]", + "language": "python", + "name": "conda-env-science-py" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 2 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython2", + "version": "2.7.13" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/examples/elements/bokeh/Ellipse.ipynb b/examples/elements/bokeh/Ellipse.ipynb new file mode 100644 index 0000000000..f005924169 --- /dev/null +++ b/examples/elements/bokeh/Ellipse.ipynb @@ -0,0 +1,77 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
\n", + "
\n", + "
Title
Ellipse Element
\n", + "
Dependencies
Bokeh
\n", + "
Backends
[Bokeh](./Ellipse.ipynb)
[Matplotlib](../matplotlib/Ellipse.ipynb)
\n", + "
\n", + "
" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "import numpy as np\n", + "import holoviews as hv\n", + "hv.notebook_extension('bokeh')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "An ``Ellipse`` is an annotation that takes a center x-position, a center y-position, a width and an optional aspect ratio:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "%%opts Ellipse (line_width=6)\n", + "# Generate some data\n", + "c1 = np.random.normal(loc=2, scale=0.2, size=(200,200))\n", + "c2x = np.random.normal(loc=-2, scale=0.6, size=200)\n", + "c2y = np.random.normal(loc=-2, scale=0.1, size=200)\n", + "c3 = np.random.normal(loc=0, scale=1.5, size=(400,400))\n", + "# Create an overlay of points and ellipses\n", + "clusters = hv.Points(c1) * hv.Points((c2x, c2y)) * hv.Points(c3)\n", + "clusters * hv.Ellipse(-2,-2, 0.2*12, aspect=1.5) * hv.Ellipse(2,2, 0.6*4)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 2", + "language": "python", + "name": "python2" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 2 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython2", + "version": "2.7.13" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/examples/elements/bokeh/ErrorBars.ipynb b/examples/elements/bokeh/ErrorBars.ipynb new file mode 100644 index 0000000000..4c52f74ad1 --- /dev/null +++ b/examples/elements/bokeh/ErrorBars.ipynb @@ -0,0 +1,108 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
\n", + "
\n", + "
Title
ErrorBars Element
\n", + "
Dependencies
Bokeh
\n", + "
Backends
[Bokeh](./ErrorBars.ipynb)
[Matplotlib](../matplotlib/ErrorBars.ipynb)
\n", + "
\n", + "
" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "import numpy as np\n", + "import holoviews as hv\n", + "hv.notebook_extension('bokeh')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "``ErrorBars`` provide a visual indicator for the variability of the plotted data on a graph. They are usually applied on top of other plots such as scatter, curve or bar plots to indicate the variability in each sample. \n", + "\n", + "``ErrorBars`` may be used to represent symmetric error or assymetric error. An ``ErrorBars`` Element must have one key dimensions representing the samples along the x-axis and two or three value dimensions representing the value of the sample and positive and negative error values associated with that sample. See the [Columnar Data Tutorial](../Tutorials/Columnar_Data.ipynb) for supported data formats, which include arrays, pandas dataframes and dictionaries of arrays." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Symmetric error\n", + "\n", + "By default the ``ErrorBars`` Element accepts x- and y-coordinates along with a symmetric error value:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "np.random.seed(7)\n", + "errors = [(0.1*i, np.sin(0.1*i), np.random.rand()/2) for i in np.linspace(0, 100, 11)]\n", + "hv.Curve(errors) * hv.ErrorBars(errors)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Assymetric error" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "``ErrorBars`` is a set of x-/y-coordinates with associated error values. Error values may be either symmetric or asymmetric, and thus can be supplied as an Nx3 or Nx4 array (or any of the alternative constructors Chart Elements allow)." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "errors = [(0.1*i, np.sin(0.1*i), np.random.rand()/2, np.random.rand()/4) for i in np.linspace(0, 100, 11)]\n", + "hv.Curve(errors) * hv.ErrorBars(errors, vdims=['y', 'yerrneg', 'yerrpos'])" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python [conda env:science]", + "language": "python", + "name": "conda-env-science-py" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 2 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython2", + "version": "2.7.13" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/examples/elements/bokeh/HLine.ipynb b/examples/elements/bokeh/HLine.ipynb new file mode 100644 index 0000000000..a111f875a1 --- /dev/null +++ b/examples/elements/bokeh/HLine.ipynb @@ -0,0 +1,72 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
\n", + "
\n", + "
Title
HLine Element
\n", + "
Dependencies
Bokeh
\n", + "
Backends
[Bokeh](./HLine.ipynb)
[Matplotlib](../matplotlib/HLine.ipynb)
\n", + "
\n", + "
" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "import numpy as np\n", + "import holoviews as hv\n", + "hv.notebook_extension('bokeh')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The ``HLine`` element is a type of annotation that marks a position along the y-axis. Here is an ``HLine`` element that marks the mean of a points distributions:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "%%opts HLine (color='blue' line_width=6) Points (color='#D3D3D3')\n", + "xs = np.random.normal(size=100)\n", + "ys = np.random.normal(size=100) * xs\n", + "hv.Points((xs,ys)) * hv.HLine(ys.mean())" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 2", + "language": "python", + "name": "python2" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 2 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython2", + "version": "2.7.13" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/examples/elements/bokeh/HSV.ipynb b/examples/elements/bokeh/HSV.ipynb new file mode 100644 index 0000000000..4b7e2fe10f --- /dev/null +++ b/examples/elements/bokeh/HSV.ipynb @@ -0,0 +1,115 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
\n", + "
\n", + "
Title
HSV Element
\n", + "
Dependencies
Bokeh
\n", + "
Backends
[Bokeh](./HSV.ipynb)
[Matplotlib](../matplotlib/HSV.ipynb)
\n", + "
\n", + "
" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "import numpy as np\n", + "import holoviews as hv\n", + "hv.notebook_extension('bokeh')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "HoloViews makes it trivial to work in any color space that can be converted to ``RGB`` by making a simple subclass of ``RGB`` as appropriate. For instance, we also provide the HSV (hue, saturation, value) color space, which is useful for plotting cyclic data (as the Hue) along with two additional dimensions (controlling the saturation and value of the color, respectively).\n", + "\n", + "Like other raster based Element types ``HSV`` accepts gridded data, which may be supplied as a simple array ``NxMx3`` ndarray representing hue, saturation and value channels along with bounds or explicit array coordinates. See the [Gridded Data Tutorial](../doc/Gridded_Data.ipynb) tutorial to see the accepted data formats." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "x,y = np.mgrid[-50:51, -50:51] * 0.1\n", + "h = 0.5 + np.sin(0.2*(x**2+y**2)) / 2.0\n", + "s = 0.5*np.cos(y*3)+0.5\n", + "v = 0.5*np.cos(x*3)+0.5\n", + "\n", + "hsv = hv.HSV(np.dstack([h, s, v]))\n", + "hsv" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "You can see how this is created from the original channels:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "%opts Image (cmap='gray')\n", + "hsv[..., 'H'].relabel('H') + hsv[..., 'S'].relabel('S') + hsv[..., 'V'].relabel('V')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "An ``HSV`` Element can also easily be converted to an ``RGB`` Element using the ``rgb`` property:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "print(hsv.rgb)\n", + "hsv.rgb[..., 'R'] + hsv.rgb[..., 'G'] + hsv.rgb[..., 'B']" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python [conda env:science]", + "language": "python", + "name": "conda-env-science-py" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 2 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython2", + "version": "2.7.13" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/examples/elements/bokeh/HeatMap.ipynb b/examples/elements/bokeh/HeatMap.ipynb new file mode 100644 index 0000000000..680c7763b4 --- /dev/null +++ b/examples/elements/bokeh/HeatMap.ipynb @@ -0,0 +1,113 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
\n", + "
\n", + "
Title
HeatMap Element
\n", + "
Dependencies
Bokeh
\n", + "
Backends
[Bokeh](./HeatMap.ipynb)
[Matplotlib](../matplotlib/HeatMap.ipynb)
\n", + "
\n", + "
" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "import numpy as np\n", + "import holoviews as hv\n", + "hv.notebook_extension('bokeh')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "``HeatMap`` visualises tabular data indexed by two key dimensions as a grid of colored values. This allows spotting correlations in multivariate data and provides a high-level overview of how the two variables are plotted.\n", + "\n", + "The data for a ``HeatMap`` may be supplied as 2D tabular data with one or more associated value dimensions. The first value dimension will be colormapped, but further value dimensions may be revealed using the hover tool." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "data = [(chr(65+i), chr(97+j), i*j) for i in range(5) for j in range(5) if i!=j]\n", + "hv.HeatMap(data).sort()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "It is important to note that the data should be aggregated before plotting as the ``HeatMap`` cannot display multiple values for one coordinate and will simply use the first value it finds for each combination of x- and y-coordinates." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "heatmap = hv.HeatMap([(0, 0, 1), (0, 0, 10), (1, 0, 2), (1, 1, 3)])\n", + "heatmap + heatmap.aggregate(function=np.max)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "As the above example shows before aggregating the second value for the (0, 0) is ignored unless we aggregate the data first.\n", + "\n", + "To reveal the values of a ``HeatMap`` we can either enable a ``colorbar`` or add a hover tool. The hover tools even allows displaying any number of additional value dimensions, providing additional information a static plot could not capture:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "%%opts HeatMap [tools=['hover'] colorbar=True width=325 toolbar='above']\n", + "hv.HeatMap((np.random.randint(0, 10, 100), np.random.randint(0, 10, 100),\n", + " np.random.randn(100), np.random.randn(100)), vdims=['z', 'z2']).redim.range(z=(-2, 2))" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python [conda env:science]", + "language": "python", + "name": "conda-env-science-py" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 2 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython2", + "version": "2.7.13" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/examples/elements/bokeh/Histogram.ipynb b/examples/elements/bokeh/Histogram.ipynb new file mode 100644 index 0000000000..ed31ed3c75 --- /dev/null +++ b/examples/elements/bokeh/Histogram.ipynb @@ -0,0 +1,119 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
\n", + "
\n", + "
Title
Histogram Element
\n", + "
Dependencies
Bokeh
\n", + "
Backends
[Bokeh](./Histogram.ipynb)
[Matplotlib](../matplotlib/Histogram.ipynb)
\n", + "
\n", + "
" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "import numpy as np\n", + "import holoviews as hv\n", + "hv.notebook_extension('bokeh')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "``Histogram``s partition the `x` axis into discrete (but not necessarily regular) bins, showing counts in each as a bar. A ``Histogram`` accepts the output of ``np.histogram`` as input, which consists of a tuple of the histogram values with a shape of ``N`` and bin edges with a shape of ``N+1``. As a simple example we will generate a histogram of a normal distribution with 20 bins." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "np.random.seed(1)\n", + "data = np.random.randn(10000)\n", + "frequencies, edges = np.histogram(data, 20)\n", + "print('Values: %s, Edges: %s' % (frequencies.shape[0], edges.shape[0]))\n", + "hv.Histogram(frequencies, edges)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The ``Histogram`` Element will also expand evenly sampled bin centers, therefore we can easily cast between a linearly sampled Curve or Scatter and a Histogram." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "xs = np.linspace(0, np.pi*2)\n", + "ys = np.sin(xs)\n", + "curve = hv.Curve((xs, ys))\n", + "curve + hv.Histogram(curve)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The ``.hist`` method is an easy way to compute a histogram from an existing Element. The method effectively just calls the ``histogram`` operation, which lets you compute a histogram from an Element, and then adjoins the resulting histogram. Here we will create two sets of ``Points``, compute a ``Histogram`` for the 'x' and 'y' dimension on each, which we then overlay and adjoin to the plot." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "%%opts Histogram (alpha=0.3)\n", + "from holoviews.operation import histogram\n", + "points1 = hv.Points(np.random.randn(100,2)*2+1)\n", + "points2 = hv.Points(np.random.randn(100,2))\n", + "xhist, yhist = (histogram(points1, bin_range=(-5, 5), dimension=dim) *\n", + " histogram(points2, bin_range=(-5, 5), dimension=dim) \n", + " for dim in 'xy')\n", + "(points1 * points2) << yhist(plot=dict(width=125)) << xhist(plot=dict(height=125))" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 2", + "language": "python", + "name": "python2" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 2 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython2", + "version": "2.7.13" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/examples/elements/bokeh/Image.ipynb b/examples/elements/bokeh/Image.ipynb new file mode 100644 index 0000000000..f4cfb24296 --- /dev/null +++ b/examples/elements/bokeh/Image.ipynb @@ -0,0 +1,131 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
\n", + "
\n", + "
Title
Image Element
\n", + "
Dependencies
Bokeh
\n", + "
Backends
[Bokeh](./Image.ipynb)
[Matplotlib](../matplotlib/Image.ipynb)
\n", + "
\n", + "
" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "import numpy as np\n", + "import holoviews as hv\n", + "hv.notebook_extension('bokeh')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Like ``Raster``, a HoloViews ``Image`` allows you to view 2D arrays using an arbitrary color map. Unlike ``Raster``, an ``Image`` is associated with a [2D coordinate system in continuous space](Continuous_Coordinates.ipynb), which is appropriate for values sampled from some underlying continuous distribution (as in a photograph or other measurements from locations in real space)." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "ls = np.linspace(0, 10, 200)\n", + "xx, yy = np.meshgrid(ls, ls)\n", + "\n", + "bounds=(-1,-1,1,1) # Coordinate system: (left, bottom, top, right)\n", + "img = hv.Image(np.sin(xx)*np.cos(yy), bounds=bounds)\n", + "img" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Slicing, sampling, etc. on an ``Image`` all operate in this continuous space, whereas the corresponding operations on a ``Raster`` work on the raw array coordinates." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "img + img[-0.5:0.5, -0.5:0.5]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Notice how, because our declared coordinate system is continuous, we can slice with any floating-point value we choose. The appropriate range of the samples in the input numpy array will always be displayed, whether or not there are samples at those specific floating-point values. This also allows us to index by a floating value, since the ``Image`` is defined as a continuous space it will snap to the closest coordinate, to inspect the closest coordinate we can use the ``closest`` method:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "%%opts Points (color='black' marker='x' size=20)\n", + "closest = img.closest((0.1,0.1))\n", + "print('The value at position %s is %s' % (closest, img[0.1, 0.1]))\n", + "img * hv.Points([img.closest((0.1,0.1))])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We can also easily take cross-sections of the Image by using the sample method or collapse a dimension using the ``reduce`` method:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "img.sample(x=0) + img.reduce(x=np.mean)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python [conda env:science]", + "language": "python", + "name": "conda-env-science-py" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 2 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython2", + "version": "2.7.13" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/examples/elements/bokeh/ItemTable.ipynb b/examples/elements/bokeh/ItemTable.ipynb new file mode 100644 index 0000000000..473fe47233 --- /dev/null +++ b/examples/elements/bokeh/ItemTable.ipynb @@ -0,0 +1,70 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
\n", + "
\n", + "
Title
ItemTable Element
\n", + "
Dependencies
Bokeh
\n", + "
Backends
[Bokeh](./ItemTable.ipynb)
[Matplotlib](../matplotlib/ItemTable.ipynb)
\n", + "
\n", + "
" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "import numpy as np\n", + "import holoviews as hv\n", + "hv.notebook_extension('bokeh')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "An ``ItemTable`` is an ordered collection of key, value pairs. It can be used to directly visualize items in a tabular format where the items may be supplied as an ``OrderedDict`` or a list of (key,value) pairs. A standard Python dictionary can be easily visualized using a call to the ``.items()`` method, though the entries in such a dictionary are not kept in any particular order, and so you may wish to sort them before display. One typical usage for an ``ItemTable`` is to list parameter values or measurements associated with an adjacent ``Element``." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "%%opts ItemTable [height=60]\n", + "hv.ItemTable([('Age', 10), ('Weight',15), ('Height','0.8 meters')])" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python [conda env:science]", + "language": "python", + "name": "conda-env-science-py" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 2 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython2", + "version": "2.7.13" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/examples/elements/bokeh/Path.ipynb b/examples/elements/bokeh/Path.ipynb new file mode 100644 index 0000000000..9b3d048a05 --- /dev/null +++ b/examples/elements/bokeh/Path.ipynb @@ -0,0 +1,125 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
\n", + "
\n", + "
Title
Path Element
\n", + "
Dependencies
Bokeh
\n", + "
Backends
[Bokeh](./Path.ipynb)
[Matplotlib](../matplotlib/Path.ipynb)
\n", + "
\n", + "
" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "import numpy as np\n", + "import holoviews as hv\n", + "hv.notebook_extension('bokeh')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "A ``Path`` object is actually a collection of lines, which are all plotted with the same style. Unlike ``Curve`` where the y-axis is the dependent variable, a ``Path`` consists of lines connecting arbitrary points in two-dimensional space as is not expected to be a function.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "%%opts Path (color='black' line_width=4)\n", + "lin = np.linspace(-np.pi,np.pi,300)\n", + "\n", + "def lissajous(t, a,b, delta):\n", + " return (np.sin(a * t + delta), np.sin(b * t))\n", + "\n", + "hv.Path(lissajous(np.linspace(-np.pi, np.pi, 1000),3,5,np.pi/2))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Unlike ``Curve`` as single ``Path`` element can contain multiple lines that are disconnected from each other which will all be plotted in the same style. Only by overlaying multiple ``Path`` objects do you iterate through the defined color cycle (or any other style options that have been defined). A ``Path`` is often useful to draw arbitrary annotations on top of an existing plot.\n", + "\n", + "A ``Path`` Element accepts multiple formats for specifying the paths, the simplest of which is passing a list of ``Nx2`` arrays of the x- and y-coordinates, alternative we can pass lists of coordinates. In this example we will create some coordinates representing rectangles and ellipses annotating an ``RGB`` image:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "%%opts Path (line_width=4)\n", + "angle = np.linspace(0, 2*np.pi, 100)\n", + "baby = list(zip(0.15*np.sin(angle), 0.2*np.cos(angle)-0.2))\n", + "\n", + "adultR = [(0.25, 0.45), (0.35,0.35), (0.25, 0.25), (0.15, 0.35), (0.25, 0.45)]\n", + "adultL = [(-0.3, 0.4), (-0.3, 0.3), (-0.2, 0.3), (-0.2, 0.4),(-0.3, 0.4)]\n", + "scene = hv.RGB.load_image('../../../doc/assets/penguins.png')\n", + "\n", + "scene * hv.Path([adultL, adultR, baby]) * hv.Path([baby])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "A ``Path`` can also be used as a means to display a number of lines with the same sampling along the x-axis at once. If we initialize the ``Path`` with a tuple of x-coordinates and stacked y-coordinates, we can quickly view a number of lines at once. Here we will generate a number of random traces each slightly offset along the y-axis:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "%%opts Path [width=600]\n", + "N, NLINES = 100, 10\n", + "hv.Path((np.arange(N), np.random.rand(N, NLINES) + np.arange(NLINES)[np.newaxis, :])) *\\\n", + "hv.Path((np.arange(N), np.random.rand(N, NLINES) + np.arange(NLINES)[np.newaxis, :]))" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 2", + "language": "python", + "name": "python2" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 2 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython2", + "version": "2.7.13" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/examples/elements/bokeh/Points.ipynb b/examples/elements/bokeh/Points.ipynb new file mode 100644 index 0000000000..0ae7c19dbd --- /dev/null +++ b/examples/elements/bokeh/Points.ipynb @@ -0,0 +1,133 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
\n", + "
\n", + "
Title
Points Element
\n", + "
Dependencies
Bokeh
\n", + "
Backends
[Bokeh](./Points.ipynb)
[Matplotlib](../matplotlib/Points.ipynb)
\n", + "
\n", + "
" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "import numpy as np\n", + "import holoviews as hv\n", + "hv.notebook_extension('bokeh')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The ``Points`` element visualizes as markers placed in a space of two independent variables, traditionally denoted *x* and *y*. In HoloViews, the names ``'x'`` and ``'y'`` are used as the default ``key_dimensions`` of the element. We can see this from the default axis labels when visualizing a simple ``Points`` element:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "%%opts Points (color='k' marker='+' size=10)\n", + "np.random.seed(12)\n", + "coords = np.random.rand(50,2)\n", + "hv.Points(coords)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Here both the random *x* values and random *y* values are *both* considered to be the 'data' with no dependency between them (compare this to how [``Scatter``](./Scatter.ipynb) elements are defined). You can think of ``Points`` as simply marking positions in some two-dimensional space that can be sliced by specifying a 2D region-of-interest:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "%%opts Points (color='k' marker='+' size=10)\n", + "hv.Points(coords) + hv.Points(coords)[0.6:0.8,0.2:0.5]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Although the simplest ``Points`` element simply mark positions in a two-dimensional space without any associated value this doesn't mean value dimensions aren't supported. Here is an example with two additional quantities for each point, declared as the ``value_dimension``s *z* and α visualized as the color and size of the dots, respectively:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "%%opts Points [color_index=2 size_index=3 scaling_factor=50]\n", + "np.random.seed(10)\n", + "data = np.random.rand(100,4)\n", + "\n", + "points = hv.Points(data, vdims=['z', 'size'])\n", + "points + points[0.3:0.7, 0.3:0.7].hist()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "In the right subplot, the ``hist`` method is used to show the distribution of samples along the first value dimension we added (*z*).\n", + "\n", + "\n", + "The marker shape specified above can be any supported by [matplotlib](http://matplotlib.org/api/markers_api.html), e.g. ``s``, ``d``, or ``o``; the other options select the color and size of the marker. For convenience with the [bokeh backend](Bokeh_Backend), the matplotlib marker options are supported using a compatibility function in HoloViews." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Note**: Although the ``Scatter`` element is superficially similar to the [``Points``](./Points.ipynb) element (they can generate plots that look identical), the two element types are semantically quite different. The fundamental difference is that [``Points``](./Points.ipynb) are used to visualize data where the *y* variable is *dependent*. This semantic difference also explains why the histogram generated by ``hist`` call above visualizes the distribution of a different dimension than it does for [``Scatter``](./Scatter.ipynb).\n", + "\n", + "This difference means that ``Points`` naturally combine elements that express independent variables in two-dimensional space, for instance [``Raster``](./Raster.ipynb) types such as [``Image``](./Image.ipynb). Similarly, ``Scatter`` expresses a dependent relationship in two-dimensions and combine naturally with ``Chart`` types such as [``Curve``](./Curve.ipynb)." + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python [conda env:science]", + "language": "python", + "name": "conda-env-science-py" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 2 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython2", + "version": "2.7.13" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/examples/elements/bokeh/Polygons.ipynb b/examples/elements/bokeh/Polygons.ipynb new file mode 100644 index 0000000000..fbc9833e2f --- /dev/null +++ b/examples/elements/bokeh/Polygons.ipynb @@ -0,0 +1,99 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
\n", + "
\n", + "
Title
Polygons Element
\n", + "
Dependencies
Bokeh
\n", + "
Backends
[Bokeh](./Polygons.ipynb)
[Matplotlib](../matplotlib/Polygons.ipynb)
\n", + "
\n", + "
" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "import numpy as np\n", + "import holoviews as hv\n", + "hv.notebook_extension('bokeh')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "A ``Polygons`` object is similar to a ``Contours`` object except that each supplied path is closed and filled. Just like ``Contours``, an optional ``level`` value may be supplied; the Polygons will then be colored according to the supplied ``cmap``. Non-finite values such as ``np.NaN`` or ``np.inf`` will default to the supplied ``facecolor``.\n", + "\n", + "Polygons with values can be used to build heatmaps with arbitrary shapes." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "%%opts Polygons (cmap='hot' line_color='black' line_width=2)\n", + "np.random.seed(35)\n", + "hv.Polygons([np.random.rand(4,2)], level=0.5) *\\\n", + "hv.Polygons([np.random.rand(4,2)], level=1.0) *\\\n", + "hv.Polygons([np.random.rand(4,2)], level=1.5) *\\\n", + "hv.Polygons([np.random.rand(4,2)], level=2.0)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "``Polygons`` without a value are useful as annotation, but also allow us to draw arbitrary shapes." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "def rectangle(x=0, y=0, width=1, height=1):\n", + " return np.array([(x,y), (x+width, y), (x+width, y+height), (x, y+height)])\n", + "\n", + "(hv.Polygons([rectangle(width=2), rectangle(x=6, width=2)])(style={'fill_color': '#a50d0d'})\n", + "* hv.Polygons([rectangle(x=2, height=2), rectangle(x=5, height=2)])(style={'fill_color': '#ffcc00'})\n", + "* hv.Polygons([rectangle(x=3, height=2, width=2)])(style={'fill_color': 'cyan'}))" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python [conda env:science]", + "language": "python", + "name": "conda-env-science-py" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 2 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython2", + "version": "2.7.13" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/examples/elements/bokeh/QuadMesh.ipynb b/examples/elements/bokeh/QuadMesh.ipynb new file mode 100644 index 0000000000..78b5a7dc86 --- /dev/null +++ b/examples/elements/bokeh/QuadMesh.ipynb @@ -0,0 +1,140 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
\n", + "
\n", + "
Title
QuadMesh Element
\n", + "
Dependencies
Bokeh
\n", + "
Backends
[Bokeh](./QuadMesh.ipynb)
[Matplotlib](../matplotlib/QuadMesh.ipynb)
\n", + "
\n", + "
" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "import numpy as np\n", + "import holoviews as hv\n", + "hv.notebook_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": { + "collapsed": false + }, + "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": { + "collapsed": false + }, + "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": { + "collapsed": false + }, + "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": { + "collapsed": false + }, + "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." + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 2", + "language": "python", + "name": "python2" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 2 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython2", + "version": "2.7.13" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/examples/elements/bokeh/RGB.ipynb b/examples/elements/bokeh/RGB.ipynb new file mode 100644 index 0000000000..1c784e0130 --- /dev/null +++ b/examples/elements/bokeh/RGB.ipynb @@ -0,0 +1,136 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
\n", + "
\n", + "
Title
RGB Element
\n", + "
Dependencies
Bokeh
\n", + "
Backends
[Bokeh](./RGB.ipynb)
[Matplotlib](../matplotlib/RGB.ipynb)
\n", + "
\n", + "
" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "import numpy as np\n", + "import holoviews as hv\n", + "hv.notebook_extension('bokeh')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The ``RGB`` element is a subclass of [``Image``](./Image.ipynb) that supports red, green, blue channels. One of the simplest ways of creating an ``RGB`` element is to load an image file (such as PNG) off disk, using the ``load_image`` classmethod:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "hv.RGB.load_image('../../../doc/assets/penguins.png')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Although convenient, this method doesn't show how an ``RGB`` is constructed from arrays. The next example shows that the input can be a simple stack of two-dimensional numpy arrays:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "x,y = np.mgrid[-50:51, -50:51] * 0.1\n", + "\n", + "r = 0.5*np.sin(np.pi +3*x**2+y**2)+0.5\n", + "g = 0.5*np.sin(x**2+2*y**2)+0.5\n", + "b = 0.5*np.sin(np.pi/2+x**2+y**2)+0.5\n", + "\n", + "hv.RGB(np.dstack([r,g,b]))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "You can see how the RGB object is created from the original channels:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "%%opts Image (cmap='gray')\n", + "hv.Image(r,label=\"R\") + hv.Image(g,label=\"G\") + hv.Image(b,label=\"B\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "``RGB`` also supports an optional alpha channel, which will be used as a mask revealing or hiding any ``Element``s it is overlaid on top of:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "%%opts Image (cmap='gray')\n", + "mask = 0.5*np.sin(0.2*(x**2+y**2))+0.5\n", + "rgba = hv.RGB(np.dstack([r,g,b,mask]))\n", + "\n", + "bg = hv.Image(0.5*np.cos(x*3)+0.5, label=\"Background\") * hv.VLine(x=0,label=\"Background\")\n", + "overlay = (bg*rgba).relabel(\"RGBA Overlay\")\n", + "bg + hv.Image(mask,label=\"Mask\") + overlay" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python [conda env:science]", + "language": "python", + "name": "conda-env-science-py" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 2 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython2", + "version": "2.7.13" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/examples/elements/bokeh/Raster.ipynb b/examples/elements/bokeh/Raster.ipynb new file mode 100644 index 0000000000..446f83fa30 --- /dev/null +++ b/examples/elements/bokeh/Raster.ipynb @@ -0,0 +1,78 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
\n", + "
\n", + "
Title
Raster Element
\n", + "
Dependencies
Bokeh
\n", + "
Backends
[Bokeh](./Raster.ipynb)
[Matplotlib](../matplotlib/Raster.ipynb)
\n", + "
\n", + "
" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "import numpy as np\n", + "import holoviews as hv\n", + "hv.notebook_extension('bokeh')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "A ``Raster`` is the base class for image-like elements (namely [``Image``](./Image.ipynb), [``RGB``](./RGB.ipynb) and [``HSV``](./HSV.ipynb)), but may be used directly to visualize 2D arrays using a color map:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "xvals = np.linspace(0,4,202)\n", + "ys,xs = np.meshgrid(xvals, -xvals[::-1])\n", + "hv.Raster(np.sin(((ys)**3)*xs))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The coordinate system of a ``Raster`` is the raw indexes of the underlying array, with integer values always starting from (0,0) in the top left, with default extents corresponding to the shape of the array. For a similar element used to visualize arrays but defined in a continuous Cartesian coordinate system, use the [``Image``](./Image.ipynb) element." + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 2", + "language": "python", + "name": "python2" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 2 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython2", + "version": "2.7.13" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/examples/elements/bokeh/Scatter.ipynb b/examples/elements/bokeh/Scatter.ipynb new file mode 100644 index 0000000000..cd7856e3e6 --- /dev/null +++ b/examples/elements/bokeh/Scatter.ipynb @@ -0,0 +1,137 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
\n", + "
\n", + "
Title
Scatter Element
\n", + "
Dependencies
Bokeh
\n", + "
Backends
[Bokeh](./Scatter.ipynb)
[Matplotlib](../matplotlib/Scatter.ipynb)
\n", + "
\n", + "
" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "import numpy as np\n", + "import holoviews as hv\n", + "hv.notebook_extension('bokeh')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The ``Scatter`` element visualizes as markers placed in a space of one independent variable, traditionally denoted as *x*, against a dependent variable, traditonally denoted as *y*. In HoloViews, the name ``'x'`` is the default dimension name used in the ``key_dimensions`` and ``'y'`` is the default dimension name used in the ``value_dimensions``. We can see this from the default axis labels when visualizing a simple ``Scatter`` element:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "%%opts Scatter (color='k' marker='s' size=10)\n", + "np.random.seed(42)\n", + "coords = [(i, np.random.random()) for i in range(20)]\n", + "hv.Scatter(coords)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Here the random *y* values are considered to be the 'data' whereas the x positions express where those values are located (compare this to how [``Points``](./Points.ipynb) elements are defined). In this sense, ``Scatter`` can be thought of as a [``Curve``](./Curve.ipynb) without any lines connecting the samples and you can use slicing to view the *y* values corresponding to a chosen *x* range:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "%%opts Scatter (color='k' marker='s' size=10)\n", + "hv.Scatter(coords)[0:12] + hv.Scatter(coords)[12:20]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "A ``Scatter`` element must always have at least one value dimension but that doesn't mean additional value dimensions aren't supported. Here is an example with two additional quantities for each point, declared as the ``value_dimension``s *z* and α visualized as the color and size of the dots, respectively:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "%%opts Scatter [color_index=2 size_index=3 scaling_factor=50]\n", + "np.random.seed(10)\n", + "data = np.random.rand(100,4)\n", + "\n", + "scatter = hv.Scatter(data, vdims=['y', 'z', 'size'])\n", + "scatter + scatter[0.3:0.7, 0.3:0.7].hist()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "In the right subplot, the ``hist`` method is used to show the distribution of samples along our first value dimension, (*y*)." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The marker shape specified above can be any supported by [matplotlib](http://matplotlib.org/api/markers_api.html), e.g. ``s``, ``d``, or ``o``; the other options select the color and size of the marker. For convenience with the [bokeh backend](Bokeh_Backend), the matplotlib marker options are supported using a compatibility function in HoloViews." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Note**: Although the ``Scatter`` element is superficially similar to the [``Points``](./Points.ipynb) element (they can generate plots that look identical), the two element types are semantically quite different: ``Points`` are used to visualize data where the *y* variable is *dependent*. This semantic difference also explains why the histogram generated by ``hist`` call above visualizes the distribution of a different dimension than it does for [``Points``](./Points.ipynb).\n", + "\n", + "This difference means that ``Scatter`` naturally combine elements that express dependent variables in two-dimensional space such as the ``Chart`` types, such as [``Curve``](./Curve.ipynb). Similarly, ``Points`` express a independent relationship in two-dimensions and combine naturally with [``Raster``](./Raster.ipynb) types such as [``Image``](./Image.ipynb)." + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python [conda env:science]", + "language": "python", + "name": "conda-env-science-py" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 2 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython2", + "version": "2.7.13" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/examples/elements/bokeh/Spikes.ipynb b/examples/elements/bokeh/Spikes.ipynb new file mode 100644 index 0000000000..9148325687 --- /dev/null +++ b/examples/elements/bokeh/Spikes.ipynb @@ -0,0 +1,152 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
\n", + "
\n", + "
Title
Spikes Element
\n", + "
Dependencies
Bokeh
\n", + "
Backends
[Bokeh](./Spikes.ipynb)
[Matplotlib](../matplotlib/Spikes.ipynb)
\n", + "
\n", + "
" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "import numpy as np\n", + "import holoviews as hv\n", + "hv.notebook_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:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "%%opts Spikes (line_alpha=0.4) [spike_length=0.1]\n", + "xs = np.random.rand(50)\n", + "hv.Spikes(xs)" + ] + }, + { + "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": { + "collapsed": false + }, + "outputs": [], + "source": [ + "%%opts Points (color='red')\n", + "ys = np.random.rand(50)\n", + "hv.Points((xs, ys)) * hv.Spikes(xs)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "When supplying a second dimension to the ``Spikes`` element as a value dimensions, these additional values will be mapped onto the line height. Optionally, you may also supply a colormap ``cmap`` and ``color_index`` to map the value dimensions to a suitable set of colors. This way we can, for example, plot a [mass spectrogram](https://en.wikipedia.org/wiki/Mass_spectrometry):" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "%%opts Spikes (cmap='Reds')\n", + "hv.Spikes(np.random.rand(20, 2), kdims=['Mass'], vdims=['Intensity'])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Another possibility is to draw a number of spike trains representing the firing of neurons, of the sort that are commonly encountered in neuroscience. 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": { + "collapsed": false + }, + "outputs": [], + "source": [ + "%%opts Spikes [spike_length=0.1] NdOverlay [show_legend=False]\n", + "hv.NdOverlay({i: hv.Spikes(np.random.randint(0, 100, 10), kdims=['Time'])(plot=dict(position=0.1*i))\n", + " for i in range(10)})(plot=dict(yticks=[((i+1)*0.1-0.05, i) for i in range(10)]))" + ] + }, + { + "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": { + "collapsed": false + }, + "outputs": [], + "source": [ + "%%opts Spikes (line_alpha=0.2)\n", + "points = hv.Points(np.random.randn(500, 2))\n", + "points << hv.Spikes(points['y']) << hv.Spikes(points['x'])" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python [conda env:science]", + "language": "python", + "name": "conda-env-science-py" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 2 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython2", + "version": "2.7.13" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/examples/elements/bokeh/Spline.ipynb b/examples/elements/bokeh/Spline.ipynb new file mode 100644 index 0000000000..6edcffb70c --- /dev/null +++ b/examples/elements/bokeh/Spline.ipynb @@ -0,0 +1,78 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
\n", + "
\n", + "
Title
Spline Element
\n", + "
Dependencies
Bokeh
\n", + "
Backends
[Bokeh](./Spline.ipynb)
[Matplotlib](../matplotlib/Spline.ipynb)
\n", + "
\n", + "
" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "import numpy as np\n", + "import holoviews as hv\n", + "hv.notebook_extension('bokeh')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The ``Spline`` annotation is used to draw cubic Bezier curves. In the overlay below, the spline is in green and the control points are shown by the light grey line:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "%%opts Curve (color='#D3D3D3') Spline (line_width=6 color='green')\n", + "points = [(-0.3, -0.3), (0,0), (0.25, -0.25), (0.3, 0.3)]\n", + "hv.Spline((points,[])) * hv.Curve(points)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Note that the Bokeh ``Spline`` does not support the same control codes as the [matplotlib version](../matplotlib/Spline.ipynb) which is why the codes are supplied above as an empty list." + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 2", + "language": "python", + "name": "python2" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 2 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython2", + "version": "2.7.13" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/examples/elements/bokeh/Spread.ipynb b/examples/elements/bokeh/Spread.ipynb new file mode 100644 index 0000000000..d4067ea86d --- /dev/null +++ b/examples/elements/bokeh/Spread.ipynb @@ -0,0 +1,112 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
\n", + "
\n", + "
Title
Spread Element
\n", + "
Dependencies
Bokeh
\n", + "
Backends
[Bokeh](./Spread.ipynb)
[Matplotlib](../matplotlib/Spread.ipynb)
\n", + "
\n", + "
" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "import numpy as np\n", + "import holoviews as hv\n", + "hv.notebook_extension('bokeh')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "``Spread`` elements have the same data format as the [``ErrorBars``](ErrorBars.ipynb) element, namely x- and y-values with associated symmetric or assymetric errors, but are interpreted as samples from a continuous distribution (just as ``Curve`` is the continuous version of ``Scatter``). These are often paired with an overlaid ``Curve`` to show an average trend along with a corresponding spread of values; see the [Columnar Data tutorial](Columnar_Data.ipynb) for examples. \n", + "\n", + "Note that as the ``Spread`` element is used to add information to a plot (typically a ``Curve``) the default alpha value is less that one, making it partially transparent. \n", + "\n", + "\n", + "##### Symmetric" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Given two value dimensions corresponding to the position on the y-axis and the error, ``Spread`` will visualize itself assuming symmetric errors:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "np.random.seed(42)\n", + "xs = np.linspace(0, np.pi*2, 20)\n", + "err = 0.2+np.random.rand(len(xs))\n", + "hv.Spread((xs, np.sin(xs), err))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "##### Asymmetric" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Given three value dimensions corresponding to the position on the y-axis, the negative error and the positive error, ``Spread`` can be used to visualize assymmetric errors:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "%%opts Spread (fill_color='indianred' fill_alpha=1)\n", + "xs = np.linspace(0, np.pi*2, 20)\n", + "hv.Spread((xs, np.sin(xs), 0.1+np.random.rand(len(xs)), 0.1+np.random.rand(len(xs))),\n", + " vdims=['y', 'yerrneg', 'yerrpos'])" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 2", + "language": "python", + "name": "python2" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 2 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython2", + "version": "2.7.13" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/examples/elements/bokeh/Table.ipynb b/examples/elements/bokeh/Table.ipynb new file mode 100644 index 0000000000..ae0ea6b0ce --- /dev/null +++ b/examples/elements/bokeh/Table.ipynb @@ -0,0 +1,155 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
\n", + "
\n", + "
Title
Table Element
\n", + "
Dependencies
Bokeh
\n", + "
Backends
[Bokeh](./Table.ipynb)
[Matplotlib](../matplotlib/Table.ipynb)
\n", + "
\n", + "
" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "import numpy as np\n", + "import holoviews as hv\n", + "hv.notebook_extension('bokeh')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "A table is more general than an [``ItemTable``](./ItemTable.ioynb), as it allows multi-dimensional keys and multidimensional values. Let's say we have the following data:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "gender = ['M','M', 'M','F']\n", + "age = [10,16,13,12]\n", + "weight = [15,18,16,10]\n", + "height = [0.8,0.6,0.7,0.8]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We can construct a ``Table`` using a dictionary format (identical in format as that accepted by the [pandas](http://pandas.pydata.org/) ``DataFrame``):" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "%%opts Table [height=140]\n", + "hv.Table({'Gender':gender, 'Age':age, 'Weight':weight, 'Height':height},\n", + " kdims = ['Gender', 'Age'], vdims=['Weight', 'Height'])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Or we can declare the same table by dimension position, with key dimensions followed by value dimensions:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "%%opts Table [height=140]\n", + "table = hv.Table((gender, age, weight, height), kdims = ['Gender', 'Age'], vdims=['Weight', 'Height'])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Note that you can use the ``select`` method using tables by the key dimensions:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "%%opts Table [height=100]\n", + "table.select(Gender='M') + table.select(Gender='M', Age=10)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The ``Table`` is used as a common data structure that may be converted to any other HoloViews data structure via the ``to`` utility available on the object. Here we use this utility to show the weight of the males in our datset by age:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "table.select(Gender='M').to.curve(kdims=[\"Age\"], vdims=[\"Weight\"])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "For more extended usage of table conversion see the [Columnar Data](Columnnar_Data.ipynb) and [Pandas Conversion](Pandas_Conversion.ipynb) Tutorials." + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 2", + "language": "python", + "name": "python2" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 2 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython2", + "version": "2.7.13" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/examples/elements/bokeh/Text.ipynb b/examples/elements/bokeh/Text.ipynb new file mode 100644 index 0000000000..44eacf32b3 --- /dev/null +++ b/examples/elements/bokeh/Text.ipynb @@ -0,0 +1,71 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
\n", + "
\n", + "
Title
Text Element
\n", + "
Dependencies
Bokeh
\n", + "
Backends
[Bokeh](./Text.ipynb)
[Matplotlib](../matplotlib/Text.ipynb)
\n", + "
\n", + "
" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "import numpy as np\n", + "import holoviews as hv\n", + "hv.notebook_extension('bokeh')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The ``Text`` annotation is used to overlay text at a particular position on a plot:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "%%opts Curve (color='#D3D3D3')\n", + "xs = np.linspace(-5,5,100)\n", + "hv.Curve((xs,-(xs-2)**2)) * hv.Text(0, -30, 'Quadratic Curve')" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 2", + "language": "python", + "name": "python2" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 2 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython2", + "version": "2.7.13" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/examples/elements/bokeh/VLine.ipynb b/examples/elements/bokeh/VLine.ipynb new file mode 100644 index 0000000000..1e4cd8acbf --- /dev/null +++ b/examples/elements/bokeh/VLine.ipynb @@ -0,0 +1,72 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
\n", + "
\n", + "
Title
VLine Element
\n", + "
Dependencies
Bokeh
\n", + "
Backends
[Bokeh](./VLine.ipynb)
[Matplotlib](../matplotlib/VLine.ipynb)
\n", + "
\n", + "
" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "import numpy as np\n", + "import holoviews as hv\n", + "hv.notebook_extension('bokeh')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The ``VLine`` element is a type of annotation that marks a position along the x-axis. Here is a ``VLine`` marking the maximum of a quadratic curve:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "%%opts VLine (color='red' line_width=6) Curve (color='#D3D3D3')\n", + "xs = np.linspace(-5,5,100)\n", + "ys = -(xs-2)**2\n", + "hv.Curve((xs,ys)) * hv.VLine(xs[ys.argmax()])" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 2", + "language": "python", + "name": "python2" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 2 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython2", + "version": "2.7.13" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/examples/elements/bokeh/VectorField.ipynb b/examples/elements/bokeh/VectorField.ipynb new file mode 100644 index 0000000000..b5ea5ac404 --- /dev/null +++ b/examples/elements/bokeh/VectorField.ipynb @@ -0,0 +1,160 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
\n", + "
\n", + "
Title
VectorField Element
\n", + "
Dependencies
Bokeh
\n", + "
Backends
[Bokeh](./VectorField.ipynb)
[Matplotlib](../matplotlib/VectorField.ipynb)
\n", + "
\n", + "
" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "import numpy as np\n", + "import holoviews as hv\n", + "hv.notebook_extension('bokeh')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "A ``VectorField`` plot displays velocity vectors as arrows at ``x`` and ``y`` positions with angle and magnitude components (or alternatively ``U``, ``V`` components). The element accepts the usual columnar format passing the ``(x, y, angles, magnitudes)`` components as a tuple, but also handles 2D arrays when supplied as a list instead:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "%%opts VectorField [size_index=3]\n", + "x,y = np.mgrid[-10:10,-10:10] * 0.25\n", + "sine_rings = np.sin(x**2+y**2)*np.pi+np.pi\n", + "exp_falloff = 1/np.exp((x**2+y**2)/8)\n", + "\n", + "vector_data = [x,y,sine_rings, exp_falloff]\n", + "hv.VectorField(vector_data)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "As you can see above, here the *x* and *y* positions are chosen to make a regular grid. The arrow angles follow a sinsoidal ring pattern, and the arrow lengths fall off exponentially from the center, so this plot has four dimensions of data (direction and length for each *x,y* position).\n", + "\n", + "Using the ``%%opts`` cell-magic, we can also use color as a redundant indicator to the direction or magnitude:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "%%opts VectorField [size_index=3] VectorField.A [color_index=2] VectorField.M [color_index=3]\n", + "hv.VectorField(vector_data, group='A') + hv.VectorField(vector_data, group='M')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "By default the arrows are rescaled to the minimum distance between individual arrows, to disable this rescaling set ``rescale=False`` and adjust the ``scale`` manually (smaller values result in larger arrows). This allows fixed scaling even when plotting arrows in an animation. Here we will vary the arrow angle with a Phase dimension and also add this angle to the magnitude data, showing the arrow angles and magnitudes varying. Due to the fixed scaling we can make out the differences across frames:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "%%opts VectorField [color_index=2 size_index=3 rescale_lengths=False] (scale=4)\n", + "hv.HoloMap({phase: hv.VectorField([x, y,(vector_data[2]+phase)%np.pi*2, vector_data[3]+np.abs(phase)])\n", + " for phase in np.linspace(-np.pi,np.pi,5)}, kdims=['Phase'])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Vectors are also often expressed through U and V components we can easily transform these to a magnitude and angle:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "xs, ys = np.arange(0, 2 * np.pi, .2), np.arange(0, 2 * np.pi, .2)\n", + "X, Y = np.meshgrid(xs, ys)\n", + "U = np.cos(X)\n", + "V = np.sin(Y)\n", + "\n", + "# Convert U, V to magnitude and angle\n", + "mag = np.sqrt(U**2 + V**2)\n", + "angle = (np.pi/2.) - np.arctan2(U/mag, V/mag)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "``VectorField`` also allows defining the ``pivot`` point of the vectors. We can for instance define ``pivot='tip'`` to pivot around the tip of the arrow. To make this clearer we will mark the pivot points:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "%%opts VectorField [width=500 color_index=3 size_index=3 pivot='tip'] (cmap='fire' scale=0.8) Points (color='black' size=1)\n", + "hv.VectorField((xs, ys, angle, mag)) * hv.Points((X.flat, Y.flat))" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 2", + "language": "python", + "name": "python2" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 2 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython2", + "version": "2.7.13" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/examples/elements/matplotlib/Area.ipynb b/examples/elements/matplotlib/Area.ipynb new file mode 100644 index 0000000000..13e3329379 --- /dev/null +++ b/examples/elements/matplotlib/Area.ipynb @@ -0,0 +1,131 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
\n", + "
\n", + "
Title
Area Element
\n", + "
Dependencies
Matplotlib
\n", + "
Backends
[Matplotlib](./Area.ipynb)
[Bokeh](../bokeh/Area.ipynb)
\n", + "
\n", + "
" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "import numpy as np\n", + "import holoviews as hv\n", + "hv.notebook_extension()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "``Area`` elements are ``Curve`` elements where the area below the line is filled. Like ``Curve`` elements, ``Area`` elements are used to display the development of quantitative values over an interval or time period. ``Area`` Elements may also be stacked to display multiple data series in a cumulative fashion over the value dimension.\n", + "\n", + "The data of an ``Area`` Element should be tabular with one key dimension representing the samples over the interval or the timeseries and one or two value dimensions. A single value dimension will fill the area between the curve and the x-axis, while two value dimensions will fill the area between the curves. See the [Columnar Data Tutorial](../Tutorials/Columnar_Data.ipynb) for supported data formats, which include arrays, pandas dataframes and dictionaries of arrays." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Area under the curve\n", + "\n", + "By default the Area Element draws just the area under the curve, i.e. the region between the curve and the origin." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "xs = np.linspace(0, np.pi*4, 40)\n", + "hv.Area((xs, np.sin(xs)))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Area between curves\n", + "\n", + "When supplied a second value dimension the area is defined as the area between two curves." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "X = np.linspace(0,3,200)\n", + "Y = X**2 + 3\n", + "Y2 = np.exp(X) + 2\n", + "Y3 = np.cos(X)\n", + "hv.Area((X, Y, Y2), vdims=['y', 'y2']) * hv.Area((X, Y, Y3), vdims=['y', 'y3'])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Stacked areas \n", + "\n", + "Areas are also useful to visualize multiple variables changing over time, but in order to be able to compare them the areas need to be stacked. To do this, use the ``Area.stack`` classmethod to stack multiple ``Area`` elements in an (Nd)Overlay.\n", + "\n", + "In this example we will generate a set of 5 arrays representing percentages and create an ``Overlay`` of them. Then we simply call the ``stack`` method with this overlay to get a stacked area chart.\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "values = np.random.rand(5, 20)\n", + "percentages = (values/values.sum(axis=0)).T*100\n", + "\n", + "overlay = hv.Overlay([hv.Area(percentages[:, i], vdims=[hv.Dimension('value', unit='%')]) for i in range(5)])\n", + "overlay + hv.Area.stack(overlay)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 2", + "language": "python", + "name": "python2" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 2 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython2", + "version": "2.7.13" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/examples/elements/matplotlib/Arrow.ipynb b/examples/elements/matplotlib/Arrow.ipynb new file mode 100644 index 0000000000..e8e32bedea --- /dev/null +++ b/examples/elements/matplotlib/Arrow.ipynb @@ -0,0 +1,72 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
\n", + "
\n", + "
Title
Arrow
\n", + "
Dependencies
Matplotlib
\n", + "
Backends
[Matplotlib](./Arrow.ipynb)
\n", + "
\n", + "
" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "import numpy as np\n", + "import holoviews as hv\n", + "hv.notebook_extension()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The ``Arrow`` element is a type of annotation that points to a position on a visualization with optional text:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "%%opts Curve (color='#D3D3D3')\n", + "xs = np.linspace(-5,5,100)\n", + "ys = -(xs-2)**3\n", + "hv.Curve((xs,ys)) * hv.Arrow(0,-0.1, 'Inflection', 'v')" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 2", + "language": "python", + "name": "python2" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 2 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython2", + "version": "2.7.13" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/examples/elements/matplotlib/Bars.ipynb b/examples/elements/matplotlib/Bars.ipynb new file mode 100644 index 0000000000..5396276e4b --- /dev/null +++ b/examples/elements/matplotlib/Bars.ipynb @@ -0,0 +1,109 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
\n", + "
\n", + "
Title
Bars Element
\n", + "
Dependencies
Matplotlib
\n", + "
Backends
[Matplotlib](./Bars.ipynb)
[Bokeh](../bokeh/Bars.ipynb)
\n", + "
\n", + "
" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as np\n", + "import holoviews as hv\n", + "hv.notebook_extension('matplotlib')" + ] + }, + { + "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 stacked by supplying a second key dimensions representing sub-categories. Therefore the ``Bars`` Element expects a tabular data format with one or two key dimensions and one value dimension. See the [Columnar Data Tutorial](../Tutorials/Columnar_Data.ipynb) 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", + "bars = hv.Bars(data, kdims=[hv.Dimension('Car occupants')], vdims=['Count'])\n", + "bars" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "You can 'slice' a ``Bars`` element by selecting categories as follows:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "bars[['one', 'two', 'three']] + bars[['four', 'five', 'six']]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "``Bars`` support stacking just like the ``Area`` element as well as grouping by a second key dimension. To activate grouping and stacking set the ``group_index`` or ``stack_index`` to the dimension name or dimension index:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%%opts Bars.Grouped [category_index=0 group_index=1 stack_index=5] \n", + "%%opts Bars.Stacked [color_by=['stack'] stack_index=1 category_index=5]\n", + "from itertools import product\n", + "np.random.seed(3)\n", + "index, groups = ['A', 'B'], ['a', 'b']\n", + "keys = product(index, groups)\n", + "bars = hv.Bars([k+(np.random.rand()*100.,) for k in keys],\n", + " kdims=['Index', 'Group'], vdims=['Count'])\n", + "bars.relabel(group='Grouped') + bars.relabel(group='Stacked')" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python [conda env:science]", + "language": "python", + "name": "conda-env-science-py" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 2 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython2", + "version": "2.7.13" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/examples/elements/matplotlib/Bounds.ipynb b/examples/elements/matplotlib/Bounds.ipynb new file mode 100644 index 0000000000..d10616dc3d --- /dev/null +++ b/examples/elements/matplotlib/Bounds.ipynb @@ -0,0 +1,89 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
\n", + "
\n", + "
Title
Bounds Element
\n", + "
Dependencies
Matplotlib
\n", + "
Backends
[Matplotlib](./Bounds.ipynb)
[Bokeh](../bokeh/Bounds.ipynb)
\n", + "
\n", + "
" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "import numpy as np\n", + "import holoviews as hv\n", + "hv.notebook_extension()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "A ``Bounds`` element is an box shaped annotation that is specified as a tuple in (left, bottom, right, top) format:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "%%opts Bounds (color='orange' linewidth=6)\n", + "penguins = hv.RGB.load_image('../../../doc/assets/penguins.png')\n", + "penguins * hv.Bounds((-0.15, -0.4, 0.2, 0))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "It is useful for denoting a region of interest defined by some bounds (such as a slice) which is unlike the [``Box``](./Box.ipynb) element which is useful for drawing a box at a specific location. Here we show the a slice of the ``RGB`` element (green channel only) outlined by the bounds. Note that the values in the ``Bounds`` tuple are the same ones as used in the slice:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "penguins * penguins[-0.15:0.2, -0.4:0, 'G'] * hv.Bounds((-0.15, -0.4, 0.2, 0))" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 2", + "language": "python", + "name": "python2" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 2 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython2", + "version": "2.7.13" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/examples/elements/matplotlib/Box.ipynb b/examples/elements/matplotlib/Box.ipynb new file mode 100644 index 0000000000..05865e5344 --- /dev/null +++ b/examples/elements/matplotlib/Box.ipynb @@ -0,0 +1,91 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
\n", + "
\n", + "
Title
Box Element
\n", + "
Dependencies
Matplotlib
\n", + "
Backends
[Matplotlib](./Box.ipynb)
[Bokeh](../bokeh/Box.ipynb)
\n", + "
\n", + "
" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "import numpy as np\n", + "import holoviews as hv\n", + "hv.notebook_extension()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "A ``Box`` is an annotation that takes a center x-position, a center y-position and a width:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "%%opts Box (linewidth=5 color='purple') Image (cmap='gray')\n", + "data = np.sin(np.mgrid[0:100,0:100][1]/10.0)\n", + "data[range(30, 70), range(30, 70)] = -3\n", + "hv.Image(data) * hv.Box(-0, 0, 0.5 )" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "In addition to these arguments, it supports an optional ``aspect ratio``:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "%%opts Box (linewidth=5 color='purple') Image (cmap='gray')\n", + "hv.Image(data) * hv.Box(-0, 0, 0.25, aspect=3)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 2", + "language": "python", + "name": "python2" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 2 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython2", + "version": "2.7.13" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/examples/elements/matplotlib/BoxWhisker.ipynb b/examples/elements/matplotlib/BoxWhisker.ipynb new file mode 100644 index 0000000000..d2d2b522a3 --- /dev/null +++ b/examples/elements/matplotlib/BoxWhisker.ipynb @@ -0,0 +1,99 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
\n", + "
\n", + "
Title
BoxWhisker Element
\n", + "
Dependencies
Matplotlib
\n", + "
Backends
[Matplotlib](./BoxWhisker.ipynb)
[Bokeh](../bokeh/BoxWhisker.ipynb)
\n", + "
\n", + "
" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "import numpy as np\n", + "import holoviews as hv\n", + "hv.notebook_extension()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "A ``BoxWhisker`` Element is a quick way of visually summarizing one or more groups of numerical data through their quartiles. \n", + "\n", + "The data of a ``BoxWhisker`` Element may have any number of key dimensions representing the grouping of the value dimension and a single value dimensions representing the distribution of values within each group. See the [Columnar Data Tutorial](../Tutorials/Columnar_Data.ipynb) for supported data formats, which include arrays, pandas dataframes and dictionaries of arrays." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Without any groups a BoxWhisker Element represents a single distribution of values:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "hv.BoxWhisker(np.random.randn(1000), vdims=['Value'])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "By supplying key dimensions we can compare our distributions across multiple variables." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "%%opts BoxWhisker [width=600 height=400 show_legend=False] (whisker_color='gray' color='white')\n", + "groups = [chr(65+g) for g in np.random.randint(0, 3, 200)]\n", + "hv.BoxWhisker((groups, np.random.randint(0, 5, 200), np.random.randn(200)),\n", + " kdims=['Group', 'Category'], vdims=['Value']).sort()" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 2", + "language": "python", + "name": "python2" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 2 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython2", + "version": "2.7.13" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/examples/elements/matplotlib/Contours.ipynb b/examples/elements/matplotlib/Contours.ipynb new file mode 100644 index 0000000000..b55c99b7a3 --- /dev/null +++ b/examples/elements/matplotlib/Contours.ipynb @@ -0,0 +1,99 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
\n", + "
\n", + "
Title
Contours Element
\n", + "
Dependencies
Matplotlib
\n", + "
Backends
[Matplotlib](./Contours.ipynb)
[Bokeh](../bokeh/Contours.ipynb)
\n", + "
\n", + "
" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "import numpy as np\n", + "import holoviews as hv\n", + "hv.notebook_extension()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "A ``Contours`` object is similar to ``Path`` object except it may be associated with a numeric value (the ``level``), which can be used to apply colormapping the ``Contours``. To see the effect of this we can create a number of ``Contours`` with varying shapes and ``level`` values. In this case we will create a number of concentric rings with increasing radii and level values and colormap the ``Contours`` with the viridis colormap:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "%%opts Contours (cmap='viridis')\n", + "\n", + "def circle(radius, x=0, y=0):\n", + " angles = np.linspace(0, 2*np.pi, 100)\n", + " return np.array(list(zip(x+radius*np.sin(angles), y+radius*np.cos(angles))))\n", + "\n", + "hv.Overlay([hv.Contours([circle(i+0.05)], level=i) for i in np.linspace(0, 1, 10)])" + ] + }, + { + "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 compute an ``NdOverlay`` containing a ``Contours`` Element 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": { + "collapsed": false + }, + "outputs": [], + "source": [ + "%%opts Contours [show_legend=False colorbar=True width=325] (cmap='fire')\n", + "x,y = np.mgrid[-50:51, -50:51] * 0.05\n", + "img = hv.Image(np.sin(x**2+y**3))\n", + "\n", + "z0, z1 = img.range('z')\n", + "img + hv.operation.contours(img, levels=np.linspace(z0, z1, 5), overlaid=False)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 2", + "language": "python", + "name": "python2" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 2 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython2", + "version": "2.7.13" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/examples/elements/matplotlib/Curve.ipynb b/examples/elements/matplotlib/Curve.ipynb new file mode 100644 index 0000000000..c52e7ec259 --- /dev/null +++ b/examples/elements/matplotlib/Curve.ipynb @@ -0,0 +1,106 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
\n", + "
\n", + "
Title
Curve Element
\n", + "
Dependencies
Matplotlib
\n", + "
Backends
[Matplotlib](./Curve.ipynb)
[Bokeh](../bokeh/Curve.ipynb)
\n", + "
\n", + "
" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "import numpy as np\n", + "import holoviews as hv\n", + "hv.notebook_extension()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "``Curve`` Elements are used to display quantitative values over a continuous interval or time span. They accept tabular data with one key dimension representing the samples along the x-axis and one value dimension of the height of the curve at for each sample. See the [Columnar Data Tutorial](../Tutorials/Columnar_Data.ipynb) for supported data formats, which include arrays, pandas dataframes and dictionaries of arrays." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Simple Curve\n", + "\n", + "A ``Curve`` is a set of values provided for some set of keys from a [continuously indexable 1D coordinate system](Continuous_Coordinates.ipynb), where the plotted values will be connected up because they are assumed to be samples from a continuous relation." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "points = [(0.1*i, np.sin(0.1*i)) for i in range(100)]\n", + "hv.Curve(points)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Interpolation" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The ``Curve`` also supports the ``interpolation`` plot option to determine whether to linearly interpolate the curve values or to draw discrete steps:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "%%opts NdOverlay [legend_position='right']\n", + "hv.NdOverlay({interp: hv.Curve(points[::8])(plot=dict(interpolation=interp))\n", + " for interp in ['linear', 'steps-mid', 'steps-pre', 'steps-post']})" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 2", + "language": "python", + "name": "python2" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 2 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython2", + "version": "2.7.13" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/examples/elements/matplotlib/Ellipse.ipynb b/examples/elements/matplotlib/Ellipse.ipynb new file mode 100644 index 0000000000..ccbfe8e1a7 --- /dev/null +++ b/examples/elements/matplotlib/Ellipse.ipynb @@ -0,0 +1,77 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
\n", + "
\n", + "
Title
Ellipse Element
\n", + "
Dependencies
Matplotlib
\n", + "
Backends
[Matplotlib](./Ellipse.ipynb)
[Bokeh](../bokeh/Ellipse.ipynb)
\n", + "
\n", + "
" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "import numpy as np\n", + "import holoviews as hv\n", + "hv.notebook_extension()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "An ``Ellipse`` is an annotation that takes a center x-position, a center y-position, a width and an optional aspect ratio:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "%%opts Ellipse (linewidth=6)\n", + "# Generate some data\n", + "c1 = np.random.normal(loc=2, scale=0.2, size=(200,200))\n", + "c2x = np.random.normal(loc=-2, scale=0.6, size=200)\n", + "c2y = np.random.normal(loc=-2, scale=0.1, size=200)\n", + "c3 = np.random.normal(loc=0, scale=1.5, size=(400,400))\n", + "# Create an overlay of points and ellipses\n", + "clusters = hv.Points(c1) * hv.Points((c2x, c2y)) * hv.Points(c3)\n", + "clusters * hv.Ellipse(-2,-2, 0.2*12, aspect=1.5) * hv.Ellipse(2,2, 0.6*4)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 2", + "language": "python", + "name": "python2" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 2 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython2", + "version": "2.7.13" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/examples/elements/matplotlib/ErrorBars.ipynb b/examples/elements/matplotlib/ErrorBars.ipynb new file mode 100644 index 0000000000..6420fb2fbd --- /dev/null +++ b/examples/elements/matplotlib/ErrorBars.ipynb @@ -0,0 +1,108 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
\n", + "
\n", + "
Title
ErrorBars Element
\n", + "
Dependencies
Matplotlib
\n", + "
Backends
[Matplotlib](./ErrorBars.ipynb)
[Bokeh](../bokeh/ErrorBars.ipynb)
\n", + "
\n", + "
" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "import numpy as np\n", + "import holoviews as hv\n", + "hv.notebook_extension()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "``ErrorBars`` provide a visual indicator for the variability of the plotted data on a graph. They are usually applied on top of other plots such as scatter, curve or bar plots to indicate the variability in each sample. \n", + "\n", + "``ErrorBars`` may be used to represent symmetric error or assymetric error. An ``ErrorBars`` Element must have one key dimensions representing the samples along the x-axis and two or three value dimensions representing the value of the sample and positive and negative error values associated with that sample. See the [Columnar Data Tutorial](../Tutorials/Columnar_Data.ipynb) for supported data formats, which include arrays, pandas dataframes and dictionaries of arrays." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Symmetric error\n", + "\n", + "By default the ``ErrorBars`` Element accepts x- and y-coordinates along with a symmetric error value:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "np.random.seed(7)\n", + "errors = [(0.1*i, np.sin(0.1*i), np.random.rand()/2) for i in np.linspace(0, 100, 11)]\n", + "hv.Curve(errors) * hv.ErrorBars(errors)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Assymetric error" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "``ErrorBars`` is a set of x-/y-coordinates with associated error values. Error values may be either symmetric or asymmetric, and thus can be supplied as an Nx3 or Nx4 array (or any of the alternative constructors Chart Elements allow)." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "errors = [(0.1*i, np.sin(0.1*i), np.random.rand()/2, np.random.rand()/4) for i in np.linspace(0, 100, 11)]\n", + "hv.Curve(errors) * hv.ErrorBars(errors, vdims=['y', 'yerrneg', 'yerrpos'])" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 2", + "language": "python", + "name": "python2" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 2 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython2", + "version": "2.7.13" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/examples/elements/matplotlib/HLine.ipynb b/examples/elements/matplotlib/HLine.ipynb new file mode 100644 index 0000000000..c3873518aa --- /dev/null +++ b/examples/elements/matplotlib/HLine.ipynb @@ -0,0 +1,72 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
\n", + "
\n", + "
Title
HLine Element
\n", + "
Dependencies
Matplotlib
\n", + "
Backends
[Matplotlib](./HLine.ipynb)
[Bokeh](../bokeh/HLine.ipynb)
\n", + "
\n", + "
" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "import numpy as np\n", + "import holoviews as hv\n", + "hv.notebook_extension()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The ``HLine`` element is a type of annotation that marks a position along the y-axis. Here is an ``HLine`` element that marks the mean of a points distributions:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "%%opts HLine (color='blue' linewidth=6) Points (color='#D3D3D3')\n", + "xs = np.random.normal(size=100)\n", + "ys = np.random.normal(size=100) * xs\n", + "hv.Points((xs,ys)) * hv.HLine(ys.mean())" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 2", + "language": "python", + "name": "python2" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 2 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython2", + "version": "2.7.13" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/examples/elements/matplotlib/HSV.ipynb b/examples/elements/matplotlib/HSV.ipynb new file mode 100644 index 0000000000..3c4bc2e61a --- /dev/null +++ b/examples/elements/matplotlib/HSV.ipynb @@ -0,0 +1,115 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
\n", + "
\n", + "
Title
HSV Element
\n", + "
Dependencies
Matplotlib
\n", + "
Backends
[Matplotlib](./HSV.ipynb)
[Bokeh](../bokeh/HSV.ipynb)
\n", + "
\n", + "
" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "import numpy as np\n", + "import holoviews as hv\n", + "hv.notebook_extension()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "HoloViews makes it trivial to work in any color space that can be converted to ``RGB`` by making a simple subclass of ``RGB`` as appropriate. For instance, we also provide the HSV (hue, saturation, value) color space, which is useful for plotting cyclic data (as the Hue) along with two additional dimensions (controlling the saturation and value of the color, respectively).\n", + "\n", + "Like other raster based Element types ``HSV`` accepts gridded data, which may be supplied as a simple array ``NxMx3`` ndarray representing hue, saturation and value channels along with bounds or explicit array coordinates. See the [Gridded Data Tutorial](../doc/Gridded_Data.ipynb) tutorial to see the accepted data formats." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "x,y = np.mgrid[-50:51, -50:51] * 0.1\n", + "h = 0.5 + np.sin(0.2*(x**2+y**2)) / 2.0\n", + "s = 0.5*np.cos(y*3)+0.5\n", + "v = 0.5*np.cos(x*3)+0.5\n", + "\n", + "hsv = hv.HSV(np.dstack([h, s, v]))\n", + "hsv" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "You can see how this is created from the original channels:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "%opts Image (cmap='gray')\n", + "hsv[..., 'H'].relabel('H') + hsv[..., 'S'].relabel('S') + hsv[..., 'V'].relabel('V')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "An ``HSV`` Element can also easily be converted to an ``RGB`` Element using the ``rgb`` property:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "print(hsv.rgb)\n", + "hsv.rgb[..., 'R'] + hsv.rgb[..., 'G'] + hsv.rgb[..., 'B']" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 2", + "language": "python", + "name": "python2" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 2 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython2", + "version": "2.7.13" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/examples/elements/matplotlib/HeatMap.ipynb b/examples/elements/matplotlib/HeatMap.ipynb new file mode 100644 index 0000000000..3772e39b7d --- /dev/null +++ b/examples/elements/matplotlib/HeatMap.ipynb @@ -0,0 +1,113 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
\n", + "
\n", + "
Title
HeatMap Element
\n", + "
Dependencies
Matplotlib
\n", + "
Backends
[Matplotlib](./HeatMap.ipynb)
[Bokeh](../bokeh/HeatMap.ipynb)
\n", + "
\n", + "
" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "import numpy as np\n", + "import holoviews as hv\n", + "hv.notebook_extension()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "``HeatMap`` visualises tabular data indexed by two key dimensions as a grid of colored values. This allows spotting correlations in multivariate data and provides a high-level overview of how the two variables are plotted.\n", + "\n", + "The data for a ``HeatMap`` may be supplied as 2D tabular data with one or more associated value dimensions. The first value dimension will be colormapped, but further value dimensions may be revealed using the hover tool." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "data = [(chr(65+i), chr(97+j), i*j) for i in range(5) for j in range(5) if i!=j]\n", + "hv.HeatMap(data).sort()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "It is important to note that the data should be aggregated before plotting as the ``HeatMap`` cannot display multiple values for one coordinate and will simply use the first value it finds for each combination of x- and y-coordinates." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "heatmap = hv.HeatMap([(0, 0, 1), (0, 0, 10), (1, 0, 2), (1, 1, 3)])\n", + "heatmap + heatmap.aggregate(function=np.max)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "As the above example shows before aggregating the second value for the (0, 0) is ignored unless we aggregate the data first.\n", + "\n", + "To reveal the values of a ``HeatMap`` we can enable a ``colorbar`` and if you wish to have interactive hover information, you can use the hover tool in the [Bokeh backend](../bokeh/HeatMap.ipynb):" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "%%opts HeatMap [ colorbar=True fig_size=250]\n", + "hv.HeatMap((np.random.randint(0, 10, 100), np.random.randint(0, 10, 100),\n", + " np.random.randn(100), np.random.randn(100)), vdims=['z', 'z2']).redim.range(z=(-2, 2))" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 2", + "language": "python", + "name": "python2" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 2 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython2", + "version": "2.7.13" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/examples/elements/matplotlib/Histogram.ipynb b/examples/elements/matplotlib/Histogram.ipynb new file mode 100644 index 0000000000..f4723d267c --- /dev/null +++ b/examples/elements/matplotlib/Histogram.ipynb @@ -0,0 +1,119 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
\n", + "
\n", + "
Title
Histogram Element
\n", + "
Dependencies
Matplotlib
\n", + "
Backends
[Matplotlib](./Histogram.ipynb)
[Bokeh](../bokeh/Histogram.ipynb)
\n", + "
\n", + "
" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "import numpy as np\n", + "import holoviews as hv\n", + "hv.notebook_extension()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "``Histogram``s partition the `x` axis into discrete (but not necessarily regular) bins, showing counts in each as a bar. A ``Histogram`` accepts the output of ``np.histogram`` as input, which consists of a tuple of the histogram values with a shape of ``N`` and bin edges with a shape of ``N+1``. As a simple example we will generate a histogram of a normal distribution with 20 bins." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "np.random.seed(1)\n", + "data = np.random.randn(10000)\n", + "frequencies, edges = np.histogram(data, 20)\n", + "print('Values: %s, Edges: %s' % (frequencies.shape[0], edges.shape[0]))\n", + "hv.Histogram(frequencies, edges)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The ``Histogram`` Element will also expand evenly sampled bin centers, therefore we can easily cast between a linearly sampled Curve or Scatter and a Histogram." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "xs = np.linspace(0, np.pi*2)\n", + "ys = np.sin(xs)\n", + "curve = hv.Curve((xs, ys))\n", + "curve + hv.Histogram(curve)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The ``.hist`` method is an easy way to compute a histogram from an existing Element. The method effectively just calls the ``histogram`` operation, which lets you compute a histogram from an Element, and then adjoins the resulting histogram. Here we will create two sets of ``Points``, compute a ``Histogram`` for the 'x' and 'y' dimension on each, which we then overlay and adjoin to the plot." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "%%opts Histogram (alpha=0.3)\n", + "from holoviews.operation import histogram\n", + "points1 = hv.Points(np.random.randn(100,2)*2+1)\n", + "points2 = hv.Points(np.random.randn(100,2))\n", + "xhist, yhist = (histogram(points1, bin_range=(-5, 5), dimension=dim) *\n", + " histogram(points2, bin_range=(-5, 5), dimension=dim) \n", + " for dim in 'xy')\n", + "(points1 * points2) << yhist(plot=dict(width=125)) << xhist(plot=dict(height=125))" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 2", + "language": "python", + "name": "python2" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 2 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython2", + "version": "2.7.13" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/examples/elements/matplotlib/Image.ipynb b/examples/elements/matplotlib/Image.ipynb new file mode 100644 index 0000000000..4f75dc08d4 --- /dev/null +++ b/examples/elements/matplotlib/Image.ipynb @@ -0,0 +1,131 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
\n", + "
\n", + "
Title
Image Element
\n", + "
Dependencies
Matplotlib
\n", + "
Backends
[Matplotlib](./Image.ipynb)
[Bokeh](../bokeh/Image.ipynb)
\n", + "
\n", + "
" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "import numpy as np\n", + "import holoviews as hv\n", + "hv.notebook_extension()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Like ``Raster``, a HoloViews ``Image`` allows you to view 2D arrays using an arbitrary color map. Unlike ``Raster``, an ``Image`` is associated with a [2D coordinate system in continuous space](Continuous_Coordinates.ipynb), which is appropriate for values sampled from some underlying continuous distribution (as in a photograph or other measurements from locations in real space)." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "ls = np.linspace(0, 10, 200)\n", + "xx, yy = np.meshgrid(ls, ls)\n", + "\n", + "bounds=(-1,-1,1,1) # Coordinate system: (left, bottom, top, right)\n", + "img = hv.Image(np.sin(xx)*np.cos(yy), bounds=bounds)\n", + "img" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Slicing, sampling, etc. on an ``Image`` all operate in this continuous space, whereas the corresponding operations on a ``Raster`` work on the raw array coordinates." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "img + img[-0.5:0.5, -0.5:0.5]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Notice how, because our declared coordinate system is continuous, we can slice with any floating-point value we choose. The appropriate range of the samples in the input numpy array will always be displayed, whether or not there are samples at those specific floating-point values. This also allows us to index by a floating value, since the ``Image`` is defined as a continuous space it will snap to the closest coordinate, to inspect the closest coordinate we can use the ``closest`` method:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "%%opts Points (color='black' marker='x' size=20)\n", + "closest = img.closest((0.1,0.1))\n", + "print('The value at position %s is %s' % (closest, img[0.1, 0.1]))\n", + "img * hv.Points([img.closest((0.1,0.1))])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We can also easily take cross-sections of the Image by using the sample method or collapse a dimension using the ``reduce`` method:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "img.sample(x=0) + img.reduce(x=np.mean)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 2", + "language": "python", + "name": "python2" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 2 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython2", + "version": "2.7.13" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/examples/elements/matplotlib/ItemTable.ipynb b/examples/elements/matplotlib/ItemTable.ipynb new file mode 100644 index 0000000000..53a5293963 --- /dev/null +++ b/examples/elements/matplotlib/ItemTable.ipynb @@ -0,0 +1,69 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
\n", + "
\n", + "
Title
ItemTable Element
\n", + "
Dependencies
Matplotlib
\n", + "
Backends
[Matplotlib](./ItemTable.ipynb)
[Bokeh](../bokeh/ItemTable.ipynb)
\n", + "
\n", + "
" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "import numpy as np\n", + "import holoviews as hv\n", + "hv.notebook_extension()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "An ``ItemTable`` is an ordered collection of key, value pairs. It can be used to directly visualize items in a tabular format where the items may be supplied as an ``OrderedDict`` or a list of (key,value) pairs. A standard Python dictionary can be easily visualized using a call to the ``.items()`` method, though the entries in such a dictionary are not kept in any particular order, and so you may wish to sort them before display. One typical usage for an ``ItemTable`` is to list parameter values or measurements associated with an adjacent ``Element``." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "hv.ItemTable([('Age', 10), ('Weight',15), ('Height','0.8 meters')])" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 2", + "language": "python", + "name": "python2" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 2 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython2", + "version": "2.7.13" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/examples/elements/matplotlib/Path.ipynb b/examples/elements/matplotlib/Path.ipynb new file mode 100644 index 0000000000..328963b19b --- /dev/null +++ b/examples/elements/matplotlib/Path.ipynb @@ -0,0 +1,125 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
\n", + "
\n", + "
Title
Path Element
\n", + "
Dependencies
Matplotlib
\n", + "
Backends
[Matplotlib](./Path.ipynb)
[Bokeh](../bokeh/Path.ipynb)
\n", + "
\n", + "
" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "import numpy as np\n", + "import holoviews as hv\n", + "hv.notebook_extension()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "A ``Path`` object is actually a collection of lines, which are all plotted with the same style. Unlike ``Curve`` where the y-axis is the dependent variable, a ``Path`` consists of lines connecting arbitrary points in two-dimensional space as is not expected to be a function.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "%%opts Path (color='black' linewidth=4)\n", + "lin = np.linspace(-np.pi,np.pi,300)\n", + "\n", + "def lissajous(t, a,b, delta):\n", + " return (np.sin(a * t + delta), np.sin(b * t))\n", + "\n", + "hv.Path(lissajous(np.linspace(-np.pi, np.pi, 1000),3,5,np.pi/2))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Unlike ``Curve`` as single ``Path`` element can contain multiple lines that are disconnected from each other which will all be plotted in the same style. Only by overlaying multiple ``Path`` objects do you iterate through the defined color cycle (or any other style options that have been defined). A ``Path`` is often useful to draw arbitrary annotations on top of an existing plot.\n", + "\n", + "A ``Path`` Element accepts multiple formats for specifying the paths, the simplest of which is passing a list of ``Nx2`` arrays of the x- and y-coordinates, alternative we can pass lists of coordinates. In this example we will create some coordinates representing rectangles and ellipses annotating an ``RGB`` image:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "%%opts Path (linewidth=4)\n", + "angle = np.linspace(0, 2*np.pi, 100)\n", + "baby = list(zip(0.15*np.sin(angle), 0.2*np.cos(angle)-0.2))\n", + "\n", + "adultR = [(0.25, 0.45), (0.35,0.35), (0.25, 0.25), (0.15, 0.35), (0.25, 0.45)]\n", + "adultL = [(-0.3, 0.4), (-0.3, 0.3), (-0.2, 0.3), (-0.2, 0.4),(-0.3, 0.4)]\n", + "scene = hv.RGB.load_image('../../../doc/assets/penguins.png')\n", + "\n", + "scene * hv.Path([adultL, adultR, baby]) * hv.Path([baby])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "A ``Path`` can also be used as a means to display a number of lines with the same sampling along the x-axis at once. If we initialize the ``Path`` with a tuple of x-coordinates and stacked y-coordinates, we can quickly view a number of lines at once. Here we will generate a number of random traces each slightly offset along the y-axis:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "%%opts Path [fig_size=400 aspect=3]\n", + "N, NLINES = 100, 10\n", + "hv.Path((np.arange(N), np.random.rand(N, NLINES) + np.arange(NLINES)[np.newaxis, :])) *\\\n", + "hv.Path((np.arange(N), np.random.rand(N, NLINES) + np.arange(NLINES)[np.newaxis, :]))" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 2", + "language": "python", + "name": "python2" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 2 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython2", + "version": "2.7.13" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/examples/elements/matplotlib/Points.ipynb b/examples/elements/matplotlib/Points.ipynb new file mode 100644 index 0000000000..6db7110989 --- /dev/null +++ b/examples/elements/matplotlib/Points.ipynb @@ -0,0 +1,133 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
\n", + "
\n", + "
Title
Points Element
\n", + "
Dependencies
Matplotlib
\n", + "
Backends
[Matplotlib](./Points.ipynb)
[Bokeh](../bokeh/Points.ipynb)
\n", + "
\n", + "
" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "import numpy as np\n", + "import holoviews as hv\n", + "hv.notebook_extension()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The ``Points`` element visualizes as markers placed in a space of two independent variables, traditionally denoted *x* and *y*. In HoloViews, the names ``'x'`` and ``'y'`` are used as the default ``key_dimensions`` of the element. We can see this from the default axis labels when visualizing a simple ``Points`` element:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "%%opts Points (color='k' marker='+' size=10)\n", + "np.random.seed(12)\n", + "coords = np.random.rand(50,2)\n", + "hv.Points(coords)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Here both the random *x* values and random *y* values are *both* considered to be the 'data' with no dependency between them (compare this to how [``Scatter``](./Scatter.ipynb) elements are defined). You can think of ``Points`` as simply marking positions in some two-dimensional space that can be sliced by specifying a 2D region-of-interest:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "%%opts Points (color='k' marker='+' size=10)\n", + "hv.Points(coords) + hv.Points(coords)[0.6:0.8,0.2:0.5]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Although the simplest ``Points`` element simply mark positions in a two-dimensional space without any associated value this doesn't mean value dimensions aren't supported. Here is an example with two additional quantities for each point, declared as the ``value_dimension``s *z* and α visualized as the color and size of the dots, respectively:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "%%opts Points [color_index=2 size_index=3 scaling_factor=50]\n", + "np.random.seed(10)\n", + "data = np.random.rand(100,4)\n", + "\n", + "points = hv.Points(data, vdims=['z', 'size'])\n", + "points + points[0.3:0.7, 0.3:0.7].hist()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "In the right subplot, the ``hist`` method is used to show the distribution of samples along the first value dimension we added (*z*).\n", + "\n", + "\n", + "The marker shape specified above can be any supported by [matplotlib](http://matplotlib.org/api/markers_api.html), e.g. ``s``, ``d``, or ``o``; the other options select the color and size of the marker. For convenience with the [bokeh backend](Bokeh_Backend), the matplotlib marker options are supported using a compatibility function in HoloViews." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Note**: Although the ``Scatter`` element is superficially similar to the [``Points``](./Points.ipynb) element (they can generate plots that look identical), the two element types are semantically quite different. The fundamental difference is that [``Points``](./Points.ipynb) are used to visualize data where the *y* variable is *dependent*. This semantic difference also explains why the histogram generated by ``hist`` call above visualizes the distribution of a different dimension than it does for [``Scatter``](./Scatter.ipynb).\n", + "\n", + "This difference means that ``Points`` naturally combine elements that express independent variables in two-dimensional space, for instance [``Raster``](./Raster.ipynb) types such as [``Image``](./Image.ipynb). Similarly, ``Scatter`` expresses a dependent relationship in two-dimensions and combine naturally with ``Chart`` types such as [``Curve``](./Curve.ipynb)." + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 2", + "language": "python", + "name": "python2" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 2 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython2", + "version": "2.7.13" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/examples/elements/matplotlib/Polygons.ipynb b/examples/elements/matplotlib/Polygons.ipynb new file mode 100644 index 0000000000..3c6497bbe8 --- /dev/null +++ b/examples/elements/matplotlib/Polygons.ipynb @@ -0,0 +1,99 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
\n", + "
\n", + "
Title
Polygons Element
\n", + "
Dependencies
Matplotlib
\n", + "
Backends
[Matplotlib](./Polygons.ipynb)
[Bokeh](../bokeh/Polygons.ipynb)
\n", + "
\n", + "
" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "import numpy as np\n", + "import holoviews as hv\n", + "hv.notebook_extension()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "A ``Polygons`` object is similar to a ``Contours`` object except that each supplied path is closed and filled. Just like ``Contours``, an optional ``level`` value may be supplied; the Polygons will then be colored according to the supplied ``cmap``. Non-finite values such as ``np.NaN`` or ``np.inf`` will default to the supplied ``facecolor``.\n", + "\n", + "Polygons with values can be used to build heatmaps with arbitrary shapes." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "%%opts Polygons (cmap='hot' edgecolor='black' linewidth=2)\n", + "np.random.seed(35)\n", + "hv.Polygons([np.random.rand(4,2)], level=0.5) *\\\n", + "hv.Polygons([np.random.rand(4,2)], level=1.0) *\\\n", + "hv.Polygons([np.random.rand(4,2)], level=1.5) *\\\n", + "hv.Polygons([np.random.rand(4,2)], level=2.0)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "``Polygons`` without a value are useful as annotation, but also allow us to draw arbitrary shapes." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "def rectangle(x=0, y=0, width=1, height=1):\n", + " return np.array([(x,y), (x+width, y), (x+width, y+height), (x, y+height)])\n", + "\n", + "(hv.Polygons([rectangle(width=2), rectangle(x=6, width=2)])(style={'facecolor': '#a50d0d'})\n", + "* hv.Polygons([rectangle(x=2, height=2), rectangle(x=5, height=2)])(style={'facecolor': '#ffcc00'})\n", + "* hv.Polygons([rectangle(x=3, height=2, width=2)])(style={'facecolor': 'cyan'}))" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 2", + "language": "python", + "name": "python2" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 2 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython2", + "version": "2.7.13" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/examples/elements/matplotlib/QuadMesh.ipynb b/examples/elements/matplotlib/QuadMesh.ipynb new file mode 100644 index 0000000000..32f04361c0 --- /dev/null +++ b/examples/elements/matplotlib/QuadMesh.ipynb @@ -0,0 +1,120 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
\n", + "
\n", + "
Title
QuadMesh Element
\n", + "
Dependencies
Matplotlib
\n", + "
Backends
[Matplotlib](./QuadMesh.ipynb)
[Bokeh](../bokeh/QuadMesh.ipynb)
\n", + "
\n", + "
" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "import numpy as np\n", + "import holoviews as hv\n", + "hv.notebook_extension()" + ] + }, + { + "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": { + "collapsed": false + }, + "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. As the bin edges have continuous values, you can use non-linear axes such as log axes:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "%%opts QuadMesh [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": { + "collapsed": false + }, + "outputs": [], + "source": [ + "qmesh = hv.QuadMesh((xs, ys, zs))\n", + "qmesh[20:400, :8].redim.range(z=qmesh.range('z'))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "To use an interactive hover tool to inspect the sample values, you can use ``QuadMesh`` with the hover tool in the [Bokeh backend](../bokeh/QuadMesh.ipynb)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 2", + "language": "python", + "name": "python2" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 2 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython2", + "version": "2.7.13" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/examples/elements/matplotlib/RGB.ipynb b/examples/elements/matplotlib/RGB.ipynb new file mode 100644 index 0000000000..4cda4e4b1d --- /dev/null +++ b/examples/elements/matplotlib/RGB.ipynb @@ -0,0 +1,136 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
\n", + "
\n", + "
Title
RGB Element
\n", + "
Dependencies
Matplotlib
\n", + "
Backends
[Matplotlib](./RGB.ipynb)
[Bokeh](../bokeh/RGB.ipynb)
\n", + "
\n", + "
" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "import numpy as np\n", + "import holoviews as hv\n", + "hv.notebook_extension()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The ``RGB`` element is a subclass of [``Image``](./Image.ipynb) that supports red, green, blue channels. One of the simplest ways of creating an ``RGB`` element is to load an image file (such as PNG) off disk, using the ``load_image`` classmethod:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "hv.RGB.load_image('../../../doc/assets/penguins.png')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Although convenient, this method doesn't show how an ``RGB`` is constructed from arrays. The next example shows that the input can be a simple stack of two-dimensional numpy arrays:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "x,y = np.mgrid[-50:51, -50:51] * 0.1\n", + "\n", + "r = 0.5*np.sin(np.pi +3*x**2+y**2)+0.5\n", + "g = 0.5*np.sin(x**2+2*y**2)+0.5\n", + "b = 0.5*np.sin(np.pi/2+x**2+y**2)+0.5\n", + "\n", + "hv.RGB(np.dstack([r,g,b]))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "You can see how the RGB object is created from the original channels:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "%%opts Image (cmap='gray')\n", + "hv.Image(r,label=\"R\") + hv.Image(g,label=\"G\") + hv.Image(b,label=\"B\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "``RGB`` also supports an optional alpha channel, which will be used as a mask revealing or hiding any ``Element``s it is overlaid on top of:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "%%opts Image (cmap='gray')\n", + "mask = 0.5*np.sin(0.2*(x**2+y**2))+0.5\n", + "rgba = hv.RGB(np.dstack([r,g,b,mask]))\n", + "\n", + "bg = hv.Image(0.5*np.cos(x*3)+0.5, label=\"Background\") * hv.VLine(x=0,label=\"Background\")\n", + "overlay = (bg*rgba).relabel(\"RGBA Overlay\")\n", + "bg + hv.Image(mask,label=\"Mask\") + overlay" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 2", + "language": "python", + "name": "python2" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 2 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython2", + "version": "2.7.13" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/examples/elements/matplotlib/Raster.ipynb b/examples/elements/matplotlib/Raster.ipynb new file mode 100644 index 0000000000..79d01a83b5 --- /dev/null +++ b/examples/elements/matplotlib/Raster.ipynb @@ -0,0 +1,78 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
\n", + "
\n", + "
Title
Raster Element
\n", + "
Dependencies
Matplotlib
\n", + "
Backends
[Matplotlib](./Raster.ipynb)
[Bokeh](../bokeh/Raster.ipynb)
\n", + "
\n", + "
" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "import numpy as np\n", + "import holoviews as hv\n", + "hv.notebook_extension()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "A ``Raster`` is the base class for image-like elements (namely [``Image``](./Image.ipynb), [``RGB``](./RGB.ipynb) and [``HSV``](./HSV.ipynb)), but may be used directly to visualize 2D arrays using a color map:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "xvals = np.linspace(0,4,202)\n", + "ys,xs = np.meshgrid(xvals, -xvals[::-1])\n", + "hv.Raster(np.sin(((ys)**3)*xs))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The coordinate system of a ``Raster`` is the raw indexes of the underlying array, with integer values always starting from (0,0) in the top left, with default extents corresponding to the shape of the array. For a similar element used to visualize arrays but defined in a continuous Cartesian coordinate system, use the [``Image``](./Image.ipynb) element." + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 2", + "language": "python", + "name": "python2" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 2 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython2", + "version": "2.7.13" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/examples/elements/matplotlib/Scatter.ipynb b/examples/elements/matplotlib/Scatter.ipynb new file mode 100644 index 0000000000..862fd8ad61 --- /dev/null +++ b/examples/elements/matplotlib/Scatter.ipynb @@ -0,0 +1,137 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
\n", + "
\n", + "
Title
Scatter Element
\n", + "
Dependencies
Matplotlib
\n", + "
Backends
[Matplotlib](./Scatter.ipynb)
[Bokeh](../bokeh/Scatter.ipynb)
\n", + "
\n", + "
" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "import numpy as np\n", + "import holoviews as hv\n", + "hv.notebook_extension()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The ``Scatter`` element visualizes as markers placed in a space of one independent variable, traditionally denoted as *x*, against a dependent variable, traditonally denoted as *y*. In HoloViews, the name ``'x'`` is the default dimension name used in the ``key_dimensions`` and ``'y'`` is the default dimension name used in the ``value_dimensions``. We can see this from the default axis labels when visualizing a simple ``Scatter`` element:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "%%opts Scatter (color='k' marker='s' size=10)\n", + "np.random.seed(42)\n", + "coords = [(i, np.random.random()) for i in range(20)]\n", + "hv.Scatter(coords)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Here the random *y* values are considered to be the 'data' whereas the x positions express where those values are located (compare this to how [``Points``](./Points.ipynb) elements are defined). In this sense, ``Scatter`` can be thought of as a [``Curve``](./Curve.ipynb) without any lines connecting the samples and you can use slicing to view the *y* values corresponding to a chosen *x* range:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "%%opts Scatter (color='k' marker='s' size=10)\n", + "hv.Scatter(coords)[0:12] + hv.Scatter(coords)[12:20]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "A ``Scatter`` element must always have at least one value dimension but that doesn't mean additional value dimensions aren't supported. Here is an example with two additional quantities for each point, declared as the ``value_dimension``s *z* and α visualized as the color and size of the dots, respectively:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "%%opts Scatter [color_index=2 size_index=3 scaling_factor=50]\n", + "np.random.seed(10)\n", + "data = np.random.rand(100,4)\n", + "\n", + "scatter = hv.Scatter(data, vdims=['y', 'z', 'size'])\n", + "scatter + scatter[0.3:0.7, 0.3:0.7].hist()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "In the right subplot, the ``hist`` method is used to show the distribution of samples along our first value dimension, (*y*)." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The marker shape specified above can be any supported by [matplotlib](http://matplotlib.org/api/markers_api.html), e.g. ``s``, ``d``, or ``o``; the other options select the color and size of the marker. For convenience with the [bokeh backend](Bokeh_Backend), the matplotlib marker options are supported using a compatibility function in HoloViews." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Note**: Although the ``Scatter`` element is superficially similar to the [``Points``](./Points.ipynb) element (they can generate plots that look identical), the two element types are semantically quite different: ``Points`` are used to visualize data where the *y* variable is *dependent*. This semantic difference also explains why the histogram generated by ``hist`` call above visualizes the distribution of a different dimension than it does for [``Points``](./Points.ipynb).\n", + "\n", + "This difference means that ``Scatter`` naturally combine elements that express dependent variables in two-dimensional space such as the ``Chart`` types, such as [``Curve``](./Curve.ipynb). Similarly, ``Points`` express a independent relationship in two-dimensions and combine naturally with [``Raster``](./Raster.ipynb) types such as [``Image``](./Image.ipynb)." + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 2", + "language": "python", + "name": "python2" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 2 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython2", + "version": "2.7.13" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/examples/elements/matplotlib/Spikes.ipynb b/examples/elements/matplotlib/Spikes.ipynb new file mode 100644 index 0000000000..6f897471c8 --- /dev/null +++ b/examples/elements/matplotlib/Spikes.ipynb @@ -0,0 +1,152 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
\n", + "
\n", + "
Title
Spikes Element
\n", + "
Dependencies
Matplotlib
\n", + "
Backends
[Matplotlib](./Spikes.ipynb)
[Bokeh](../bokeh/Spikes.ipynb)
\n", + "
\n", + "
" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "import numpy as np\n", + "import holoviews as hv\n", + "hv.notebook_extension()" + ] + }, + { + "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:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "%%opts Spikes (alpha=0.4) [spike_length=0.1]\n", + "xs = np.random.rand(50)\n", + "hv.Spikes(xs)" + ] + }, + { + "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": { + "collapsed": false + }, + "outputs": [], + "source": [ + "%%opts Points (color='red')\n", + "ys = np.random.rand(50)\n", + "hv.Points((xs, ys)) * hv.Spikes(xs)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "When supplying a second dimension to the ``Spikes`` element as a value dimensions, these additional values will be mapped onto the line height. Optionally, you may also supply a colormap ``cmap`` and ``color_index`` to map the value dimensions to a suitable set of colors. This way we can, for example, plot a [mass spectrogram](https://en.wikipedia.org/wiki/Mass_spectrometry):" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "%%opts Spikes (cmap='Reds')\n", + "hv.Spikes(np.random.rand(20, 2), kdims=['Mass'], vdims=['Intensity'])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Another possibility is to draw a number of spike trains representing the firing of neurons, of the sort that are commonly encountered in neuroscience. 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": { + "collapsed": false + }, + "outputs": [], + "source": [ + "%%opts Spikes [spike_length=0.1] NdOverlay [show_legend=False]\n", + "hv.NdOverlay({i: hv.Spikes(np.random.randint(0, 100, 10), kdims=['Time'])(plot=dict(position=0.1*i))\n", + " for i in range(10)})(plot=dict(yticks=[((i+1)*0.1-0.05, i) for i in range(10)]))" + ] + }, + { + "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": { + "collapsed": false + }, + "outputs": [], + "source": [ + "%%opts Spikes (alpha=0.2)\n", + "points = hv.Points(np.random.randn(500, 2))\n", + "points << hv.Spikes(points['y']) << hv.Spikes(points['x'])" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 2", + "language": "python", + "name": "python2" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 2 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython2", + "version": "2.7.13" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/examples/elements/matplotlib/Spline.ipynb b/examples/elements/matplotlib/Spline.ipynb new file mode 100644 index 0000000000..4ffb90a193 --- /dev/null +++ b/examples/elements/matplotlib/Spline.ipynb @@ -0,0 +1,78 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
\n", + "
\n", + "
Title
Spline Element
\n", + "
Dependencies
Matplotlib
\n", + "
Backends
[Matplotlib](./Spline.ipynb)
[Bokeh](../bokeh/Spline.ipynb)
\n", + "
\n", + "
" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "import numpy as np\n", + "import holoviews as hv\n", + "hv.notebook_extension()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The ``Spline`` annotation is used to draw cubic Bezier curves. In the overlay below, the spline is in green and the control points are shown by the light grey line:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "%%opts Curve (color='#D3D3D3') Spline (linewidth=6 edgecolor='green')\n", + "points = [(-0.3, -0.3), (0,0), (0.25, -0.25), (0.3, 0.3)]\n", + "hv.Spline((points, [1,4,4,4])) * hv.Curve(points)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The first argument to ``Splines`` are the control point positions and the integers in the second list are the control codes, as documented in the [matplotlib splines documentation](http://matplotlib.org/api/path_api.html)." + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 2", + "language": "python", + "name": "python2" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 2 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython2", + "version": "2.7.13" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/examples/elements/matplotlib/Spread.ipynb b/examples/elements/matplotlib/Spread.ipynb new file mode 100644 index 0000000000..060cda230f --- /dev/null +++ b/examples/elements/matplotlib/Spread.ipynb @@ -0,0 +1,111 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
\n", + "
\n", + "
Title
Spread Element
\n", + "
Dependencies
Matplotlib
\n", + "
Backends
[Matplotlib](./Spread.ipynb)
[Bokeh](../bokeh/Spread.ipynb)
\n", + "
\n", + "
" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "import numpy as np\n", + "import holoviews as hv\n", + "hv.notebook_extension()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "``Spread`` elements have the same data format as the [``ErrorBars``](ErrorBars.ipynb) element, namely x- and y-values with associated symmetric or assymetric errors, but are interpreted as samples from a continuous distribution (just as ``Curve`` is the continuous version of ``Scatter``). These are often paired with an overlaid ``Curve`` to show an average trend along with a corresponding spread of values; see the [Columnar Data tutorial](Columnar_Data.ipynb) for examples.\n", + "\n", + "Note that as the ``Spread`` element is used to add information to a plot (typically a ``Curve``) the default alpha value is less that one, making it partially transparent. \n", + "\n", + "##### Symmetric" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Given two value dimensions corresponding to the position on the y-axis and the error, ``Spread`` will visualize itself assuming symmetric errors:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "np.random.seed(42)\n", + "xs = np.linspace(0, np.pi*2, 20)\n", + "err = 0.2+np.random.rand(len(xs))\n", + "hv.Spread((xs, np.sin(xs), err))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "##### Asymmetric" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Given three value dimensions corresponding to the position on the y-axis, the negative error and the positive error, ``Spread`` can be used to visualize assymmetric errors:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "%%opts Spread (facecolor='indianred' alpha=1)\n", + "xs = np.linspace(0, np.pi*2, 20)\n", + "hv.Spread((xs, np.sin(xs), 0.1+np.random.rand(len(xs)), 0.1+np.random.rand(len(xs))),\n", + " vdims=['y', 'yerrneg', 'yerrpos'])" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 2", + "language": "python", + "name": "python2" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 2 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython2", + "version": "2.7.13" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/examples/elements/matplotlib/Table.ipynb b/examples/elements/matplotlib/Table.ipynb new file mode 100644 index 0000000000..5918a8daff --- /dev/null +++ b/examples/elements/matplotlib/Table.ipynb @@ -0,0 +1,153 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
\n", + "
\n", + "
Title
Table Element
\n", + "
Dependencies
Matplotlib
\n", + "
Backends
[Matplotlib](./Table.ipynb)
[Bokeh](../bokeh/Table.ipynb)
\n", + "
\n", + "
" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "import numpy as np\n", + "import holoviews as hv\n", + "hv.notebook_extension()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "A table is more general than an [``ItemTable``](./ItemTable.ioynb), as it allows multi-dimensional keys and multidimensional values. Let's say we have the following data:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "gender = ['M','M', 'M','F']\n", + "age = [10,16,13,12]\n", + "weight = [15,18,16,10]\n", + "height = [0.8,0.6,0.7,0.8]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We can construct a ``Table`` using a dictionary format (identical in format as that accepted by the [pandas](http://pandas.pydata.org/) ``DataFrame``):" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "hv.Table({'Gender':gender, 'Age':age, 'Weight':weight, 'Height':height},\n", + " kdims = ['Gender', 'Age'], vdims=['Weight', 'Height'])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Or we can declare the same table by dimension position, with key dimensions followed by value dimensions:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "table = hv.Table((gender, age, weight, height), kdims = ['Gender', 'Age'], vdims=['Weight', 'Height'])\n", + "table" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Note that you can use the ``select`` method using tables by the key dimensions:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "table.select(Gender='M') + table.select(Gender='M', Age=10)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The ``Table`` is used as a common data structure that may be converted to any other HoloViews data structure via the ``to`` utility available on the object. Here we use this utility to show the weight of the males in our datset by age:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "table.select(Gender='M').to.curve(kdims=[\"Age\"], vdims=[\"Weight\"])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "For more extended usage of table conversion see the [Columnar Data](Columnnar_Data.ipynb) and [Pandas Conversion](Pandas_Conversion.ipynb) Tutorials." + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 2", + "language": "python", + "name": "python2" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 2 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython2", + "version": "2.7.13" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/examples/elements/matplotlib/Text.ipynb b/examples/elements/matplotlib/Text.ipynb new file mode 100644 index 0000000000..0a36022841 --- /dev/null +++ b/examples/elements/matplotlib/Text.ipynb @@ -0,0 +1,71 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
\n", + "
\n", + "
Title
Text Element
\n", + "
Dependencies
Matplotlib
\n", + "
Backends
[Matplotlib](./Text.ipynb)
[Bokeh](../bokeh/Text.ipynb)
\n", + "
\n", + "
" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "import numpy as np\n", + "import holoviews as hv\n", + "hv.notebook_extension()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The ``Text`` annotation is used to overlay text at a particular position on a plot:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "%%opts Curve (color='#D3D3D3')\n", + "xs = np.linspace(-5,5,100)\n", + "hv.Curve((xs,-(xs-2)**2)) * hv.Text(0, -30, 'Quadratic Curve')" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 2", + "language": "python", + "name": "python2" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 2 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython2", + "version": "2.7.13" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/examples/elements/matplotlib/VLine.ipynb b/examples/elements/matplotlib/VLine.ipynb new file mode 100644 index 0000000000..55b1fab420 --- /dev/null +++ b/examples/elements/matplotlib/VLine.ipynb @@ -0,0 +1,72 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
\n", + "
\n", + "
Title
VLine Element
\n", + "
Dependencies
Matplotlib
\n", + "
Backends
[Matplotlib](./VLine.ipynb)
[Bokeh](../bokeh/VLine.ipynb)
\n", + "
\n", + "
" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "import numpy as np\n", + "import holoviews as hv\n", + "hv.notebook_extension()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The ``VLine`` element is a type of annotation that marks a position along the x-axis. Here is a ``VLine`` marking the maximum of a quadratic curve:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "%%opts VLine (color='red' linewidth=6) Curve (color='#D3D3D3')\n", + "xs = np.linspace(-5,5,100)\n", + "ys = -(xs-2)**2\n", + "hv.Curve((xs,ys)) * hv.VLine(xs[ys.argmax()])" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 2", + "language": "python", + "name": "python2" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 2 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython2", + "version": "2.7.13" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/examples/elements/matplotlib/VectorField.ipynb b/examples/elements/matplotlib/VectorField.ipynb new file mode 100644 index 0000000000..434909ec06 --- /dev/null +++ b/examples/elements/matplotlib/VectorField.ipynb @@ -0,0 +1,160 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
\n", + "
\n", + "
Title
VectorField Element
\n", + "
Dependencies
Matplotlib
\n", + "
Backends
[Matplotlib](./VectorField.ipynb)
[Bokeh](../bokeh/VectorField.ipynb)
\n", + "
\n", + "
" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "import numpy as np\n", + "import holoviews as hv\n", + "hv.notebook_extension()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "A ``VectorField`` plot displays velocity vectors as arrows at ``x`` and ``y`` positions with angle and magnitude components (or alternatively ``U``, ``V`` components). The element accepts the usual columnar format passing the ``(x, y, angles, magnitudes)`` components as a tuple, but also handles 2D arrays when supplied as a list instead:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "%%opts VectorField [size_index=3]\n", + "x,y = np.mgrid[-10:10,-10:10] * 0.25\n", + "sine_rings = np.sin(x**2+y**2)*np.pi+np.pi\n", + "exp_falloff = 1/np.exp((x**2+y**2)/8)\n", + "\n", + "vector_data = [x,y,sine_rings, exp_falloff]\n", + "hv.VectorField(vector_data)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "As you can see above, here the *x* and *y* positions are chosen to make a regular grid. The arrow angles follow a sinsoidal ring pattern, and the arrow lengths fall off exponentially from the center, so this plot has four dimensions of data (direction and length for each *x,y* position).\n", + "\n", + "Using the ``%%opts`` cell-magic, we can also use color as a redundant indicator to the direction or magnitude:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "%%opts VectorField [size_index=3] VectorField.A [color_index=2] VectorField.M [color_index=3]\n", + "hv.VectorField(vector_data, group='A') + hv.VectorField(vector_data, group='M')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "By default the arrows are rescaled to the minimum distance between individual arrows, to disable this rescaling set ``rescale=False`` and adjust the ``scale`` manually (smaller values result in larger arrows). This allows fixed scaling even when plotting arrows in an animation. Here we will vary the arrow angle with a Phase dimension and also add this angle to the magnitude data, showing the arrow angles and magnitudes varying. Due to the fixed scaling we can make out the differences across frames:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "%%opts VectorField [color_index=2 size_index=3 rescale_lengths=False] (scale=4)\n", + "hv.HoloMap({phase: hv.VectorField([x, y,(vector_data[2]+phase)%np.pi*2, vector_data[3]+np.abs(phase)])\n", + " for phase in np.linspace(-np.pi,np.pi,5)}, kdims=['Phase'])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Vectors are also often expressed through U and V components we can easily transform these to a magnitude and angle:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "xs, ys = np.arange(0, 2 * np.pi, .2), np.arange(0, 2 * np.pi, .2)\n", + "X, Y = np.meshgrid(xs, ys)\n", + "U = np.cos(X)\n", + "V = np.sin(Y)\n", + "\n", + "# Convert U, V to magnitude and angle\n", + "mag = np.sqrt(U**2 + V**2)\n", + "angle = (np.pi/2.) - np.arctan2(U/mag, V/mag)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "``VectorField`` also allows defining the ``pivot`` point of the vectors. We can for instance define ``pivot='tip'`` to pivot around the tip of the arrow. To make this clearer we will mark the pivot points:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "%%opts VectorField [color_index=3 size_index=3 pivot='tip'] (cmap='fire' scale=0.8) Points (color='black' s=1)\n", + "hv.VectorField((xs, ys, angle, mag)) * hv.Points((X.flat, Y.flat))" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 2", + "language": "python", + "name": "python2" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 2 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython2", + "version": "2.7.13" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/holoviews/element/chart.py b/holoviews/element/chart.py index 5f705a2807..d8a3eaa40c 100644 --- a/holoviews/element/chart.py +++ b/holoviews/element/chart.py @@ -391,8 +391,8 @@ class Area(Curve): def stack(cls, areas): """ Stacks an (Nd)Overlay of Area or Curve Elements by offsetting - their baselines. To stack a HoloMap or DynamicMap use the - stack_area Element operation or apply it using the map method. + their baselines. To stack a HoloMap or DynamicMap use the map + method. """ baseline = np.zeros(len(areas.get(0))) stacked = areas.clone(shared_data=False) diff --git a/holoviews/operation/element.py b/holoviews/operation/element.py index ab4b5fed33..7530791dfe 100644 --- a/holoviews/operation/element.py +++ b/holoviews/operation/element.py @@ -668,15 +668,6 @@ def _process(self, element, key=None): return element.map(self._process_layer, Element) -class stack_area(Operation): - """ - Stacks an (Nd)Overlay of Area Elements by offsetting their baseline. - """ - - def _process(self, areas, key=None): - return Area.stack(areas) - - #==================# # Other operations # #==================# diff --git a/tests/testoperation.py b/tests/testoperation.py index 822995a232..fe36511fa2 100644 --- a/tests/testoperation.py +++ b/tests/testoperation.py @@ -6,7 +6,7 @@ from holoviews.element.comparison import ComparisonTestCase from holoviews.operation.element import (operation, transform, threshold, gradient, contours, histogram, - interpolate_curve, stack_area) + interpolate_curve) class OperationTests(ComparisonTestCase): """ @@ -95,7 +95,7 @@ def test_points_histogram_weighted(self): op_hist = histogram(points, num_bins=3, weight_dimension='y') hist = Histogram(([0.022222, 0.088889, 0.222222], [0, 3, 6, 9]), vdims=['y']) self.assertEqual(op_hist, hist) - + def test_points_histogram_mean_weighted(self): points = Points([float(i) for i in range(10)]) op_hist = histogram(points, num_bins=3, weight_dimension='y', mean_weighted=True) @@ -119,15 +119,14 @@ def test_interpolate_curve_post(self): def test_stack_area_overlay(self): areas = Area([1, 2, 3]) * Area([1, 2, 3]) - stacked = stack_area(areas) + stacked = Area.stack(areas) area1 = Area(([0, 1, 2], [1, 2, 3], [0, 0, 0]), vdims=['y', 'Baseline']) area2 = Area(([0, 1, 2], [2, 4, 6], [1, 2, 3]), vdims=['y', 'Baseline']) self.assertEqual(stacked, area1 * area2) def test_stack_area_ndoverlay(self): areas = NdOverlay([(0, Area([1, 2, 3])), (1, Area([1, 2, 3]))]) - stacked = stack_area(areas) + stacked = Area.stack(areas) area1 = Area(([0, 1, 2], [1, 2, 3], [0, 0, 0]), vdims=['y', 'Baseline']) area2 = Area(([0, 1, 2], [2, 4, 6], [1, 2, 3]), vdims=['y', 'Baseline']) self.assertEqual(stacked, NdOverlay([(0, area1), (1, area2)])) -