Open josephernest opened 1 year ago
Can you say more about
then you can zoom only with a certain aspect ratio rectangular shape, which is sometimes a limiting factor for the UX/UI
Is your concern that the point where you mouse down is always a corner of the final viewport, but you think the behavior you describe better reflects user intention? That may be the case, ie you zoom by essentially “highlighting” the points you care about, and if that’s smaller than the region needed to satisfy the scale constraint you’d prefer to expand the range so your whole “selection” is visible and centered.
I don’t like the idea of the final viewport being different from what you saw, but if we agree that this mechanism is better we could just change to doing it this way, ie rather than the mouse down point always being a corner, it’s always on an edge, as is the final cursor location, but the box expands symmetrically in whichever dimension it needs to to maintain the constraint.
One potentially weird effect: if you drag across an edge, using this rule the box would expand to include some areas outside the current viewport. Maybe better to avoid that, and expand only as far as the edge of the current viewport, and expand more on the other side when that happens.
Thank you for your feedback @alexcjohnson.
A few answers to your question
Is your concern that the point where you mouse down is always a corner of the final viewport
No no, this is not really the concern.
I don’t like the idea of the final viewport being different from what you saw
You're right, this is the drawback. But I don't find it problematic. What do you think about Eric's solution from the runnable snippet code here: https://stackoverflow.com/questions/75792497/zoom-on-a-plotly-heatmap/76142244#76142244 ?
About the UX: I showed the current Plotly way to some users in our team, and they were unconfortable by the fact the zooming rectangle aspect ratio is fixed, they wanted a free-shape rectangle.
Matplotlib does another way (which is not optimal though ;))
Zooming:
Zoomed:
I don't think one behavior is really better than the other. The scaleanchor constraint as it is currently implemented is constraining, but in the other hand I agree with @alexcjohnson, the fact that the final zoom range is not (or not always) what the user drawn can be disturbing.
One option would be to improve the current implementation by applying the rules used in my code directly to the dragbox, ie. as it is right now (so that the user is still able to see what happens when he drags), but with the behavior Alex suggested if I understood correctly :
rather than the mouse down point always being a corner, it’s always on an edge, as is the final cursor location, but the box expands symmetrically in whichever dimension it needs to to maintain the constraint.
The end result would be a bit less constraining, and without the disturbing effect.
This does not exclude a second option, that would be to introduce a parameter, say constraindragbox: true | false
, that tells whether to constrain the dragbox, or only the final zoom range like in the SO answer.
One potentially weird effect: if you drag across an edge, using this rule the box would expand to include some areas outside the current viewport. Maybe better to avoid that, and expand only as far as the edge of the current viewport, and expand more on the other side when that happens.
Exactly, the SO answer does not handle those "edge cases" ;) I will try to improve it. [Edit] : I updated the answer so that the zoom ranges always stay inside the viewport.
@alexcjohnson Do you think @lvlte's idea could be included in the next release?
This is the behaviour used in most tools that display data as image or heatmap (or cartography map) : when we zoom, the UI uses all the available width to make it easier to visualize data: here in Photopea but it's the same in Photosthop etc.:
https://github.com/plotly/plotly.js/assets/6168083/dc5a8811-e5d3-4551-8a4e-b3bb82593384
On the other hand, the current status in Plotly heatmaps is this:
https://github.com/plotly/plotly.js/assets/6168083/5c0e1298-7813-4ea6-a86b-dd8c55bd649e
All the free space is lost on left and right, thus the visualization during zoom is not optimal.
If the width is small, and height is high, this effect is even more extreme.
What do you think @lvlte @alexcjohnson ?
The scaleanchor constrain is one thing (which also makes the shape of the zoom window fixed), but how it is applied on a given axis (that is, either by increasing its "range" or by decreasing its "domain") is another thing which is determined by constrain
and constraintoward
.
In your example the constrain is on the domain whereas you expect it to be on the range. This happens because you also have an image trace on the plot :
constrain
- [...] Default is "domain" for axes containing image traces, "range" otherwise.
You can't remove the axes scaleanchor that comes with an image trace, but you can still set the constrain you want.
Hi @lvlte, do you think there have been updates about this since our last emails? i.e. is this behaviour now available out-of-the-box in Plotly.js or is your patch (https://stackoverflow.com/a/76142244) still required for this? Thanks in advance!
PS: after using this patch, sometimes I want to change the xaxis / yaxis range manually. Then when using:
Plotly.relayout("heatmap", { 'xaxis.range': xrange, 'yaxis.range': yrange })
breaks the behaviour from the patch.
Currently there are 2 “zooming” behaviours in Plotly.JS heatmaps:
Demo here : Here you can take any rectangular shape for the zoom (click, drag and drop). But then the pixels are not square, which is not ok for some applications (the aspect ratio is not preserved, and sometimes it should be preserved):
Demo here : Here the pixels are square thanks to
{'yaxis': {'scaleanchor': 'x'}}
, but then you can zoom only with a certain aspect ratio rectangular shape, which is sometimes a limiting factor for the UX/UI:But often, it is useful to have both, i.e. being able to draw a rectangle selection zoom of any shape + keep square-shape pixels.
Eric found a solution here: https://stackoverflow.com/a/76142244/1422096
IMHO this feature should be available directly in Plotly heatmaps (because it's the standard expected behaviour, which is common in Matplotlib etc.), what do you think? @lvlte @archmoj