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

BoxEdit stream not updating 2nd, 3rd ... box #5434

Closed
JanHomann opened this issue Sep 11, 2022 · 8 comments · Fixed by #6415
Closed

BoxEdit stream not updating 2nd, 3rd ... box #5434

JanHomann opened this issue Sep 11, 2022 · 8 comments · Fixed by #6415
Labels
type: bug Something isn't correct or isn't working
Milestone

Comments

@JanHomann
Copy link

JanHomann commented Sep 11, 2022

Package versions

holoviews = 1.15.0
bokeh     = 2.4.3

Description of bug

When moving the 2nd, 3rd ... box liked to a BoxEdit stream, the plot generated by the callback function does not update the corresponding trace. The y-scale of the plot does get updated, though. When inspecting the BoxEdit element, it also contains the updated values.

This happens also (but not only) in the example provided by the official documentation:
https://holoviews.org/gallery/demos/bokeh/box_draw_roi_editor.html

Example code

Here is the official example code (link provided above), modified to work without the external data file dependency twophoton.npz.

import numpy as np
import holoviews as hv
from holoviews import opts
from holoviews import streams
hv.extension('bokeh')

data = np.random.randn(62,111,50)
calcium_array = data
ds = hv.Dataset((np.arange(50), np.arange(111), np.arange(62), calcium_array),
                ['Time', 'x', 'y'], 'Fluorescence')

polys = hv.Polygons([])
box_stream = streams.BoxEdit(source=polys)

def roi_curves(data):
    if not data or not any(len(d) for d in data.values()):
        return hv.NdOverlay({0: hv.Curve([], 'Time', 'Fluorescence')})
    
    curves = {}
    data = zip(data['x0'], data['x1'], data['y0'], data['y1'])
    for i, (x0, x1, y0, y1) in enumerate(data):
        selection = ds.select(x=(x0, x1), y=(y0, y1))
        curves[i] = hv.Curve(selection.aggregate('Time', np.mean))
    return hv.NdOverlay(curves)

hlines = hv.HoloMap({i: hv.VLine(i) for i in range(50)}, 'Time')
dmap = hv.DynamicMap(roi_curves, streams=[box_stream])

im = ds.to(hv.Image, ['x', 'y'], dynamic=True)
(im * polys + dmap * hlines).opts(
    opts.Curve(width=400, framewise=True), 
    opts.Polygons(fill_alpha=0.2, line_color='white'), 
    opts.VLine(color='black'))

Error message

No error message generated.

Bug in action

2022-09-11 16 48 08

@JanHomann JanHomann changed the title BoxEdit stream not updating 2nd 3rd ... box BoxEdit stream not updating 2nd, 3rd ... box Sep 11, 2022
@JanHomann
Copy link
Author

JanHomann commented Sep 12, 2022

It seems like NdOverlay isn't correctly updating. I can't get Overlay to work, either.

@JanHomann
Copy link
Author

JanHomann commented Sep 12, 2022

This here works, but it requires fixing the number of elements in the NdOverlay beforehand. Unfortunately, this solution always generates a legend for ten elements. So it seems DynamicMap has a problem with a variable number of elements in the NdOverlay.

It seems like there was a similar issue already discovered, but closed as fixed: #3701

import numpy as np
import holoviews as hv
from holoviews import opts
from holoviews import streams
hv.extension('bokeh')

data = np.random.randn(62,111,50)
calcium_array = data
ds = hv.Dataset((np.arange(50), np.arange(111), np.arange(62), calcium_array),
                ['Time', 'x', 'y'], 'Fluorescence')

polys = hv.Polygons([])
box_stream = streams.BoxEdit(source=polys)

def roi_curves(data):
    # initialize NdOverlay with 10 empty curves
    ndoverlay = hv.NdOverlay({i:hv.Curve([], 'Time', 'Fluorescence') for i in range(10)}) #<---- line added
    if not data or not any(len(d) for d in data.values()):
        return ndoverlay                                                                  #<---- line changed
    
    data = zip(data['x0'], data['x1'], data['y0'], data['y1'])
    for i, (x0, x1, y0, y1) in enumerate(data):
        selection = ds.select(x=(x0, x1), y=(y0, y1))       
        s = selection.aggregate('Time', np.mean)        
        ndoverlay.get(i).data = s.data                             #<--- instead of making new curves, just change the data
    return ndoverlay                                               #<--- return NdOverlay

hlines = hv.HoloMap({i: hv.VLine(i) for i in range(50)}, 'Time')
dmap = hv.DynamicMap(roi_curves, streams=[box_stream])

im = ds.to(hv.Image, ['x', 'y'], dynamic=True)
(im * polys + dmap * hlines).opts(
    opts.NdOverlay(legend_position='right'),
    opts.Curve(width=400, framewise=True), 
    opts.Polygons(fill_alpha=0.2, line_color='white'), 
    opts.VLine(color='black'))

2022-09-11 22 26 41

@droumis
Copy link
Member

droumis commented Sep 19, 2022

@philippjfr, do you think the first gif demonstrates a bug in HoloViews or Bokeh?

Also, as shown in the second gif, do think prepopulating the legend with empty entries is appropriate behavior in general?

@droumis droumis added the type: bug Something isn't correct or isn't working label Sep 19, 2022
@droumis droumis added this to the 1.15.2 milestone Sep 19, 2022
@philippjfr
Copy link
Member

Definitely a HoloViews bug, seems like elements in the NdOverlay that aren't rendered are still being considered in the range calculation of the overlay.

@JanHomann
Copy link
Author

JanHomann commented Jul 12, 2023

Seemed to have been fixed in holoviews = 1.15.4. Yay!

But now in holoviews = 1.16.2 the whole box_edit tool seems to be broken. It doesn't even show up in the toolbar, and when I add it by hand, it doesn't work. Not so yay.

@droumis
Copy link
Member

droumis commented Jul 13, 2023

I think there are multiple issues going on here. You can make the box_edit tool appear in the toolbar with opts(tools=['box_edit'].. but there's still a bug preventing this from working.. I think related to #5756

@hoxbro
Copy link
Member

hoxbro commented Jul 13, 2023

As @droumis said, it is a know regression because we changed from Bokeh's Rect to Bokeh's Quad. Quad currently does not support BoxEditTool, but should come in Bokeh 3.3, when this PR is merged bokeh/bokeh#13204.

Copy link

This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Jan 28, 2025
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
type: bug Something isn't correct or isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants