Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit e7c6cb7

Browse filesBrowse files
committed
Fix toolmanager x/y scale "togglers".
ToolXScale and ToolYScale actually *cannot* be implemented using ToolToggleBase because a single "toggle" flag cannot store the log/linear state of *multiple* axes at once (i.e. the behavior of pressing "l" becomes wrong as soon as there are multiple axes in a given figure). Instead these must be plain tools that inspect the actual scale on the axes before deciding what to do. In practice, the easiest is to again reuse the classic toolbar implementation, as is already done for ToolGrid and ToolMinorGrid. Factor out that "forward-to-classic-toolbar" implementation into a _ToolForwardingToClassicToolbar base class and use that whereever possible.
1 parent a4dca24 commit e7c6cb7
Copy full SHA for e7c6cb7

File tree

Expand file treeCollapse file tree

2 files changed

+39
-79
lines changed
Filter options
Expand file treeCollapse file tree

2 files changed

+39
-79
lines changed

‎lib/matplotlib/backend_tools.py

Copy file name to clipboardExpand all lines: lib/matplotlib/backend_tools.py
+29-64Lines changed: 29 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -358,101 +358,66 @@ def remove_rubberband(self):
358358
pass
359359

360360

361-
class ToolQuit(ToolBase):
361+
class _ToolForwardingToClassicToolbar(ToolBase):
362+
_rc_entry = '' # Must be set by subclass.
363+
default_keymap = property(lambda self: mpl.rcParams[self._rc_entry])
364+
365+
def trigger(self, sender, event, data=None):
366+
sentinel = str(uuid.uuid4())
367+
# Trigger class toolbar implementation by temporarily setting the keymap to a
368+
# unique key and sending an appropriate event.
369+
with cbook._setattr_cm(event, key=sentinel), \
370+
mpl.rc_context({self._rc_entry: sentinel}):
371+
mpl.backend_bases.key_press_handler(event, self.figure.canvas)
372+
373+
374+
class ToolQuit(_ToolForwardingToClassicToolbar):
362375
"""Tool to call the figure manager destroy method."""
363376

364377
description = 'Quit the figure'
365-
default_keymap = property(lambda self: mpl.rcParams['keymap.quit'])
366-
367-
def trigger(self, sender, event, data=None):
368-
Gcf.destroy_fig(self.figure)
378+
_rc_entry = 'keymap.quit'
369379

370380

371-
class ToolQuitAll(ToolBase):
381+
class ToolQuitAll(_ToolForwardingToClassicToolbar):
372382
"""Tool to call the figure manager destroy method."""
373383

374384
description = 'Quit all figures'
375-
default_keymap = property(lambda self: mpl.rcParams['keymap.quit_all'])
376-
377-
def trigger(self, sender, event, data=None):
378-
Gcf.destroy_all()
385+
_rc_entry = 'keymap.quit_all'
379386

380387

381-
class ToolGrid(ToolBase):
388+
class ToolGrid(_ToolForwardingToClassicToolbar):
382389
"""Tool to toggle the major grids of the figure."""
383390

384391
description = 'Toggle major grids'
385-
default_keymap = property(lambda self: mpl.rcParams['keymap.grid'])
386-
387-
def trigger(self, sender, event, data=None):
388-
sentinel = str(uuid.uuid4())
389-
# Trigger grid switching by temporarily setting :rc:`keymap.grid`
390-
# to a unique key and sending an appropriate event.
391-
with cbook._setattr_cm(event, key=sentinel), \
392-
mpl.rc_context({'keymap.grid': sentinel}):
393-
mpl.backend_bases.key_press_handler(event, self.figure.canvas)
392+
_rc_entry = 'keymap.grid'
394393

395394

396-
class ToolMinorGrid(ToolBase):
395+
class ToolMinorGrid(_ToolForwardingToClassicToolbar):
397396
"""Tool to toggle the major and minor grids of the figure."""
398397

399398
description = 'Toggle major and minor grids'
400-
default_keymap = property(lambda self: mpl.rcParams['keymap.grid_minor'])
401-
402-
def trigger(self, sender, event, data=None):
403-
sentinel = str(uuid.uuid4())
404-
# Trigger grid switching by temporarily setting :rc:`keymap.grid_minor`
405-
# to a unique key and sending an appropriate event.
406-
with cbook._setattr_cm(event, key=sentinel), \
407-
mpl.rc_context({'keymap.grid_minor': sentinel}):
408-
mpl.backend_bases.key_press_handler(event, self.figure.canvas)
399+
_rc_entry = 'keymap.grid_minor'
409400

410401

411-
class ToolFullScreen(ToolBase):
402+
class ToolFullScreen(_ToolForwardingToClassicToolbar):
412403
"""Tool to toggle full screen."""
413404

414405
description = 'Toggle fullscreen mode'
415-
default_keymap = property(lambda self: mpl.rcParams['keymap.fullscreen'])
406+
_rc_entry = 'keymap.fullscreen'
416407

417-
def trigger(self, sender, event, data=None):
418-
self.figure.canvas.manager.full_screen_toggle()
419-
420-
421-
class AxisScaleBase(ToolToggleBase):
422-
"""Base Tool to toggle between linear and logarithmic."""
423408

424-
def trigger(self, sender, event, data=None):
425-
if event.inaxes is None:
426-
return
427-
super().trigger(sender, event, data)
428-
429-
def enable(self, event=None):
430-
self.set_scale(event.inaxes, 'log')
431-
self.figure.canvas.draw_idle()
409+
class ToolXScale(_ToolForwardingToClassicToolbar):
410+
"""Tool to toggle between linear and logarithmic scales on the X axis."""
432411

433-
def disable(self, event=None):
434-
self.set_scale(event.inaxes, 'linear')
435-
self.figure.canvas.draw_idle()
412+
description = 'Toggle scale X axis'
413+
_rc_entry = 'keymap.xscale'
436414

437415

438-
class ToolYScale(AxisScaleBase):
416+
class ToolYScale(_ToolForwardingToClassicToolbar):
439417
"""Tool to toggle between linear and logarithmic scales on the Y axis."""
440418

441419
description = 'Toggle scale Y axis'
442-
default_keymap = property(lambda self: mpl.rcParams['keymap.yscale'])
443-
444-
def set_scale(self, ax, scale):
445-
ax.set_yscale(scale)
446-
447-
448-
class ToolXScale(AxisScaleBase):
449-
"""Tool to toggle between linear and logarithmic scales on the X axis."""
450-
451-
description = 'Toggle scale X axis'
452-
default_keymap = property(lambda self: mpl.rcParams['keymap.xscale'])
453-
454-
def set_scale(self, ax, scale):
455-
ax.set_xscale(scale)
420+
_rc_entry = 'keymap.yscale'
456421

457422

458423
class ToolViewsPositions(ToolBase):

‎lib/matplotlib/backend_tools.pyi

Copy file name to clipboardExpand all lines: lib/matplotlib/backend_tools.pyi
+10-15Lines changed: 10 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -58,21 +58,16 @@ class RubberbandBase(ToolBase):
5858
def draw_rubberband(self, *data) -> None: ...
5959
def remove_rubberband(self) -> None: ...
6060

61-
class ToolQuit(ToolBase): ...
62-
class ToolQuitAll(ToolBase): ...
63-
class ToolGrid(ToolBase): ...
64-
class ToolMinorGrid(ToolBase): ...
65-
class ToolFullScreen(ToolBase): ...
66-
67-
class AxisScaleBase(ToolToggleBase):
68-
def enable(self, event: ToolEvent | None = ...) -> None: ...
69-
def disable(self, event: ToolEvent | None = ...) -> None: ...
70-
71-
class ToolYScale(AxisScaleBase):
72-
def set_scale(self, ax: Axes, scale: str | ScaleBase) -> None: ...
73-
74-
class ToolXScale(AxisScaleBase):
75-
def set_scale(self, ax, scale: str | ScaleBase) -> None: ...
61+
class _ToolForwardingToClassicToolbar(ToolBase):
62+
_rc_entry: str
63+
64+
class ToolQuit(_ToolForwardingToClassicToolbar): ...
65+
class ToolQuitAll(_ToolForwardingToClassicToolbar): ...
66+
class ToolGrid(_ToolForwardingToClassicToolbar): ...
67+
class ToolMinorGrid(_ToolForwardingToClassicToolbar): ...
68+
class ToolFullScreen(_ToolForwardingToClassicToolbar): ...
69+
class ToolXScale(_ToolForwardingToClassicToolbar): ...
70+
class ToolYScale(_ToolForwardingToClassicToolbar): ...
7671

7772
class ToolViewsPositions(ToolBase):
7873
views: dict[Figure | Axes, cbook.Stack]

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.