holoviz / holoviews

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

rasterize leads to Bokeh "inner_height doesn't have a value set" error #5746

Closed peterroelants closed 1 year ago

peterroelants commented 1 year ago

Description of expected behavior and the observed behavior

Using rasterize leads to the following being printed to the output:

bokeh.core.property.descriptors.UnsetValueError: figure(id='30ff47ca-b677-4099-9127-3ba111a7364a', ...).inner_height doesn't have a value set

For some reason the result is non-deterministic, I can not always replicate this (only exactly the same setting). Testing this on VSCode notebooks.

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

import numpy as np

import xarray as xr

import matplotlib.pyplot as plt
import bokeh.models
import holoviews as hv
from holoviews.operation.datashader import rasterize
import panel as pn

hv.extension('bokeh')
pn.extension(comms='vscode')

x_size = 100
y_size = 100
data = xr.DataArray(
    data=np.random.rand(x_size, y_size),
    name='z',
    dims=['x', 'y'],
    coords={
        'x': np.sort(np.random.rand(x_size)),
        'y': np.sort(np.random.rand(y_size)),
    },
)

lcms_fitted_mesh = hv.QuadMesh(data, kdims=['x', 'y'], vdims=['z'])
rasterize(lcms_fitted_mesh)

Stack traceback and/or browser JavaScript console output

Task exception was never retrieved
future: <Task finished name='Task-15' coro=<Callback.process_on_change() done, defined at [/home/peterroelants/mambaforge/envs/lcms_polymer_env/lib/python3.11/site-packages/holoviews/plotting/bokeh/callbacks.py:322](https://vscode-remote+ssh-002dremote-002bspicy.vscode-resource.vscode-cdn.net/home/peterroelants/mambaforge/envs/lcms_polymer_env/lib/python3.11/site-packages/holoviews/plotting/bokeh/callbacks.py:322)> exception=UnsetValueError("figure(id='30ff47ca-b677-4099-9127-3ba111a7364a', ...).inner_height doesn't have a value set")>
Traceback (most recent call last):
  File "[/home/peterroelants/mambaforge/envs/lcms_polymer_env/lib/python3.11/site-packages/holoviews/plotting/bokeh/callbacks.py](https://vscode-remote+ssh-002dremote-002bspicy.vscode-resource.vscode-cdn.net/home/peterroelants/mambaforge/envs/lcms_polymer_env/lib/python3.11/site-packages/holoviews/plotting/bokeh/callbacks.py)", line 340, in process_on_change
    msg[attr] = self.resolve_attr_spec(path, cb_obj)
                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "[/home/peterroelants/mambaforge/envs/lcms_polymer_env/lib/python3.11/site-packages/holoviews/plotting/bokeh/callbacks.py](https://vscode-remote+ssh-002dremote-002bspicy.vscode-resource.vscode-cdn.net/home/peterroelants/mambaforge/envs/lcms_polymer_env/lib/python3.11/site-packages/holoviews/plotting/bokeh/callbacks.py)", line 248, in resolve_attr_spec
    resolved = getattr(resolved, p, None)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "[/home/peterroelants/mambaforge/envs/lcms_polymer_env/lib/python3.11/site-packages/bokeh/core/property/descriptors.py](https://vscode-remote+ssh-002dremote-002bspicy.vscode-resource.vscode-cdn.net/home/peterroelants/mambaforge/envs/lcms_polymer_env/lib/python3.11/site-packages/bokeh/core/property/descriptors.py)", line 283, in __get__
    raise UnsetValueError(f"{obj}.{self.name} doesn't have a value set")
bokeh.core.property.descriptors.UnsetValueError: figure(id='30ff47ca-b677-4099-9127-3ba111a7364a', ...).inner_height doesn't have a value set

ALL software version info

Visual Studio Code Version 1.78.2

Python implementation: CPython
Python version       : 3.11.3
IPython version      : 8.14.0

holoviews : 1.16.1
numpy     : 1.24.3
xarray    : 2023.5.0
panel     : 1.1.0
matplotlib: 3.7.1
bokeh     : 3.1.1
MatusGasparik commented 1 year ago

I experience the same error.

hoxbro commented 1 year ago

@mattpap, any idea what is causing this?

mattpap commented 1 year ago

inner_height is a readonly property set by bokehjs and returned back to bokeh. Seeing this code:

getattr(resolved, p, None)

If I understand this code correctly, then this is expected to fail. Since the introduction of unset values, getting bokeh's properties like this will result in UnsetValueError, if the value is unset. None is a perfectly valid value in bokeh's type system (see Nullable), thus it shouldn't be expected to be viable missing value indicator. try-expect UnsetValueError should resolve this, at least on the surface. However, if someone could explain the intention behind this code, then I can point to the right API to deal with this.

hoxbro commented 1 year ago

The behavior only happens in VSCode, which uses jupyter_bokeh.

As far as I can see, the example works even with the error.

mattpap commented 1 year ago

As far as I can see, the example works even with the error.

That's expected. inner_height and similar properties are for informational purpose and have no real bearing on anything. If the failure doesn't interrupt anything important, then a bokeh process will continue fine, just with the relevant value missing.

mattpap commented 1 year ago

The behavior only happens in VSCode,

It may be a timing issue. If those properties are read before bokehjs has a chance to update them, then UnsetValueError will occur. If things happen in holoviews (or whichever layer of integration) before bokehjs signals the ready state, then errors like this one should be expected.