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

Combination of datashade and hv.operation.apply_when results in navy background on zoom #6493

Open
1 task
JSKenyon opened this issue Jan 17, 2025 · 4 comments
Labels
type: bug Something isn't correct or isn't working

Comments

@JSKenyon
Copy link

JSKenyon commented Jan 17, 2025

Software Version Info

OS: Ubuntu 24.04
Python: 3.10.16
Firefox: 133.0.3
Environment:

anyio==4.8.0
argon2-cffi==23.1.0
argon2-cffi-bindings==21.2.0
arrow==1.3.0
asttokens==3.0.0
async-lru==2.0.4
attrs==24.3.0
babel==2.16.0
beautifulsoup4==4.12.3
bleach==6.2.0
bokeh==3.6.2
certifi==2024.12.14
cffi==1.17.1
charset-normalizer==3.4.1
click==8.1.8
cloudpickle==3.1.1
colorcet==3.1.0
comm==0.2.2
contourpy==1.3.1
dask==2024.12.1
datashader==0.16.3
debugpy==1.8.12
decorator==5.1.1
defusedxml==0.7.1
exceptiongroup==1.2.2
executing==2.1.0
fastjsonschema==2.21.1
fqdn==1.5.1
fsspec==2024.12.0
h11==0.14.0
holoviews==1.20.0
httpcore==1.0.7
httpx==0.28.1
idna==3.10
importlib_metadata==8.5.0
ipykernel==6.29.5
ipython==8.31.0
isoduration==20.11.0
jedi==0.19.2
Jinja2==3.1.5
json5==0.10.0
jsonpointer==3.0.0
jsonschema==4.23.0
jsonschema-specifications==2024.10.1
jupyter-events==0.11.0
jupyter-lsp==2.2.5
jupyter_client==8.6.3
jupyter_core==5.7.2
jupyter_server==2.15.0
jupyter_server_terminals==0.5.3
jupyterlab==4.3.4
jupyterlab_pygments==0.3.0
jupyterlab_server==2.27.3
linkify-it-py==2.0.3
llvmlite==0.43.0
locket==1.0.0
Markdown==3.7
markdown-it-py==3.0.0
MarkupSafe==3.0.2
matplotlib-inline==0.1.7
mdit-py-plugins==0.4.2
mdurl==0.1.2
mistune==3.1.0
multipledispatch==1.0.0
nbclient==0.10.2
nbconvert==7.16.5
nbformat==5.10.4
nest-asyncio==1.6.0
notebook==7.3.2
notebook_shim==0.2.4
numba==0.60.0
numpy==2.0.2
overrides==7.7.0
packaging==24.2
pandas==2.2.3
pandocfilters==1.5.1
panel==1.5.5
param==2.2.0
parso==0.8.4
partd==1.4.2
pexpect==4.9.0
pillow==11.1.0
platformdirs==4.3.6
prometheus_client==0.21.1
prompt_toolkit==3.0.48
psutil==6.1.1
ptyprocess==0.7.0
pure_eval==0.2.3
pycparser==2.22
pyct==0.5.0
Pygments==2.19.1
python-dateutil==2.9.0.post0
python-json-logger==3.2.1
pytz==2024.2
pyviz_comms==3.0.4
PyYAML==6.0.2
pyzmq==26.2.0
referencing==0.36.1
requests==2.32.3
rfc3339-validator==0.1.4
rfc3986-validator==0.1.1
rpds-py==0.22.3
scipy==1.15.1
Send2Trash==1.8.3
six==1.17.0
sniffio==1.3.1
soupsieve==2.6
stack-data==0.6.3
terminado==0.18.1
tinycss2==1.4.0
tomli==2.2.1
toolz==1.0.0
tornado==6.4.2
tqdm==4.67.1
traitlets==5.14.3
types-python-dateutil==2.9.0.20241206
typing_extensions==4.12.2
tzdata==2024.2
uc-micro-py==1.0.3
uri-template==1.3.0
urllib3==2.3.0
wcwidth==0.2.13
webcolors==24.11.1
webencodings==0.5.1
websocket-client==1.8.0
xarray==2025.1.1
xyzservices==2024.9.0
zipp==3.21.0

Description of expected behavior and the observed behavior

I am attempting to dynamically shift between a datashaded plot and the raw Points when the current window contains more points than a specified threshold using hv.operation.apply_when. This works, but the background of the resulting plot becomes navy blue on zoom at the point when the plots switches from returning a datashaded version to the raw Points.

Edit: This does not happen when using rasterize instead of datashade.

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

import holoviews as hv
import numpy as np
from holoviews.operation.datashader import datashade

hv.extension('bokeh', width=100)

points = hv.Points(np.random.multivariate_normal((0,0), [[0.1, 0.1], [0.1, 1.0]], (500000,)))

plot = hv.operation.apply_when(
    points,
    operation=lambda points: datashade(points).opts(width=800, height=800),
    predicate=lambda x: len(x) > 50000
)
plot  # Running inside a notebook.

Screenshots or screencasts of the bug in action

Image

Image

  • I may be interested in making a pull request to address this
@JSKenyon
Copy link
Author

JSKenyon commented Jan 17, 2025

The cause of this behaviour seems to stem from plotting an empty Points/Scatter object.

import holoviews as hv
from holoviews.operation.datashader import datashade

plot = datashade(hv.Scatter([])).opts(width=800, height=800)
plot

This produces:

Image

I would have assumed that this would leave an empty canvas. Is there an easy way to change this behaviour?

@JSKenyon
Copy link
Author

As my final input before the weekend, this seems to be related to how datashader handles the colourmap. It seems that datashader will make the entire plot area the colour of high end of the colour map when there are no points in the input. This is inconsistent with rasterize and, I would argue, not a sensible default.

@hoxbro
Copy link
Member

hoxbro commented Jan 17, 2025

I would agree with your assessment.

As a workaround, you can do something like this:

import holoviews as hv
import numpy as np
from holoviews.operation.datashader import datashade

def no_data_white_background(plot, element):
    if np.unique(element.rgb.data.values.view(np.uint32)).size == 1:
        element.rgb.data.values = np.zeros_like(element.rgb.data.values)
    return element


datashade._postprocess_hooks = [no_data_white_background]

hv.extension('bokeh', width=100)

points = hv.Points(np.random.multivariate_normal((0,0), [[0.1, 0.1], [0.1, 1.0]], (500000,)))

hv.operation.apply_when(
    points,
    operation=lambda points: datashade(points).opts(width=800, height=800),
    predicate=lambda x: len(x) > 50000
)
Screencast.From.2025-01-17.16-02-18.mp4

@hoxbro hoxbro added the type: bug Something isn't correct or isn't working label Jan 17, 2025
@JSKenyon
Copy link
Author

Thank you @hoxbro - that works perfectly!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type: bug Something isn't correct or isn't working
Projects
None yet
Development

No branches or pull requests

2 participants