holoviz / holoviews

With Holoviews, your data visualizes itself.
https://holoviews.org
BSD 3-Clause "New" or "Revised" License
2.66k stars 396 forks source link

holoviews.streams.PolyDraw errors when geoviews is imported #4789

Open drclanc-oss opened 3 years ago

drclanc-oss commented 3 years ago

ALL software version info

OS: Windows 10 Python: 3.8.0 Holoviews: 1.14.0 Geoviews: 1.8.1 Bokeh: 2.2.3

Description of expected behavior and the observed behavior

Expected: I expect that holoviews.streams.PolyDraw will work regardless of which other Python packages I import into my Jupyter Notebook. Observed: I can create a plot which includes PolyDraw and it works fine. When I run the exact same code after importing geoviews into my Jupyter Notebook I get an error.

Complete, minimal, self-contained example code that reproduces the issue

I took this example from the docs at https://holoviews.org/reference/streams/bokeh/PolyDraw.html . Run it once as is to see that everything works. Then uncomment the import geoviews and run it again to see the error.

import holoviews as hv
#import geoviews as gv
from holoviews import opts, streams

hv.extension('bokeh')

path = hv.Path([[(1, 5), (9, 5)]])
poly = hv.Polygons([[(2, 2), (5, 8), (8, 2)]])
path_stream = streams.PolyDraw(source=path, drag=True, show_vertices=True)
poly_stream = streams.PolyDraw(source=poly, drag=True, num_objects=4,
                               show_vertices=True, styles={
                                   'fill_color': ['red', 'green', 'blue']
                               })

(path * poly).opts(
    opts.Path(color='red', height=400, line_width=5, width=400),
    opts.Polygons(fill_alpha=0.3, active_tools=['poly_draw']))

Stack traceback and/or browser JavaScript console output


TypeError Traceback (most recent call last) ~\AppData\Roaming\Python\Python38\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:

~\Miniconda3\envs\GeoIQ2\lib\site-packages\holoviews\core\dimension.py in _reprmimebundle(self, include, exclude) 1314 combined and returned. 1315 """ -> 1316 return Store.render(self) 1317 1318

~\Miniconda3\envs\GeoIQ2\lib\site-packages\holoviews\core\options.py in render(cls, obj) 1403 data, metadata = {}, {} 1404 for hook in hooks: -> 1405 ret = hook(obj) 1406 if ret is None: 1407 continue

~\Miniconda3\envs\GeoIQ2\lib\site-packages\holoviews\ipython\display_hooks.py in pprint_display(obj) 280 if not ip.display_formatter.formatters['text/plain'].pprint: 281 return None --> 282 return display(obj, raw_output=True) 283 284

~\Miniconda3\envs\GeoIQ2\lib\site-packages\holoviews\ipython\display_hooks.py in display(obj, raw_output, **kwargs) 250 elif isinstance(obj, (CompositeOverlay, ViewableElement)): 251 with option_state(obj): --> 252 output = element_display(obj) 253 elif isinstance(obj, (Layout, NdLayout, AdjointLayout)): 254 with option_state(obj):

~\Miniconda3\envs\GeoIQ2\lib\site-packages\holoviews\ipython\display_hooks.py in wrapped(element) 144 try: 145 max_frames = OutputSettings.options['max_frames'] --> 146 mimebundle = fn(element, max_frames=max_frames) 147 if mimebundle is None: 148 return {}, {}

~\Miniconda3\envs\GeoIQ2\lib\site-packages\holoviews\ipython\display_hooks.py in element_display(element, max_frames) 190 return None 191 --> 192 return render(element) 193 194

~\Miniconda3\envs\GeoIQ2\lib\site-packages\holoviews\ipython\display_hooks.py in render(obj, kwargs) 66 renderer = renderer.instance(fig='png') 67 ---> 68 return renderer.components(obj, kwargs) 69 70

~\Miniconda3\envs\GeoIQ2\lib\site-packages\holoviews\plotting\renderer.py in components(self, obj, fmt, comm, **kwargs) 408 doc = Document() 409 with config.set(embed=embed): --> 410 model = plot.layout._render_model(doc, comm) 411 if embed: 412 return render_model(model, comm)

~\Miniconda3\envs\GeoIQ2\lib\site-packages\panel\viewable.py in _render_model(self, doc, comm) 422 if comm is None: 423 comm = state._comm_manager.get_server_comm() --> 424 model = self.get_root(doc, comm) 425 426 if config.embed:

~\Miniconda3\envs\GeoIQ2\lib\site-packages\panel\viewable.py in get_root(self, doc, comm, preprocess) 480 """ 481 doc = init_doc(doc) --> 482 root = self._get_model(doc, comm=comm) 483 if preprocess: 484 self._preprocess(root)

~\Miniconda3\envs\GeoIQ2\lib\site-packages\panel\layout\base.py in _get_model(self, doc, root, parent, comm) 110 if root is None: 111 root = model --> 112 objects = self._get_objects(model, [], doc, root, comm) 113 props = dict(self._init_properties(), objects=objects) 114 model.update(**self._process_param_change(props))

~\Miniconda3\envs\GeoIQ2\lib\site-packages\panel\layout\base.py in _get_objects(self, model, old_objects, doc, root, comm) 100 else: 101 try: --> 102 child = pane._get_model(doc, root, model, comm) 103 except RerenderError: 104 return self._get_objects(model, current_objects[:i], doc, root, comm)

~\Miniconda3\envs\GeoIQ2\lib\site-packages\panel\pane\holoviews.py in _get_model(self, doc, root, parent, comm) 239 plot = self.object 240 else: --> 241 plot = self._render(doc, comm, root) 242 243 plot.pane = self

~\Miniconda3\envs\GeoIQ2\lib\site-packages\panel\pane\holoviews.py in _render(self, doc, comm, root) 304 kwargs['comm'] = comm 305 --> 306 return renderer.get_plot(self.object, **kwargs) 307 308 def _cleanup(self, root):

~\Miniconda3\envs\GeoIQ2\lib\site-packages\holoviews\plotting\bokeh\renderer.py in get_plot(self_or_cls, obj, doc, renderer, kwargs) 71 combining the bokeh model with another plot. 72 """ ---> 73 plot = super(BokehRenderer, self_or_cls).get_plot(obj, doc, renderer, kwargs) 74 if plot.document is None: 75 plot.document = Document() if self_or_cls.notebook_context else curdoc()

~\Miniconda3\envs\GeoIQ2\lib\site-packages\holoviews\plotting\renderer.py in get_plot(self_or_cls, obj, doc, renderer, comm, **kwargs) 241 init_key = tuple(v if d is None else d for v, d in 242 zip(plot.keys[0], defaults)) --> 243 plot.update(init_key) 244 else: 245 plot = obj

~\Miniconda3\envs\GeoIQ2\lib\site-packages\holoviews\plotting\plot.py in update(self, key) 978 def update(self, key): 979 if len(self) == 1 and ((key == 0) or (key == self.keys[0])) and not self.drawn: --> 980 return self.initialize_plot() 981 item = self.getitem(key) 982 self.traverse(lambda x: setattr(x, '_updated', True))

~\Miniconda3\envs\GeoIQ2\lib\site-packages\geoviews\plotting\bokeh\plot.py in initialize_plot(self, ranges, plot, plots, source) 107 def initialize_plot(self, ranges=None, plot=None, plots=None, source=None): 108 opts = {} if isinstance(self, HvOverlayPlot) else {'source': source} --> 109 fig = super(GeoPlot, self).initialize_plot(ranges, plot, plots, **opts) 110 if self.geographic and self.show_bounds and not self.overlaid: 111 from . import GeoShapePlot

~\Miniconda3\envs\GeoIQ2\lib\site-packages\holoviews\plotting\bokeh\element.py in initialize_plot(self, ranges, plot, plots) 2318 if self.tabs: 2319 subplot.overlaid = False -> 2320 child = subplot.initialize_plot(ranges, plot, plots) 2321 if isinstance(element, CompositeOverlay): 2322 # Ensure that all subplots are in the same state

~\Miniconda3\envs\GeoIQ2\lib\site-packages\holoviews\plotting\bokeh\element.py in initialize_plot(self, ranges, plot, plots, source) 1390 1391 for cb in self.callbacks: -> 1392 cb.initialize() 1393 1394 if self.top_level:

~\Miniconda3\envs\GeoIQ2\lib\site-packages\holoviews\plotting\bokeh\callbacks.py in initialize(self, plot_id) 1357 ) 1358 plot.state.tools.append(poly_tool) -> 1359 self._update_cds_vdims(cds.data) 1360 super(PolyDrawCallback, self).initialize(plot_id) 1361

TypeError: _update_cds_vdims() takes 1 positional argument but 2 were given

Screenshots or screencasts of the bug in action

Works fine when import geoviews is commented out: image

Running the same notebook (kernel -> restart & run all) but this time importing geoviews causes an error. image

kcpevey commented 3 years ago

I hit this today. I'm able to reproduce the above code. When geoviews is imported it takes precedence some of the operations that holoviews usually does.

@philippjfr any ideas for a workaround?