-
-
Notifications
You must be signed in to change notification settings - Fork 404
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
Zoom tools automatically vertically scaled on subcoordinate_y overlays #6051
Conversation
Codecov ReportAttention:
Additional details and impacted files@@ Coverage Diff @@
## main #6051 +/- ##
==========================================
+ Coverage 88.65% 88.66% +0.01%
==========================================
Files 314 314
Lines 65688 65764 +76
==========================================
+ Hits 58234 58309 +75
- Misses 7454 7455 +1
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. |
Interestingly I've found the HoloViews version slower to zoom in/out when scrolling fast compared to the pure Bokeh one. @droumis could you try out both and see if you observe the same difference on your system? Pure Bokeh code to serve
import numpy as np
from bokeh.core.properties import field
from bokeh.io import curdoc, show
from bokeh.models import (ColumnDataSource, DataRange1d, FactorRange,
HoverTool, Range1d, WheelZoomTool, ZoomInTool, ZoomOutTool)
from bokeh.plotting import figure
from bokeh.palettes import Category10
np.random.seed(0)
n_channels = 10
n_seconds = 15
fs = 512
max_ch_disp = 5 # max channels to initially display
max_t_disp = 3 # max time in seconds to initially display
total_samples = n_seconds * fs
time = np.linspace(0, n_seconds, total_samples)
data = np.random.randn(n_channels, total_samples).cumsum(axis=1)
channels = [f'EEG {i}' for i in range(n_channels)]
hover = HoverTool(tooltips=[
("Channel", "$name"),
("Time", "$x s"),
("Amplitude", "$y µV"),
])
x_range = Range1d(start=time.min(), end=time.max())
y_range = FactorRange(factors=channels)
p = figure(x_range=x_range, y_range=y_range, lod_threshold=None)
source = ColumnDataSource(data=dict(time=time))
renderers = []
for i, channel in enumerate(channels):
xy = p.subplot(
x_source=p.x_range,
y_source=Range1d(start=data[i].min(), end=data[i].max()),
x_target=p.x_range,
y_target=Range1d(start=i, end=i + 1),
)
source.data[channel] = data[i]
line = xy.line(field("time"), field(channel), color=Category10[10][i], source=source, name=channel)
renderers.append(line)
wheel_zoom = WheelZoomTool(renderers=renderers, level=1, dimensions='height')
p.add_tools(wheel_zoom, hover)
p.toolbar.active_scroll = wheel_zoom
curdoc().add_root(p) |
It's a bit harder to compare the latency with the wheel zoom, but I don't detect a big difference when running both in a notebook. They are both very responsive with 10 channels and 15 seconds. Screen.Recording.2023-12-26.at.3.53.08.PM.movIf you scale it to 10 channels and 150 seconds, both become equally terrible. Sidenote, I'm not sure how you got the zoom_in and zoom_out tools to appear for you for the HoloViews plot.. they don't appear for me even with your code. I'm using bokeh 3.3.2. |
This reverts commit e1d688e.
My mistake! I made a wrong simplification in e1d688e after opening the PR, it's now reverted and you should be able to see the zoom_in/zoom_out tools with the code you used. Happy to hear you're not seeing any performance differences between the pure Bokeh and HoloViews versions. I'm also no longer seeing that, there must have been something temporarily wrong with my system. @droumis how do you want to proceed with the review of this PR? Addressing #5901 will have to build on this PR so the faster it's merged the less likely both work will conflict. |
Yes, I think we should proceed with review. I anticipate that there may be some discussion about this new default behavior, but let's address any concerns when they arise. To summarize the rationale for others: First, we need to have the zoom tools apply to the appropriate Second, for this subplot context, there doesn't seem to be a use case in which zooming each subcoordinate axis in both the x and y simultaneously is the desired behavior. Therefore, a more reasonable default would be to have a zoom tool apply only to the y ('height') axis by default. This is the second thing that this PR achieves. If a user wants a zoom tool for just the x axis, they can add, e.g. 'xwheel_zoom' to the list of tools in opts. The upside is that these changes would capture IMO the vast majority of use cases for The downside is that this changes (contextualizes) the behavior of a default zoom tool. It also makes it hard for a user to do the thing that probably no one would want to do - zooming each subcoordinate axis in both the x and y simultaneously). However, it also makes it harder to apply a zoom tool to the base axis (level=0). This last point could be mitigated with the use of a 'box_zoom' tools or a minimap (RangeToolLink) widget. What's the alternative? If there was a clean way to specify options (level, dimension) for a given tool, then that would be an alternative, but that seems to be more of a departure from the HoloViews way of doing things compared to the contextualized approach in this PR. That said, there are other benefits to exposing options for zoom tools (like being able to set 'maintain focus') but this is beyond scope, so maybe we adapt later on. |
A way to override the default behavior here is to pass in a Bokeh zoom model |
Another alternative raised for consideration by @jlstevens was to create a new subplot zoom string |
Yet another possibility is to have the zoom tools be further specified directly through planned UI elements/interactivity with the Bokeh toolbar |
Update. In response to a question by @hoxbro, I checked what happens when wheel-zooming while the cursor is over the x-axis. Unfortunately with this PR, nothing happens. I guess the ideal behavior is that it would switch to xwheel-zoom when over the x axis |
I support the intent of this PR and picking the right behavior given the plot makes sense. My only hesitation is that this updated tool only applies to This would be another wheel zoom tool so ideally we would have a new icon to distinguish it (otherwise visually it will look like a duplication and you can't tell at a glance which is which). |
Thanks @jlstevens for your feedback. We discussed that again with @droumis who pointed at that in the current state of this PR users can already add the |
Of course! That is a reasonable workaround for now: I was trying to think of ways to make the disruption to the normal UX as small as possible. None of my suggestions were going to block this PR but I did want to consider some options for potential future PRs. |
This pull request has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs. |
resolves #5902
An overlay set with
wheel_zoom
(default, no need to provide it),zoom_in
,zoom_out
and theiry-<zoom>
counterpart is set to automatically vertically scale the subplots. This is achieved by settingdimensions
toheight
andlevel
to1
on the Bokeh tools. The Bokeh zoom instance must know the list of all the renderers. To achieve that we:renderers
attribute (the default being 'auto')