holoviz-topics / neuro

HoloViz+Bokeh for Neuroscience
BSD 3-Clause "New" or "Revised" License
19 stars 5 forks source link

Draft public docs for Multi-Channel timeseries and Large Image workflows #96

Closed droumis closed 3 months ago

droumis commented 5 months ago

I'll probably abandon the cards on the index page because bugs in Panel

image
ahuang11 commented 5 months ago

Couldn't push directly so I pushed to a fork: https://github.com/holoviz-topics/neuro/pull/97

ahuang11 commented 4 months ago

The hover tooltips can be defined like:

            hover_tooltips=[
                ("Channel", "$label"),
                ("Time", "$x s"),
                ("Amplitude", "$y µV"),
            ],
# TODO: add handling for large number of channels - at some threshold it will impact loadable pyramid level
# TODO: profile for latency.. potentially parallel stream rendering?
# TODO: debug why sometimes the plotsize stream doesn't get triggered

X_PADDING = 0.2  # buffer x-range to reduce update latency with pans and zoom-outs

# TODO: use custom hv hovertool when holoviews is released.
def rescale(x_range, y_range, width, scale, height):

    # Handle edge case when streams are initialized
    if x_range is None:
        x_range = time_da.min().item(), time_da.max().item()
    if y_range is None:
        y_range = 0, num_channels

    # define time range slice
    x_padding = (x_range[1] - x_range[0]) * X_PADDING
    time_slice = slice(x_range[0] - x_padding, x_range[1] + x_padding)

    channel_slice = slice(y_range[0], y_range[1])

    # calculate the appropriate pyramid level and size
    if width is None or height is None:
        pyramid_level = num_levels - 1
        size = time_da.size
    else:
        sizes = np.array(
            [
                _extract_ds(ts_dt, pyramid_level)["time"].sel(time=time_slice).size
                for pyramid_level in range(num_levels)
            ]
        )
        # pyramid_level = np.argmin(np.where(diffs >= 0, diffs, np.inf)) # nearest higher-resolution level
        pyramid_level = np.argmin(
            np.abs(np.array(sizes) - width)
        )  # nearest, regardless of direction
        size = sizes[pyramid_level]

    title = (
        f"[Pyramid Level {pyramid_level} ({x_range[0]:.2f}s - {x_range[1]:.2f}s)]   "
        f"[Time Samples: {size}]  [Plot Size WxH: {width}x{height}]"
    )

    # extract new data and re-paint the plot
    ds = _extract_ds(ts_dt, pyramid_level, channels).sel(time=time_slice).load()
    df = ds.to_dataframe()

    curves = hv.Overlay(kdims="Channel")
    for channel in channels:
        curves *= hv.Curve(
            df.loc[channel], ["time"], ["data"], label=str(channel)
        ).opts(
            color="black",
            line_width=1,
            subcoordinate_y=True,
            subcoordinate_scale=2,
            default_tools=["pan", "reset", "wheel_zoom", "box_zoom", WheelZoomTool()],
            hover_tooltips=[
                ("Channel", "$label"),
                ("Time", "$x s"),
                ("Amplitude", "$y µV"),
            ],
        )

    curves = curves.opts(
        xlabel="Time (s)",
        ylabel="Channel",
        title=title,
        show_legend=False,
        padding=0,
        aspect=1.5,
        responsive=True,
        framewise=True,
        axiswise=True,
    )
    return curves

range_stream = hv.streams.RangeXY()
size_stream = hv.streams.PlotSize()
pn.serve(hv.DynamicMap(rescale, streams=[size_stream, range_stream]))
maximlt commented 4 months ago

I installed the environment at workflows/multi_channel_timeseries/environment.yml and ran the notebooks in this folder.


small_multi-chan-ts.ipynb

Got this error:

ValueError: Unexpected option 'hover_tooltips' for Curve type across all extensions. Similar options for current extension ('bokeh') are: ['hover_alpha', 'hover_color', 'hover_line_cap'].

The notebook runs fine when commenting out hover_tooltips, I guess it just needs a dev release of HoloViews.


medium_multi-chan-ts.ipynb

I got ModuleNotFoundError: No module named 'wget', fixed by manually downloading the file and putting it in ./data. Also got the hover_tooltips error. Then got KeyError: 'minmax-lttb', got it working replacing with lttb, but newer version of HoloViews would have worked too.


large_multi-chan-ts.ipynb

Worked first try! Just got this warning when plotting the minimap:

WARNING:param.Image00868: Image dimension Time is  not evenly sampled to relative tolerance of 0.001. Please use the QuadMesh element for irregularly sampled data or set a higher tolerance on hv.config.image_rtol or the rtol parameter in the Image constructor.

time_range_annotation.ipynb

Doesn't look like this notebook is meant to be shared, it fails as it has no imports.

droumis commented 3 months ago

Thanks @maximlt !!

Replacing Image with QuadMesh seems to work so I'll just go with that.

droumis commented 3 months ago

merging progress now.. will clean up in another PR