PolyEdit#
Download this notebook from GitHub (right-click to download).
Title: PolyEdit#
Description: A linked streams example demonstrating how to use the PolyEdit stream.
Dependencies: Bokeh
Backends: Bokeh
import numpy as np
import holoviews as hv
from holoviews import opts, streams
hv.extension('bokeh')
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:
Show vertices
Double tap an existing patch or multi-line
Add vertex
Double tap an existing vertex to select it, the tool will draw the next point, to add it tap in a new location.
To finish editing and add a point double tap otherwise press the ESC key to cancel.
Move vertex
Drag an existing vertex and let go of the mouse button to release it.
Delete vertex
After selecting one or more vertices press BACKSPACE while the mouse cursor is within the plot area.
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:
np.random.seed(42)
polys = hv.Polygons([hv.Box(*i, spec=np.random.rand()/3)
for i in np.random.rand(10, 2)])
ovals = hv.Polygons([hv.Ellipse(*i, spec=np.random.rand()/3)
for i in np.random.rand(10, 2)])
poly_edit = streams.PolyEdit(source=polys, vertex_style={'color': 'red'}, shared=True)
poly_edit2 = streams.PolyEdit(source=ovals, shared=True)
(polys * ovals).opts(
opts.Polygons(active_tools=['poly_edit'], fill_alpha=0.4, height=400, width=400))
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:
poly_edit.data
{'xs': [array([0.27256464, 0.27256464, 0.4765156 , 0.4765156 , 0.27256464]),
array([0.70874497, 0.70874497, 0.75524292, 0.75524292, 0.70874497]),
array([0.10732787, 0.10732787, 0.20470942, 0.20470942, 0.10732787]),
array([-0.0029767 , -0.0029767 , 0.11914392, 0.11914392, -0.0029767 ]),
array([0.52510335, 0.52510335, 0.67712668, 0.67712668, 0.52510335]),
array([-0.11027817, -0.11027817, 0.15144715, 0.15144715, -0.11027817]),
array([0.79916368, 0.79916368, 0.8657216 , 0.8657216 , 0.79916368]),
array([0.09611923, 0.09611923, 0.26753071, 0.26753071, 0.09611923]),
array([0.20550648, 0.20550648, 0.402978 , 0.402978 , 0.20550648]),
array([0.42420328, 0.42420328, 0.43968675, 0.43968675, 0.42420328])],
'ys': [array([0.84873882, 1.05268979, 1.05268979, 0.84873882, 0.84873882]),
array([0.57540951, 0.62190746, 0.62190746, 0.57540951, 0.57540951]),
array([0.10730375, 0.2046853 , 0.2046853 , 0.10730375, 0.10730375]),
array([0.80511584, 0.92723645, 0.92723645, 0.80511584, 0.80511584]),
array([0.63206091, 0.78408424, 0.78408424, 0.63206091, 0.63206091]),
array([0.83904719, 1.10077251, 1.10077251, 0.83904719, 0.83904719]),
array([0.17906015, 0.24561807, 0.24561807, 0.17906015, 0.17906015]),
array([0.09769877, 0.26911025, 0.26911025, 0.09769877, 0.09769877]),
array([0.42602067, 0.62349219, 0.62349219, 0.42602067, 0.42602067]),
array([0.2834874 , 0.29897088, 0.29897088, 0.2834874 , 0.2834874 ])]}
Alternatively we can use the element
property to get an Element containing the returned data:
poly_edit.element
Download this notebook from GitHub (right-click to download).