{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "#### **Title**: PointDraw Stream\n", "\n", "**Description**: A linked streams example demonstrating how to use the PointDraw stream.\n", "\n", "**Dependencies**: Bokeh\n", " \n", "**Backends**: [Bokeh](./PointDraw.ipynb)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import holoviews as hv\n", "from holoviews import opts, streams\n", "from holoviews.plotting.links import DataLink\n", "\n", "hv.extension('bokeh')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The ``PointDraw`` stream adds a bokeh tool to the source plot, which allows drawing, dragging and deleting points and making the drawn data available to Python. The tool supports the following actions:\n", "\n", "**Add point**\n", "\n", " Tap anywhere on the plot\n", "\n", "**Move point**\n", " \n", " Tap and drag an existing point, the point will be dropped once you let go of the mouse button.\n", "\n", "**Delete point**\n", "\n", " Tap a point to select it then press BACKSPACE or DELETE key while the mouse is within the plot area." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "As a simple example we will create a ``PointDraw`` stream and attach it to a set of ``Points`` with a color dimension. By using a `DataLink` we can additionally link the `Points` to a Table containing the same data.\n", "\n", "We can now add drag and delete points, see the x/y position change in the table and edit the a color for each point in the table. Additionally the ``empty_value`` parameter on the ``PointDraw`` stream lets us define the value that will be inserted on columns other than the x/y position, which we can use here to set new points to 'black'. Finally we can limit the number of points using the ``num_objects`` option, ensuring that once the limit is reached the oldest point is dropped." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "data = ([0, 0.5, 1], [0, 0.5, 0], ['red', 'green', 'blue'])\n", "points = hv.Points(data, vdims='color').redim.range(x=(-.1, 1.1), y=(-.1, 1.1))\n", "point_stream = streams.PointDraw(data=points.columns(), num_objects=10, source=points, empty_value='black')\n", "table = hv.Table(points, ['x', 'y'], 'color')\n", "DataLink(points, table)\n", "\n", "(points + table).opts(\n", " opts.Layout(merge_tools=False),\n", " opts.Points(active_tools=['point_draw'], color='color', height=400,\n", " size=10, tools=['hover'], width=400),\n", " opts.Table(editable=True))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Whenever the data source is edited the data is synced with Python, both in the notebook and when deployed on the bokeh server. The data is made available as a dictionary of columns:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "point_stream.data" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Alternatively we can use the ``element`` property to get an Element containing the returned data:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "point_stream.element" ] } ], "metadata": { "language_info": { "name": "python", "pygments_lexer": "ipython3" } }, "nbformat": 4, "nbformat_minor": 4 }