{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "#### **Title**: PolyEdit\n", "\n", "**Description**: A linked streams example demonstrating how to use the PolyEdit stream.\n", "\n", "**Dependencies**: Bokeh\n", "\n", "**Backends**: [Bokeh](./PolyEdit.ipynb)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import numpy as np\n", "import holoviews as hv\n", "from holoviews import opts, streams\n", "\n", "hv.extension('bokeh')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The ``PolyEdit`` stream adds a bokeh tool to the source plot, which allows drawing, dragging and deleting vertices on polygons and making the drawn data available to Python. The tool supports the following actions:\n", "\n", "**Show vertices**\n", "\n", " Double tap an existing patch or multi-line\n", "\n", "**Add vertex**\n", "\n", " Double tap an existing vertex to select it, the tool will draw the next point, to add it tap in a new location.\n", " To finish editing and add a point double tap otherwise press the ESC key to cancel.\n", "\n", "**Move vertex**\n", "\n", " Drag an existing vertex and let go of the mouse button to release it.\n", "\n", "**Delete vertex**\n", "\n", " After selecting one or more vertices press BACKSPACE while the mouse cursor is within the plot area.\n", " \n", "As a simple example we will draw a number of boxes and ellipses by displaying them using a ``Polygons`` element and then link that element to two ``PolyEdit`` streams. Enabling the ``shared`` option allows editing multiple ``Polygons``/``Paths`` with the same tool. You may also supply a ``vertex_style`` dictionary defining the visual attributes of the vertices once you double tapped a polygon:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "np.random.seed(42)\n", "polys = hv.Polygons([hv.Box(*i, spec=np.random.rand()/3)\n", " for i in np.random.rand(10, 2)])\n", "ovals = hv.Polygons([hv.Ellipse(*i, spec=np.random.rand()/3)\n", " for i in np.random.rand(10, 2)])\n", "poly_edit = streams.PolyEdit(source=polys, vertex_style={'color': 'red'}, shared=True)\n", "poly_edit2 = streams.PolyEdit(source=ovals, shared=True)\n", "\n", "(polys * ovals).opts(\n", " opts.Polygons(active_tools=['poly_edit'], fill_alpha=0.4, height=400, width=400))" ] }, { "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": [ "poly_edit.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": [ "poly_edit.element" ] } ], "metadata": { "language_info": { "name": "python", "pygments_lexer": "ipython3" } }, "nbformat": 4, "nbformat_minor": 4 }