holoviz-topics / EarthSim

Tools for working with and visualizing environmental simulations.
https://earthsim.holoviz.org
BSD 3-Clause "New" or "Revised" License
65 stars 21 forks source link

Modifying instantiated annotator vs creating new #293

Closed kcpevey closed 4 years ago

kcpevey commented 5 years ago

Suppose I have an annotator:

sample_poly=dict(
    Longitude = [-10114986, -10123906, -10130333, -10121522, -10129889, -10122959],
    Latitude  = [  3806790,   3812413,   3807530,   3805407,   3798394,   3796693])
sample_points = dict(
    Longitude = [-10131185, -10131943, -10131766, -10131032],
    Latitude  = [  3805587,   3803182,   3801073,   3799778])

annot = GeoAnnotator(polys=[sample_poly], points=sample_points)
annot.panel()

And I draw a few extra points on the drawing. Then, I want to redraw that annotator with my newly drawn points. I could do something like:

annot.polys = annot.poly_stream.element
annot.points = annot.point_stream.element
annot.map_view()

image

But I loose the annotator tools. Why is that? Is this not a recommended approach? Should I just recreate the annotator altogether?

Usecase: I'm rebuilding the Specifying_Meshes.ipynb to work with xmsmesh and also make it a dashboard. So I have an annotator displayed in panel. Then I create a mesh and I want to overlay that on top of the original data and what the user has drawn. Currently, I'm trying to keep the original annotator and modify it. I also will need the ability to clear the old mesh and overlay a new one.

philippjfr commented 5 years ago

This could now be done by declaring polys and points as parameters and adding dependencies. Previously this would have required a dedicated update method.

kcpevey commented 5 years ago

In my annotator class, I have a method to update the points that has a param depends on it such that the map and table are both re-rendered. The method includes

self.points = self.point_stream.element or self.points
            self.point_stream = PointDraw(source=self.points, drag=True, data={}, num_objects=self.num_points,
                                          empty_value=self.default_value)
            projected = gv.project(self.points, projection=ccrs.PlateCarree())
            self.point_table = hv.Table(projected).opts(plot=self.table_opts, style=self.table_style)
            self.point_link = PointTableLink(source=self.points, target=self.point_table)

This approach works for updating the map (which is using points and point_stream) but then if I try to access the point_table which HAS been re-rendered, I get a python error and a js error:

Python failed with the following traceback: 
/Users/rdchlkcp/miniconda3/envs/esw0415/lib/python3.6/site-packages/param/parameterized.py inner L1146
/Users/rdchlkcp/miniconda3/envs/esw0415/lib/python3.6/site-packages/param/parameterized.py set_param L2491
/Users/rdchlkcp/miniconda3/envs/esw0415/lib/python3.6/site-packages/param/parameterized.py set_param L1292
/Users/rdchlkcp/miniconda3/envs/esw0415/lib/python3.6/site-packages/param/parameterized.py _batch_call_watchers L1407
/Users/rdchlkcp/miniconda3/envs/esw0415/lib/python3.6/site-packages/panel/viewable.py param_change L599
/Users/rdchlkcp/miniconda3/envs/esw0415/lib/python3.6/site-packages/panel/layout.py _update_model L430
/Users/rdchlkcp/miniconda3/envs/esw0415/lib/python3.6/site-packages/panel/layout.py _update_model L69
/Users/rdchlkcp/miniconda3/envs/esw0415/lib/python3.6/site-packages/panel/viewable.py _preprocess L255
/Users/rdchlkcp/miniconda3/envs/esw0415/lib/python3.6/site-packages/panel/pane/holoviews.py find_links L323
/Users/rdchlkcp/miniconda3/envs/esw0415/lib/python3.6/site-packages/holoviews/plotting/bokeh/callbacks.py __init__ L1324
    AttributeError: 'bool' object has no attribute 'all'
index.js:220 Error: Cannot send
    at CommHandler.send (comm.js:111)
    at HVJSExec.push.cue4.HVJSExec._disposePlot (renderer.js:197)
    at HVJSExec.push.cue4.HVJSExec.dispose (renderer.js:220)
    at PanelLayout.push.HWBy.PanelLayout.dispose (panellayout.js:51)
    at Panel.push.FmDU.Widget.dispose (widget.js:73)
    at OutputArea._clear (widget.js:257)
    at OutputArea.onModelChanged (widget.js:223)
    at invokeSlot (index.js:475)
    at Object.emit (index.js:433)
    at Signal.push.qUp9.Signal.emit (index.js:106)

And when I access point_stream, it doesn't see any changes made to the point_table UI.

I think I'm not applying the update correctly since I don't seem to be doing what you recommended, but I don't understand how else I could do it without rebuilding the whole annotator. polys and points are already parameters. The param depends has to be applied to a method, presumably to the view methods.

Can you explain your answer in more detail? Or will this require some time on Thursday?

kcpevey commented 5 years ago

adding an update method to the existing earthsim point and poly classes should be sufficient instead of @philippjfr trying to sort through my code

kcpevey commented 5 years ago

I'm trying to utilize the updated annotators. I'm getting the same basic error as above:

Python failed with the following traceback: 
/Users/rdchlkcp/miniconda3/envs/esw0626/lib/python3.6/site-packages/panel/param.py update_pane L587
/Users/rdchlkcp/miniconda3/envs/esw0626/lib/python3.6/site-packages/panel/param.py _update_pane L550
/Users/rdchlkcp/miniconda3/envs/esw0626/lib/python3.6/site-packages/param/parameterized.py _f L296
/Users/rdchlkcp/miniconda3/envs/esw0626/lib/python3.6/site-packages/param/parameterized.py __set__ L861
/Users/rdchlkcp/miniconda3/envs/esw0626/lib/python3.6/site-packages/param/parameterized.py _call_watcher L1454
/Users/rdchlkcp/miniconda3/envs/esw0626/lib/python3.6/site-packages/panel/pane/base.py _update_pane L128
/Users/rdchlkcp/miniconda3/envs/esw0626/lib/python3.6/site-packages/panel/pane/base.py _update_object L122
/Users/rdchlkcp/miniconda3/envs/esw0626/lib/python3.6/site-packages/panel/viewable.py _preprocess L255
/Users/rdchlkcp/miniconda3/envs/esw0626/lib/python3.6/site-packages/panel/pane/holoviews.py find_links L323
/Users/rdchlkcp/miniconda3/envs/esw0626/lib/python3.6/site-packages/holoviews/plotting/bokeh/callbacks.py __init__ L1315
    AttributeError: 'bool' object has no attribute 'all'

But I'm getting it from different parts of my panel dashboard. I think I remember seeing this when the panel widgets were disconnected from the param.depends that they were originally linked to. This might just be an issue with my dashboard, but I can't tell from that error.

@philippjfr we should discuss this on Monday as well

kcpevey commented 4 years ago

I don't know where that error was coming from, but I inadvertently fixed it... Closing.