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

Skip to content

Commit 22aa800

Browse files
authored
Merge pull request #6875 from anntzer/keymap-grid-minor
ENH: Add keymap (default: G) to toggle minor grid.
2 parents 30c9e8f + 0658c2b commit 22aa800

File tree

6 files changed

+128
-25
lines changed

6 files changed

+128
-25
lines changed
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
Improved toggling of the axes grids
2+
-----------------------------------
3+
The `g` key binding now switches the states of the `x` and `y` grids
4+
independently (by cycling through all four on/off combinations).
5+
6+
The new `G` key binding switches the states of the minor grids.
7+
8+
Both bindings are disabled if only a subset of the grid lines (in either
9+
direction) is visible, to avoid making irreversible changes to the figure.

doc/users/navigation_toolbar.rst

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,8 @@ Close all plots **shift** + **w**
9999
Constrain pan/zoom to x axis hold **x** when panning/zooming with mouse
100100
Constrain pan/zoom to y axis hold **y** when panning/zooming with mouse
101101
Preserve aspect ratio hold **CONTROL** when panning/zooming with mouse
102-
Toggle grid **g** when mouse is over an axes
102+
Toggle major grids **g** when mouse is over an axes
103+
Toggle minor grids **G** when mouse is over an axes
103104
Toggle x axis scale (log/linear) **L** or **k** when mouse is over an axes
104105
Toggle y axis scale (log/linear) **l** when mouse is over an axes
105106
================================== =================================================

lib/matplotlib/backend_bases.py

Lines changed: 51 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2482,9 +2482,10 @@ def key_press_handler(event, canvas, toolbar=None):
24822482
save_keys = rcParams['keymap.save']
24832483
quit_keys = rcParams['keymap.quit']
24842484
grid_keys = rcParams['keymap.grid']
2485+
grid_minor_keys = rcParams['keymap.grid_minor']
24852486
toggle_yscale_keys = rcParams['keymap.yscale']
24862487
toggle_xscale_keys = rcParams['keymap.xscale']
2487-
all = rcParams['keymap.all_axes']
2488+
all_keys = rcParams['keymap.all_axes']
24882489

24892490
# toggle fullscreen mode (default key 'f')
24902491
if event.key in fullscreen_keys:
@@ -2524,33 +2525,72 @@ def key_press_handler(event, canvas, toolbar=None):
25242525
return
25252526

25262527
# these bindings require the mouse to be over an axes to trigger
2528+
def _get_uniform_gridstate(ticks):
2529+
# Return True/False if all grid lines are on or off, None if they are
2530+
# not all in the same state.
2531+
if all(tick.gridOn for tick in ticks):
2532+
return True
2533+
elif not any(tick.gridOn for tick in ticks):
2534+
return False
2535+
else:
2536+
return None
25272537

2528-
# switching on/off a grid in current axes (default key 'g')
2538+
ax = event.inaxes
2539+
# toggle major grids in current axes (default key 'g')
2540+
# Both here and below (for 'G'), we do nothing is the grids are not in a
2541+
# uniform state, to avoid messing up user customization.
25292542
if event.key in grid_keys:
2530-
event.inaxes.grid()
2531-
canvas.draw()
2543+
x_state = _get_uniform_gridstate(ax.xaxis.majorTicks)
2544+
y_state = _get_uniform_gridstate(ax.yaxis.majorTicks)
2545+
cycle = [(False, False), (True, False), (True, True), (False, True)]
2546+
try:
2547+
x_state, y_state = (
2548+
cycle[(cycle.index((x_state, y_state)) + 1) % len(cycle)])
2549+
except ValueError:
2550+
# Exclude major grids not in a uniform state.
2551+
pass
2552+
else:
2553+
ax.grid(x_state, which="major", axis="x")
2554+
ax.grid(y_state, which="major", axis="y")
2555+
canvas.draw_idle()
2556+
# toggle major and minor grids in current axes (default key 'G')
2557+
if (event.key in grid_minor_keys
2558+
# Exclude major grids not in a uniform state.
2559+
and None not in [_get_uniform_gridstate(ax.xaxis.majorTicks),
2560+
_get_uniform_gridstate(ax.yaxis.majorTicks)]):
2561+
x_state = _get_uniform_gridstate(ax.xaxis.minorTicks)
2562+
y_state = _get_uniform_gridstate(ax.yaxis.minorTicks)
2563+
cycle = [(False, False), (True, False), (True, True), (False, True)]
2564+
try:
2565+
x_state, y_state = (
2566+
cycle[(cycle.index((x_state, y_state)) + 1) % len(cycle)])
2567+
except ValueError:
2568+
# Exclude minor grids not in a uniform state.
2569+
pass
2570+
else:
2571+
ax.grid(x_state, which="both", axis="x")
2572+
ax.grid(y_state, which="both", axis="y")
2573+
canvas.draw_idle()
25322574
# toggle scaling of y-axes between 'log and 'linear' (default key 'l')
25332575
elif event.key in toggle_yscale_keys:
2534-
ax = event.inaxes
25352576
scale = ax.get_yscale()
25362577
if scale == 'log':
25372578
ax.set_yscale('linear')
2538-
ax.figure.canvas.draw()
2579+
ax.figure.canvas.draw_idle()
25392580
elif scale == 'linear':
25402581
ax.set_yscale('log')
2541-
ax.figure.canvas.draw()
2582+
ax.figure.canvas.draw_idle()
25422583
# toggle scaling of x-axes between 'log and 'linear' (default key 'k')
25432584
elif event.key in toggle_xscale_keys:
2544-
ax = event.inaxes
25452585
scalex = ax.get_xscale()
25462586
if scalex == 'log':
25472587
ax.set_xscale('linear')
2548-
ax.figure.canvas.draw()
2588+
ax.figure.canvas.draw_idle()
25492589
elif scalex == 'linear':
25502590
ax.set_xscale('log')
2551-
ax.figure.canvas.draw()
2591+
ax.figure.canvas.draw_idle()
25522592

2553-
elif (event.key.isdigit() and event.key != '0') or event.key in all:
2593+
elif (event.key.isdigit() and event.key != '0') or event.key in all_keys:
25542594
# keys in list 'all' enables all axes (default key 'a'),
25552595
# otherwise if key is a number only enable this particular axes
25562596
# if it was the axes, where the event was raised

lib/matplotlib/backend_tools.py

Lines changed: 63 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -420,24 +420,74 @@ def trigger(self, sender, event, data=None):
420420
a.set_navigate(i == n)
421421

422422

423-
class ToolGrid(ToolToggleBase):
424-
"""Tool to toggle the grid of the figure"""
423+
class _ToolGridBase(ToolBase):
424+
"""Common functionality between ToolGrid and ToolMinorGrid."""
425425

426-
description = 'Toogle Grid'
427-
default_keymap = rcParams['keymap.grid']
426+
_cycle = [(False, False), (True, False), (True, True), (False, True)]
428427

429428
def trigger(self, sender, event, data=None):
430-
if event.inaxes is None:
429+
ax = event.inaxes
430+
if ax is None:
431431
return
432-
ToolToggleBase.trigger(self, sender, event, data)
432+
try:
433+
x_state, y_state, which = self._get_next_grid_states(ax)
434+
except ValueError:
435+
pass
436+
else:
437+
ax.grid(x_state, which=which, axis="x")
438+
ax.grid(y_state, which=which, axis="y")
439+
ax.figure.canvas.draw_idle()
433440

434-
def enable(self, event):
435-
event.inaxes.grid(True)
436-
self.figure.canvas.draw_idle()
441+
@staticmethod
442+
def _get_uniform_grid_state(ticks):
443+
"""
444+
Check whether all grid lines are in the same visibility state.
437445
438-
def disable(self, event):
439-
event.inaxes.grid(False)
440-
self.figure.canvas.draw_idle()
446+
Returns True/False if all grid lines are on or off, None if they are
447+
not all in the same state.
448+
"""
449+
if all(tick.gridOn for tick in ticks):
450+
return True
451+
elif not any(tick.gridOn for tick in ticks):
452+
return False
453+
else:
454+
return None
455+
456+
457+
class ToolGrid(_ToolGridBase):
458+
"""Tool to toggle the major grids of the figure"""
459+
460+
description = 'Toogle major grids'
461+
default_keymap = rcParams['keymap.grid']
462+
463+
def _get_next_grid_states(self, ax):
464+
x_state, y_state = map(self._get_uniform_grid_state,
465+
[ax.xaxis.majorTicks, ax.yaxis.majorTicks])
466+
cycle = self._cycle
467+
# Bail out (via ValueError) if major grids are not in a uniform state.
468+
x_state, y_state = (
469+
cycle[(cycle.index((x_state, y_state)) + 1) % len(cycle)])
470+
return x_state, y_state, "major"
471+
472+
473+
class ToolMinorGrid(_ToolGridBase):
474+
"""Tool to toggle the major and minor grids of the figure"""
475+
476+
description = 'Toogle major and minor grids'
477+
default_keymap = rcParams['keymap.grid_minor']
478+
479+
def _get_next_grid_states(self, ax):
480+
if None in map(self._get_uniform_grid_state,
481+
[ax.xaxis.majorTicks, ax.yaxis.majorTicks]):
482+
# Bail out if major grids are not in a uniform state.
483+
raise ValueError
484+
x_state, y_state = map(self._get_uniform_grid_state,
485+
[ax.xaxis.minorTicks, ax.yaxis.minorTicks])
486+
cycle = self._cycle
487+
# Bail out (via ValueError) if minor grids are not in a uniform state.
488+
x_state, y_state = (
489+
cycle[(cycle.index((x_state, y_state)) + 1) % len(cycle)])
490+
return x_state, y_state, "both"
441491

442492

443493
class ToolFullScreen(ToolToggleBase):
@@ -965,6 +1015,7 @@ def _mouse_move(self, event):
9651015
'subplots': 'ToolConfigureSubplots',
9661016
'save': 'ToolSaveFigure',
9671017
'grid': ToolGrid,
1018+
'grid_minor': ToolMinorGrid,
9681019
'fullscreen': ToolFullScreen,
9691020
'quit': ToolQuit,
9701021
'quit_all': ToolQuitAll,

lib/matplotlib/rcsetup.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1313,6 +1313,7 @@ def validate_animation_writer_path(p):
13131313
'keymap.quit': [['ctrl+w', 'cmd+w', 'q'], validate_stringlist],
13141314
'keymap.quit_all': [['W', 'cmd+W', 'Q'], validate_stringlist],
13151315
'keymap.grid': [['g'], validate_stringlist],
1316+
'keymap.grid_minor': [['G'], validate_stringlist],
13161317
'keymap.yscale': [['l'], validate_stringlist],
13171318
'keymap.xscale': [['k', 'L'], validate_stringlist],
13181319
'keymap.all_axes': [['a'], validate_stringlist],

matplotlibrc.template

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -584,7 +584,8 @@ backend : $TEMPLATE_BACKEND
584584
#keymap.zoom : o # zoom mnemonic
585585
#keymap.save : s # saving current figure
586586
#keymap.quit : ctrl+w, cmd+w # close the current figure
587-
#keymap.grid : g # switching on/off a grid in current axes
587+
#keymap.grid : g # switching on/off major grids in current axes
588+
#keymap.grid_minor : G # switching on/off minor grids in current axes
588589
#keymap.yscale : l # toggle scaling of y-axes ('log'/'linear')
589590
#keymap.xscale : L, k # toggle scaling of x-axes ('log'/'linear')
590591
#keymap.all_axes : a # enable all axes

0 commit comments

Comments
 (0)