Closed kcpevey closed 5 years ago
This problem is bigger than I had originally thought. It has nothing to do with wmts_widget
. I pulled the non-pipeline code out of viewResults without changing anything significant and when its pulled out, it will run and produce the panel it's supposed to.
This is the full viewResults:
class viewResults(param.Parameterized):
# objects inherited from the previous page
load_sim_widget = param.ClassSelector(class_=model.load_adh_simulation)
att_widget = param.ClassSelector(class_=model.attributes)
proj_widget = param.ClassSelector(class_=projections.projections)
# objects passed in from the previous page output
adh_viz = param.ClassSelector(class_=model.adhViz)
adh_model = param.ClassSelector(class_=adhModel)
# objects carried in
wmts_widget = param.ClassSelector(class_=display_opts.wmts)
def __init__(self, wmts_widget, **params):
super(viewResults, self).__init__(wmts_widget=wmts_widget, **params)
# what to pass out of this page
@param.output()
def output(self):
pass
# how to build this page
def panel(self):
# return pn.Pane(self.adh_viz.view_animation('dep'))
# return pn.Pane(self.run())
# return pn.Pane(wmts_widget)
return self.run()
# what to do with the stuff in this page
def run(self):
# pass
# get the coorinate system
coord_sys = self.proj_widget.get_crs()
if self.adh_viz is None:
# instantiate adhviz object
adh_viz = model.adhViz(projection=coord_sys)
# instantiate adhModel object
adh_model = adhModel(d_version=5.0)
# load the data from the sim widget
self.adh_viz, self.adh_model = self.load_sim_widget.run(viz_obj=adh_viz, mod=adh_model,
att_widget=self.att_widget, proj=coord_sys)
# hard coded !!!!!!
fpath = os.path.join(self.load_sim_widget.adh_directory, self.load_sim_widget.adh_root_filename + '_dep.dat')
dfs = read_mesh2d(fpath)
internal_names = list(dfs[0])
print('internal names {}'.format(internal_names))
label='Depth'
# Create a parameterized class to select between ERROR and Depth
results = parameters(display_result=param.ObjectSelector(default=internal_names[0], objects=internal_names))
# Define callback which returns TriMesh for specific time and ERROR/Depth
def time_mesh(time, display_result):
color_ramp_threshold = display_range.color_range[0]
df = dfs[time].copy()
df[df[display_result] < color_ramp_threshold] = np.nan
depth_points = self.adh_viz.mesh_points.add_dimension(display_result, 0, df.values, vdim=True)
return gv.TriMesh((self.adh_viz.tris, depth_points), label=display_result, crs=ccrs.GOOGLE_MERCATOR)
# Declare DynamicMap which varies by time and is linked to results class
meshes = hv.DynamicMap(time_mesh, kdims='Time', streams=[Params(results)]).redim.values(Time=sorted(dfs.keys()))
# Define function which applies colormap and color_range
def apply_opts(obj, colormap, color_range):
return obj.options(cmap=colormap).redim.range(**{obj.vdims[0].name: color_range})
viz = PolyAndPointAnnotator(path_type=gv.Path,
crs=ccrs.GOOGLE_MERCATOR,
point_columns=['depth_elevation'],
poly_columns=['name']
)
# Apply the colormap and color range dynamically
dynamic = hv.util.Dynamic(rasterize(meshes), operation=apply_opts, streams=[Params(cmap_opts), Params(display_range)]
).options(colorbar=True) * self.wmts_widget.view() * viz.polys * viz.points
# Display everything as a Panel
hv_panel = pn.panel(dynamic, widget_type='scrubber')
map_pane = pn.Column(hv_panel[0], hv_panel[1])
disp_tab = pn.Column(self.wmts_widget,
mesh_opts(name=''),
cmap_opts,
display_range,
results,
name='Display')
output_tab = pn.Pane(self.proj_widget, name='Output')
tool_pane = pn.Tabs(("unused", disp_tab),
("unused", output_tab))
return pn.Row(map_pane, tool_pane)
When I try to run it inside of the pipeline, I'm getting the error above in the java console, plus I was able to get a full traceback:
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
~/miniconda3/envs/earthsim/lib/python3.6/site-packages/IPython/core/formatters.py in __call__(self, obj, include, exclude)
968
969 if method is not None:
--> 970 return method(include=include, exclude=exclude)
971 return None
972 else:
~/ers/gitHub/panel/master/panel/panel/viewable.py in _repr_mimebundle_(self, include, exclude)
107 doc = Document()
108 comm = self._comm_manager.get_server_comm()
--> 109 model = self._get_root(doc, comm)
110 Viewable._views[model.ref['id']] = (self, model)
111 return render_mimebundle(model, doc, comm)
~/ers/gitHub/panel/master/panel/panel/viewable.py in _get_root(self, doc, comm)
84 Optional pyviz_comms when working in notebook
85 """
---> 86 root = self._get_model(doc, comm=comm)
87 self._preprocess(root)
88 return root
~/ers/gitHub/panel/master/panel/panel/layout.py in _get_model(self, doc, root, parent, comm)
130 model = self._bokeh_model()
131 root = model if root is None else root
--> 132 objects = self._get_objects(model, [], doc, root, comm)
133
134 # HACK ALERT: Insert Spacer if last item in Column has no height
~/ers/gitHub/panel/master/panel/panel/layout.py in _get_objects(self, model, old_objects, doc, root, comm)
123 child = pane._models[root.ref['id']]
124 else:
--> 125 child = pane._get_model(doc, root, model, comm)
126 new_models.append(child)
127 return new_models
~/ers/gitHub/panel/master/panel/panel/layout.py in _get_model(self, doc, root, parent, comm)
130 model = self._bokeh_model()
131 root = model if root is None else root
--> 132 objects = self._get_objects(model, [], doc, root, comm)
133
134 # HACK ALERT: Insert Spacer if last item in Column has no height
~/ers/gitHub/panel/master/panel/panel/layout.py in _get_objects(self, model, old_objects, doc, root, comm)
123 child = pane._models[root.ref['id']]
124 else:
--> 125 child = pane._get_model(doc, root, model, comm)
126 new_models.append(child)
127 return new_models
~/ers/gitHub/panel/master/panel/panel/holoviews.py in _get_model(self, doc, root, parent, comm)
112 """
113 ref = root.ref['id']
--> 114 plot = self._render(doc, comm, root)
115 child_pane = Pane(plot.state, _temporary=True)
116 model = child_pane._get_model(doc, root, parent, comm)
~/ers/gitHub/panel/master/panel/panel/holoviews.py in _render(self, doc, comm, root)
98 if comm:
99 kwargs['comm'] = comm
--> 100 plot = renderer.get_plot(self.object, **kwargs)
101 ref = root.ref['id']
102 if ref in self._plots:
~/ers/gitHub/holoviews/master/holoviews/holoviews/plotting/bokeh/renderer.py in get_plot(self_or_cls, obj, doc, renderer, **kwargs)
160 curdoc().theme = self_or_cls.theme
161 doc.theme = self_or_cls.theme
--> 162 plot = super(BokehRenderer, self_or_cls).get_plot(obj, renderer, **kwargs)
163 plot.document = doc
164 return plot
~/ers/gitHub/holoviews/master/holoviews/holoviews/plotting/renderer.py in get_plot(self_or_cls, obj, renderer, **kwargs)
201 init_key = tuple(v if d is None else d for v, d in
202 zip(plot.keys[0], defaults))
--> 203 plot.update(init_key)
204 else:
205 plot = obj
~/ers/gitHub/holoviews/master/holoviews/holoviews/plotting/plot.py in update(self, key)
532 def update(self, key):
533 if len(self) == 1 and ((key == 0) or (key == self.keys[0])) and not self.drawn:
--> 534 return self.initialize_plot()
535 item = self.__getitem__(key)
536 self.traverse(lambda x: setattr(x, '_updated', True))
~/ers/gitHub/geoviews/master/geoviews/geoviews/plotting/bokeh/plot.py in initialize_plot(self, ranges, plot, plots, source)
86 def initialize_plot(self, ranges=None, plot=None, plots=None, source=None):
87 opts = {} if isinstance(self, HvOverlayPlot) else {'source': source}
---> 88 fig = super(GeoPlot, self).initialize_plot(ranges, plot, plots, **opts)
89 if self.geographic and self.show_bounds and not self.overlaid:
90 from . import GeoShapePlot
~/ers/gitHub/holoviews/master/holoviews/holoviews/plotting/bokeh/element.py in initialize_plot(self, ranges, plot, plots)
1597
1598 if self.top_level:
-> 1599 self.init_links()
1600
1601 self._execute_hooks(element)
~/ers/gitHub/holoviews/master/holoviews/holoviews/plotting/bokeh/plot.py in init_links(self)
402 for link, src_plot, tgt_plot in links:
403 cb = Link._callbacks['bokeh'][type(link)]
--> 404 callbacks.append(cb(self.root, link, src_plot, tgt_plot))
405 return callbacks
406
~/ers/gitHub/holoviews/master/holoviews/holoviews/plotting/bokeh/callbacks.py in __init__(self, root_model, link, source_plot, target_plot)
1226 def __init__(self, root_model, link, source_plot, target_plot):
1227 src_cds = source_plot.handles['source']
-> 1228 tgt_cds = target_plot.handles['source']
1229 src_len = [len(v) for v in src_cds.data.values()]
1230 tgt_len = [len(v) for v in tgt_cds.data.values()]
AttributeError: 'NoneType' object has no attribute 'handles'
And I've traced the source of that error back to the visualization of dynamic
(not the instantiation of it).
I'm fairly certain its a bug in panel or pipeline, but this is as far as I can go. Hope this helps!
More info: The panel from self.run() generates successfully (in memory) without issue. The error above is coming from whatever happens to the panel AFTER it gets returned from the method def panel(self): return self.run()
Looks like an issue in setting up the links, will investigate.
@philippjfr Did you find anything?
I haven't been able to reproduce anything yet no. Is there a simpler example where you see the issue?
I don't have one, but I guess I could adapt #254 as a simpler example?
I'm also happy to demo my full code during another call if that helps
Let's both try to see if we can reproduce it in a simpler example and fall back to that if this doesn't work.
Got it.
The easiest way to make progress is probably for you to go to line 1226 in this file:
~/ers/gitHub/holoviews/master/holoviews/holoviews/plotting/bokeh/callbacks.py
and add print(link)
so we can see which link is actually breaking.
Nevermind, I see it's the DataLink, so I'll investigate that.
Having no luck reproducing the issue unfortunately.
Ok. I'll try and come up with a simplified example.
And also add print(link)
like you suggested
Thank you, if you can't reproduce it should we schedule a 1:1 meeting tomorrow?
That would be helpful. I'll be available after our usual meeting.
I stripped my code down and moved a few things into the notebook to make a self-contained example. This is giving the Constant parameter 'name' cannot be modified
error, but I have to head out now and I haven't had time to finish digging though it. If its helpful for you, great. If not, I'll keep working on this in the morning.
This has been resolved. I believe it had to do with passing the instantiated widgets into the class instantiation and/or properly setting up the init to handle the incoming classes.
@philippjfr I'm adding instantiated widgets to the second page/class similar to what we did with the first:
But this causes the error:
However, I can't figure out where this error is coming from since nothing I can touch has any effect. My instantiation:
wmts_widget = display_opts.wmts()
isn't the source of the error (and would happily acceptname=''
).I can instantiate and visualize
pn.Pane(wmts_widget)
. And I get the same error if I try to make a second instance of one of the widgets from the first page (thereby proving it has nothing to do with thewmts_widget
class.Also, I'm creating the stages using the same approach from the first page:
If I just remove all the
wmts_widget
references, this code works without errors.