Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit f2a7682

Browse files
timhoffmQuLogic
andauthored
ENH: Scroll to zoom (#30405)
* ENH: Scroll to zoom Implements a minimal version of #20317, in particular https://github .com//pull/20317#issuecomment-2233156558: Co-authored-by: Elliott Sales de Andrade <[email protected]>
1 parent 81febeb commit f2a7682

File tree

3 files changed

+62
-0
lines changed

3 files changed

+62
-0
lines changed
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
Zooming using mouse wheel
2+
~~~~~~~~~~~~~~~~~~~~~~~~~
3+
4+
``Ctrl+MouseWheel`` can be used to zoom in the plot windows.
5+
6+
The zoom focusses on the mouse pointer, and keeps the aspect ratio of the axes.
7+
8+
Zooming is currently only supported on rectilinear Axes.

lib/matplotlib/backend_bases.py

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2574,6 +2574,51 @@ def button_press_handler(event, canvas=None, toolbar=None):
25742574
toolbar.forward()
25752575

25762576

2577+
def scroll_handler(event, canvas=None, toolbar=None):
2578+
ax = event.inaxes
2579+
if ax is None:
2580+
return
2581+
if ax.name != "rectilinear":
2582+
# zooming is currently only supported on rectilinear axes
2583+
return
2584+
2585+
if toolbar is None:
2586+
toolbar = (canvas or event.canvas).toolbar
2587+
2588+
if toolbar is None:
2589+
# technically we do not need a toolbar, but until wheel zoom was
2590+
# introduced, any interactive modification was only possible through
2591+
# the toolbar tools. For now, we keep the restriction that a toolbar
2592+
# is required for interactive navigation.
2593+
return
2594+
2595+
if event.key == "control": # zoom towards the mouse position
2596+
toolbar.push_current()
2597+
2598+
xmin, xmax = ax.get_xlim()
2599+
ymin, ymax = ax.get_ylim()
2600+
(xmin, ymin), (xmax, ymax) = ax.transScale.transform(
2601+
[(xmin, ymin), (xmax, ymax)])
2602+
2603+
# mouse position in scaled (e.g., log) data coordinates
2604+
x, y = ax.transScale.transform((event.xdata, event.ydata))
2605+
2606+
scale_factor = 0.85 ** event.step
2607+
new_xmin = x - (x - xmin) * scale_factor
2608+
new_xmax = x + (xmax - x) * scale_factor
2609+
new_ymin = y - (y - ymin) * scale_factor
2610+
new_ymax = y + (ymax - y) * scale_factor
2611+
2612+
inv_scale = ax.transScale.inverted()
2613+
(new_xmin, new_ymin), (new_xmax, new_ymax) = inv_scale.transform(
2614+
[(new_xmin, new_ymin), (new_xmax, new_ymax)])
2615+
2616+
ax.set_xlim(new_xmin, new_xmax)
2617+
ax.set_ylim(new_ymin, new_ymax)
2618+
2619+
ax.figure.canvas.draw_idle()
2620+
2621+
25772622
class NonGuiException(Exception):
25782623
"""Raised when trying show a figure in a non-GUI backend."""
25792624
pass
@@ -2653,11 +2698,14 @@ def __init__(self, canvas, num):
26532698

26542699
self.key_press_handler_id = None
26552700
self.button_press_handler_id = None
2701+
self.scroll_handler_id = None
26562702
if rcParams['toolbar'] != 'toolmanager':
26572703
self.key_press_handler_id = self.canvas.mpl_connect(
26582704
'key_press_event', key_press_handler)
26592705
self.button_press_handler_id = self.canvas.mpl_connect(
26602706
'button_press_event', button_press_handler)
2707+
self.scroll_handler_id = self.canvas.mpl_connect(
2708+
'scroll_event', scroll_handler)
26612709

26622710
self.toolmanager = (ToolManager(canvas.figure)
26632711
if mpl.rcParams['toolbar'] == 'toolmanager'

lib/matplotlib/backend_bases.pyi

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -407,6 +407,11 @@ def button_press_handler(
407407
canvas: FigureCanvasBase | None = ...,
408408
toolbar: NavigationToolbar2 | None = ...,
409409
) -> None: ...
410+
def scroll_handler(
411+
event: MouseEvent,
412+
canvas: FigureCanvasBase | None = ...,
413+
toolbar: NavigationToolbar2 | None = ...,
414+
) -> None: ...
410415

411416
class NonGuiException(Exception): ...
412417

@@ -415,6 +420,7 @@ class FigureManagerBase:
415420
num: int | str
416421
key_press_handler_id: int | None
417422
button_press_handler_id: int | None
423+
scroll_handler_id: int | None
418424
toolmanager: ToolManager | None
419425
toolbar: NavigationToolbar2 | ToolContainerBase | None
420426
def __init__(self, canvas: FigureCanvasBase, num: int | str) -> None: ...

0 commit comments

Comments
 (0)