Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Disable hover on errorbars plot #721

Merged
merged 3 commits into from
Mar 31, 2022
Merged

Disable hover on errorbars plot #721

merged 3 commits into from
Mar 31, 2022

Conversation

maximlt
Copy link
Member

@maximlt maximlt commented Mar 25, 2022

Fixes issues seen when recently building the dev docs. I don't know why this raised an error while it used to run fine, Bokeh has become more strict in some way?

@maximlt maximlt closed this Mar 25, 2022
@maximlt maximlt reopened this Mar 25, 2022
@maximlt
Copy link
Member Author

maximlt commented Mar 30, 2022

@jlstevens could you please review this PR? We need a fix for this issue (described more in details below) that is currently breaking the build of a few pages of the site (this one for example: https://pyviz-dev.github.io/hvplot/reference/pandas/errorbars.html#pandas-gallery-errorbars).

Two runs failed, one on macos & python 3.7 that is expected since there's currently an issue with fiona/pyproj on conda-forge (I'm tracking that), and one on Windows & Python 3.7 that just timed out but ran fine after a previous commit (https://github.com/holoviz/hvplot/runs/5696022365?check_suite_focus=true).

Basically it seems that no error bars plot can be rendered with hvplot. A simple example to reproduce is:

import hvplot.pandas  # noqa
from bokeh.sampledata import perceptions

data = perceptions.numberly.describe().transpose().sort_values('mean')
data.hvplot.scatter(y='mean', ylabel='amount') * data.hvplot.errorbars(y='mean', yerr1='std')

which generates this traceback:

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
File /usr/share/miniconda/envs/test-environment/lib/python3.8/site-packages/IPython/core/formatters.py:973, in MimeBundleFormatter.__call__(self, obj, include, exclude)
    970     method = get_real_method(obj, self.print_method)
    972     if method is not None:
--> 973         return method(include=include, exclude=exclude)
    974     return None
    975 else:

File /usr/share/miniconda/envs/test-environment/lib/python3.8/site-packages/holoviews/core/dimension.py:1316, in Dimensioned._repr_mimebundle_(self, include, exclude)
   1309 def _repr_mimebundle_(self, include=None, exclude=None):
   1310     """
   1311     Resolves the class hierarchy for the class rendering the
   1312     object using any display hooks registered on Store.display
   1313     hooks.  The output of all registered display_hooks is then
   1314     combined and returned.
   1315     """
-> 1316     return Store.render(self)

File /usr/share/miniconda/envs/test-environment/lib/python3.8/site-packages/holoviews/core/options.py:1405, in Store.render(cls, obj)
   1403 data, metadata = {}, {}
   1404 for hook in hooks:
-> 1405     ret = hook(obj)
   1406     if ret is None:
   1407         continue

File /usr/share/miniconda/envs/test-environment/lib/python3.8/site-packages/holoviews/ipython/display_hooks.py:282, in pprint_display(obj)
    280 if not ip.display_formatter.formatters['text/plain'].pprint:
    281     return None
--> 282 return display(obj, raw_output=True)

File /usr/share/miniconda/envs/test-environment/lib/python3.8/site-packages/holoviews/ipython/display_hooks.py:252, 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):

File /usr/share/miniconda/envs/test-environment/lib/python3.8/site-packages/holoviews/ipython/display_hooks.py:146, in display_hook.<locals>.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 {}, {}

File /usr/share/miniconda/envs/test-environment/lib/python3.8/site-packages/holoviews/ipython/display_hooks.py:192, in element_display(element, max_frames)
    189 if type(element) not in Store.registry[backend]:
    190     return None
--> 192 return render(element)

File /usr/share/miniconda/envs/test-environment/lib/python3.8/site-packages/holoviews/ipython/display_hooks.py:68, in render(obj, **kwargs)
     65 if renderer.fig == 'pdf':
     66     renderer = renderer.instance(fig='png')
---> 68 return renderer.components(obj, **kwargs)

File /usr/share/miniconda/envs/test-environment/lib/python3.8/site-packages/holoviews/plotting/renderer.py:410, in Renderer.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)

File /usr/share/miniconda/envs/test-environment/lib/python3.8/site-packages/panel/viewable.py:460, in Renderable._render_model(self, doc, comm)
    458 if comm is None:
    459     comm = state._comm_manager.get_server_comm()
--> 460 model = self.get_root(doc, comm)
    462 if config.embed:
    463     embed_state(self, model, doc,
    464                 json=config.embed_json,
    465                 json_prefix=config.embed_json_prefix,
    466                 save_path=config.embed_save_path,
    467                 load_path=config.embed_load_path,
    468                 progress=False)

File /usr/share/miniconda/envs/test-environment/lib/python3.8/site-packages/panel/viewable.py:518, in Renderable.get_root(self, doc, comm, preprocess)
    501 """
    502 Returns the root model and applies pre-processing hooks
    503 
   (...)
    515 Returns the bokeh model corresponding to this panel object
    516 """
    517 doc = init_doc(doc)
--> 518 root = self._get_model(doc, comm=comm)
    519 if preprocess:
    520     self._preprocess(root)

File /usr/share/miniconda/envs/test-environment/lib/python3.8/site-packages/panel/layout/base.py:122, in Panel._get_model(self, doc, root, parent, comm)
    120 if root is None:
    121     root = model
--> 122 objects = self._get_objects(model, [], doc, root, comm)
    123 props = dict(self._init_params(), objects=objects)
    124 model.update(**self._process_param_change(props))

File /usr/share/miniconda/envs/test-environment/lib/python3.8/site-packages/panel/layout/base.py:112, in Panel._get_objects(self, model, old_objects, doc, root, comm)
    110 else:
    111     try:
--> 112         child = pane._get_model(doc, root, model, comm)
    113     except RerenderError:
    114         return self._get_objects(model, current_objects[:i], doc, root, comm)

File /usr/share/miniconda/envs/test-environment/lib/python3.8/site-packages/panel/pane/holoviews.py:239, in HoloViews._get_model(self, doc, root, parent, comm)
    237     plot = self.object
    238 else:
--> 239     plot = self._render(doc, comm, root)
    241 plot.pane = self
    242 backend = plot.renderer.backend

File /usr/share/miniconda/envs/test-environment/lib/python3.8/site-packages/panel/pane/holoviews.py:312, in HoloViews._render(self, doc, comm, root)
    309     if comm:
    310         kwargs['comm'] = comm
--> 312 return renderer.get_plot(self.object, **kwargs)

File /usr/share/miniconda/envs/test-environment/lib/python3.8/site-packages/holoviews/plotting/bokeh/renderer.py:73, in BokehRenderer.get_plot(self_or_cls, obj, doc, renderer, **kwargs)
     66 @bothmethod
     67 def get_plot(self_or_cls, obj, doc=None, renderer=None, **kwargs):
     68     """
     69     Given a HoloViews Viewable return a corresponding plot instance.
     70     Allows supplying a document attach the plot to, useful when
     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()

File /usr/share/miniconda/envs/test-environment/lib/python3.8/site-packages/holoviews/plotting/renderer.py:243, in Renderer.get_plot(self_or_cls, obj, doc, renderer, comm, **kwargs)
    240     defaults = [kd.default for kd in plot.dimensions]
    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

File /usr/share/miniconda/envs/test-environment/lib/python3.8/site-packages/holoviews/plotting/plot.py:991, in DimensionedPlot.update(self, key)
    989 def update(self, key):
    990     if len(self) == 1 and ((key == 0) or (key == self.keys[0])) and not self.drawn:
--> 991         return self.initialize_plot()
    992     item = self.__getitem__(key)
    993     self.traverse(lambda x: setattr(x, '_updated', True))

File /usr/share/miniconda/envs/test-environment/lib/python3.8/site-packages/holoviews/plotting/bokeh/element.py:2361, in OverlayPlot.initialize_plot(self, ranges, plot, plots)
   2359 if self.tabs:
   2360     subplot.overlaid = False
-> 2361 child = subplot.initialize_plot(ranges, plot, plots)
   2362 if isinstance(element, CompositeOverlay):
   2363     # Ensure that all subplots are in the same state
   2364     frame = element.get(key, None)

File /usr/share/miniconda/envs/test-environment/lib/python3.8/site-packages/holoviews/plotting/bokeh/element.py:1418, in ElementPlot.initialize_plot(self, ranges, plot, plots, source)
   1415     self.handles['y_range'] = plot.y_range
   1416 self.handles['plot'] = plot
-> 1418 self._init_glyphs(plot, element, ranges, source)
   1419 if not self.overlaid:
   1420     self._update_plot(key, plot, style_element)

File /usr/share/miniconda/envs/test-environment/lib/python3.8/site-packages/holoviews/plotting/bokeh/element.py:1384, in ElementPlot._init_glyphs(self, plot, element, ranges, source)
   1381 if isinstance(renderer, Renderer):
   1382     self.handles['glyph_renderer'] = renderer
-> 1384 self._postprocess_hover(renderer, source)
   1386 # Update plot, source and glyph
   1387 with abbreviated_exception():

File /usr/share/miniconda/envs/test-environment/lib/python3.8/site-packages/holoviews/plotting/bokeh/element.py:1351, in ElementPlot._postprocess_hover(self, renderer, source)
   1349     hover.renderers = []
   1350 if renderer not in hover.renderers:
-> 1351     hover.renderers.append(renderer)

File /usr/share/miniconda/envs/test-environment/lib/python3.8/site-packages/bokeh/core/property/wrappers.py:140, in notify_owner.<locals>.wrapper(self, *args, **kwargs)
    138 old = self._saved_copy()
    139 result = func(self, *args, **kwargs)
--> 140 self._notify_owners(old)
    141 return result

File /usr/share/miniconda/envs/test-environment/lib/python3.8/site-packages/bokeh/core/property/wrappers.py:169, in PropertyValueContainer._notify_owners(self, old, hint)
    167 def _notify_owners(self, old: Unknown, hint: DocumentPatchedEvent | None = None) -> None:
    168     for (owner, descriptor) in self._owners:
--> 169         descriptor._notify_mutated(owner, old, hint=hint)

File /usr/share/miniconda/envs/test-environment/lib/python3.8/site-packages/bokeh/core/property/descriptors.py:594, in PropertyDescriptor._notify_mutated(self, obj, old, hint)
    590 value = self.__get__(obj, obj.__class__)
    592 # re-validate because the contents of 'old' have changed,
    593 # in some cases this could give us a new object for the value
--> 594 value = self.property.prepare_value(obj, self.name, value, hint=hint)
    596 self._set(obj, old, value, hint=hint)

File /usr/share/miniconda/envs/test-environment/lib/python3.8/site-packages/bokeh/core/property/bases.py:365, in Property.prepare_value(self, owner, name, value, hint)
    363 else:
    364     obj_repr = owner if isinstance(owner, HasProps) else owner.__name__
--> 365     raise ValueError(f"failed to validate {obj_repr}.{name}: {error}")
    367 if isinstance(owner, HasProps):
    368     obj = owner

ValueError: failed to validate HoverTool(id='1007', ...).renderers: expected an element of either Auto or List(Instance(DataRenderer)), got [None]

@philippjfr philippjfr merged commit 07a6c5a into master Mar 31, 2022
@maximlt maximlt deleted the disable_hover_errorbars branch March 31, 2022 11:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants