Access coordinates of drawn geometries

Hi there,
I have a very simple bokey script that enables me to draw geometric shapes interactively in the figure (using the mouse). Also changes of the geometries are possible.

Now I am trying to access the coordinates of the geometries that are drawn in the figure. Can the coordinates of the different geometries be saved using python? The coordinates of different geometries should thereby stay seperable (for example if 2 polygons were drawn, each of them should have a own name with which the corresponding coordinates are saved).

Here is my code so far:

# DRAW POLYGONS:
from bokeh.plotting import figure, output_file, show
from bokeh.models import PolyDrawTool, PolyEditTool,CustomJS,ColumnDataSource


p = figure(x_range=(0, 10), y_range=(0, 10), width=1000, height=600,
           title='Poly Draw Tool')

#p1 = p.patches([[2, 5, 8]], [[2, 8, 2]], line_width=0, alpha=0.4,fill_color='blue')
l1 = p.multi_line([[1, 9]], [[5, 5]], line_width=5, alpha=0.4, color='red')
p2 = p.patches(line_width=2,alpha=0.3,fill_color='orange',line_color='black')
c1 = p.circle([],[],size=10,color='red')

draw_tool_l1 = PolyDrawTool(renderers=[l1])
draw_tool_p1 = PolyDrawTool(renderers=[p2])
edit_tool_p1 = PolyEditTool(renderers=[l1,p2],vertex_renderer=c1)

p.add_tools(draw_tool_p1, draw_tool_l1,edit_tool_p1)
p.toolbar.active_drag = draw_tool_p1

show(p)

I would be very grateful for your help.

Thanks

Absolutely you can. How you do it essentially depends on if you want to go with the bokeh-server/python callback function route, or the javascript based “standalone” CustomJS object route.

In either case, when you instantiate a renderer (for example “p2” in your code is a renderer instance), that renderer is instantiated with a lot of properties (check out dir(p2) in your console), but the most relevant one for you in this case is its “data_source” property. That will access the ColumnDataSource instance that is driving your renderer. That ColumnDataSource instance has a “data” property, which returns a dictionary with the column names as keys and arrays of values for its values. It also has a handy to_df() method on the python side that might be helpful too.

A patches object will have ‘xs’ and ‘ys’ fields which contain each patch geometry’s x and y vertex coords. It’s the same for multilines. That is what you need to access with a callback function and export. Whether that’s a python or JS function is up to you :slight_smile:

Thank you very much for your answer. :slight_smile:

However if I want to use callbacks I have to run the app on a server (also possible: local server) right? I couldn’t get the app to run with a callback the way I posted the code.

You only need a server if you want python executing your callbacks. If you want to go “standalone”/serverless, you need to go the CustomJS route, which involves writing javascript. See my explanation in this thread:

Also, check out the examples here: JavaScript callbacks — Bokeh 2.4.0 Documentation

Make an attempt building off your example above and I’ll do what I can to help.

2 Likes

Thanks for your help once again! However I am a bit desperate for some reasons:

  1. When I am drawing a shape in the browser, no new coodinate lists are generated or at least I cannot find them when I search in the element code that is shown when I open the “inspect” mode in google chrome. However when I plot shapes in the code before starting the app in the browser, coordindate lists with the predefined can be found in the “inspect” mode. I tried to have a look at these lists, in order to know how to access them (listnames), since I have no experience with such things.

  2. I want the callback function to be run when a new polygon was added. However, I have no clue which event name I can use to trigger the function.

  3. As far as I understand the standalone option, it is necessary to export the coordinate lists (in case they are created and I can access them) to my local computer and then access them using whatever tool I want to use. Did I understand that correctly?

Thanks once again and sorry for my incompetence :wink:

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.