holoviz / holoviews

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

ScaleBar on subcoordinate_y is overflowing subcoordinate range #6416

Closed droumis closed 2 weeks ago

droumis commented 3 weeks ago

ALL software version info

Software Version Info ```plaintext Python : 3.11.10 | packaged by conda-forge | (main, Sep 30 2024, 17:58:42) [Clang 17.0.6 ] Operating system : macOS-13.5.2-arm64-arm-64bit Panel comms : default holoviews : 1.20.0b0 bokeh : 3.6.0 colorcet : 3.1.0 cudf : - cupy : - dask : 2024.9.1 dask-expr : 1.1.15 datashader : 0.16.3 geoviews : - hvplot : 0.11.0 ibis-framework : - IPython : 8.28.0 ipywidgets-bokeh : - jupyter-bokeh : - jupyterlab : 4.2.5 matplotlib : 3.9.2 networkx : - notebook : 6.5.7 numba : 0.60.0 numpy : 1.26.4 pandas : 2.2.3 panel : 1.5.2 param : 2.1.1 pillow : 10.4.0 plotly : - pyarrow : 17.0.0 pyviz-comms : 3.0.3 scikit-image : - scipy : 1.14.1 spatialpandas : - streamz : - tsdownsample : 0.1.3 xarray : 2024.9.0 ```

Description of expected behavior and the observed behavior

ScaleBar on subcoordinate_y is overflowing subcoordinate range. The bar length should be limited by the extent of the subcoordinate range.

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

import holoviews as hv
import numpy as np
hv.extension("bokeh")

common_opts = dict(subcoordinate_y=True, scalebar_unit=('cm', 'm'), color='lightgrey')

curves = []
for i in range(10):
    curves.append(hv.Curve(np.random.rand(1000), label=f'c{i}').opts(**common_opts, scalebar=True if i == 5 else False))

curves = hv.Overlay(curves).opts(show_legend=False)

pn.panel(curves.opts(width=800, height=600)).servable()

Stack traceback and/or browser JavaScript console output

Screenshots or screencasts of the bug in action

image

hoxbro commented 2 weeks ago

This is because of the default options. Try updating to these:

scalebar_opts = {"bar_length": 0.8, "bar_length_units": "data", "length_sizing": "exact"}
common_opts = dict(subcoordinate_y=True, scalebar_unit=("cm", "m"), color="lightgrey", scalebar_opts=scalebar_opts)

image

droumis commented 2 weeks ago

I would not have guessed that "bar_length_units" = "data" would be needed to make the bar_length apply to the subcoordinate axis. Even in the bokeh docs: "data" - the length is provided in data space units" does not seem to align with the effect it's having here. I think this should be made to be the default for subcoordinate_y=True so that we don't make users remember this.

hoxbro commented 2 weeks ago

Agree. I also had it before your suggestions in the original PR.