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

Skip to content

Support ax.grid(visible=<bool>). #18769

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

Merged
merged 1 commit into from
Oct 20, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions lib/matplotlib/axes/_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -2976,8 +2976,6 @@ def grid(self, b=None, which='major', axis='both', **kwargs):
use `.set_axisbelow` or, for more control, call the
`~.Artist.set_zorder` method of each axis.
"""
if len(kwargs):
b = True
_api.check_in_list(['x', 'y', 'both'], axis=axis)
if axis in ['x', 'both']:
self.xaxis.grid(b, which=which, **kwargs)
Expand Down
43 changes: 23 additions & 20 deletions lib/matplotlib/axis.py
Original file line number Diff line number Diff line change
Expand Up @@ -790,10 +790,10 @@ def clear(self):
self.callbacks = cbook.CallbackRegistry()

# whether the grids are on
self._gridOnMajor = (
self._major_tick_kw['gridOn'] = (
mpl.rcParams['axes.grid'] and
mpl.rcParams['axes.grid.which'] in ('both', 'major'))
self._gridOnMinor = (
self._minor_tick_kw['gridOn'] = (
mpl.rcParams['axes.grid'] and
mpl.rcParams['axes.grid.which'] in ('both', 'minor'))

Expand Down Expand Up @@ -1398,7 +1398,6 @@ def get_major_ticks(self, numticks=None):
# Update the new tick label properties from the old.
tick = self._get_tick(major=True)
self.majorTicks.append(tick)
tick.gridline.set_visible(self._gridOnMajor)
self._copy_tick_props(self.majorTicks[0], tick)

return self.majorTicks[:numticks]
Expand All @@ -1412,7 +1411,6 @@ def get_minor_ticks(self, numticks=None):
# Update the new tick label properties from the old.
tick = self._get_tick(major=False)
self.minorTicks.append(tick)
tick.gridline.set_visible(self._gridOnMinor)
self._copy_tick_props(self.minorTicks[0], tick)

return self.minorTicks[:numticks]
Expand All @@ -1437,32 +1435,37 @@ def grid(self, b=None, which='major', **kwargs):
Define the line properties of the grid, e.g.::

grid(color='r', linestyle='-', linewidth=2)

"""
if len(kwargs):
if not b and b is not None: # something false-like but not None
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't we instead rename b to visible?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

b=None (== toggle) and visible=None (== False) behave differently. I think all these toggling APIs are pretty terrible, but breaking all the scripts in the world that do ax.grid() to toggle the grid on is just not worth it.

I guess we could aim to have the end API be def grid(visible=True, ...): (and deprecate b) though. Then the only case we'd break is people doing ax.grid() to switch off the grid when the grid is already on, which is probably much less common (and ax.grid(False) just seems much clearer). But let's keep that discussion for another time.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Uh, it's worse than I thought.

if b is not None:
if 'visible' in kwargs and bool(b) != bool(kwargs['visible']):
raise ValueError(
"'b' and 'visible' specify inconsistent grid visibilities")
if kwargs and not b: # something false-like but not None
cbook._warn_external('First parameter to grid() is false, '
'but line properties are supplied. The '
'grid will be enabled.')
b = True
b = True
which = which.lower()
_api.check_in_list(['major', 'minor', 'both'], which=which)
gridkw = {'grid_' + item[0]: item[1] for item in kwargs.items()}
if 'grid_visible' in gridkw:
forced_visibility = True
gridkw['gridOn'] = gridkw.pop('grid_visible')
else:
forced_visibility = False

if which in ['minor', 'both']:
if b is None:
self._gridOnMinor = not self._gridOnMinor
else:
self._gridOnMinor = b
self.set_tick_params(which='minor', gridOn=self._gridOnMinor,
**gridkw)
if b is None and not forced_visibility:
gridkw['gridOn'] = not self._minor_tick_kw['gridOn']
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this toggle the value in _minor_tick_kw?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

set_tick_params (called just below) does that.

elif b is not None:
gridkw['gridOn'] = b
self.set_tick_params(which='minor', **gridkw)
if which in ['major', 'both']:
if b is None:
self._gridOnMajor = not self._gridOnMajor
else:
self._gridOnMajor = b
self.set_tick_params(which='major', gridOn=self._gridOnMajor,
**gridkw)
if b is None and not forced_visibility:
gridkw['gridOn'] = not self._major_tick_kw['gridOn']
elif b is not None:
gridkw['gridOn'] = b
self.set_tick_params(which='major', **gridkw)
self.stale = True

def update_units(self, data):
Expand Down
44 changes: 27 additions & 17 deletions lib/matplotlib/tests/test_axes.py
Original file line number Diff line number Diff line change
Expand Up @@ -4577,25 +4577,35 @@ def test_twin_spines_on_top():
ax2.fill_between("i", "j", color='#7FC97F', alpha=.5, data=data)


def test_rcparam_grid_minor():
orig_grid = matplotlib.rcParams['axes.grid']
orig_locator = matplotlib.rcParams['axes.grid.which']

matplotlib.rcParams['axes.grid'] = True

values = (
('both', (True, True)),
('major', (True, False)),
('minor', (False, True))
)
@pytest.mark.parametrize("grid_which, major_visible, minor_visible", [
("both", True, True),
("major", True, False),
("minor", False, True),
])
def test_rcparam_grid_minor(grid_which, major_visible, minor_visible):
mpl.rcParams.update({"axes.grid": True, "axes.grid.which": grid_which})
fig, ax = plt.subplots()
fig.canvas.draw()
assert all(tick.gridline.get_visible() == major_visible
for tick in ax.xaxis.majorTicks)
assert all(tick.gridline.get_visible() == minor_visible
for tick in ax.xaxis.minorTicks)

for locator, result in values:
matplotlib.rcParams['axes.grid.which'] = locator
fig, ax = plt.subplots()
assert (ax.xaxis._gridOnMajor, ax.xaxis._gridOnMinor) == result

matplotlib.rcParams['axes.grid'] = orig_grid
matplotlib.rcParams['axes.grid.which'] = orig_locator
def test_grid():
fig, ax = plt.subplots()
ax.grid()
fig.canvas.draw()
assert ax.xaxis.majorTicks[0].gridline.get_visible()
ax.grid(visible=False)
fig.canvas.draw()
assert not ax.xaxis.majorTicks[0].gridline.get_visible()
ax.grid(visible=True)
fig.canvas.draw()
assert ax.xaxis.majorTicks[0].gridline.get_visible()
ax.grid()
fig.canvas.draw()
assert not ax.xaxis.majorTicks[0].gridline.get_visible()


def test_vline_limit():
Expand Down
18 changes: 9 additions & 9 deletions lib/mpl_toolkits/axisartist/axislines.py
Original file line number Diff line number Diff line change
Expand Up @@ -439,9 +439,9 @@ def get_gridlines(self, which="major", axis="both"):
if axis in ["both", "y"]:
x1, x2 = self.axes.get_xlim()
locs = []
if self.axes.yaxis._gridOnMajor:
if self.axes.yaxis._major_tick_kw["gridOn"]:
locs.extend(self.axes.yaxis.major.locator())
if self.axes.yaxis._gridOnMinor:
if self.axes.yaxis._minor_tick_kw["gridOn"]:
locs.extend(self.axes.yaxis.minor.locator())

for y in locs:
Expand Down Expand Up @@ -533,17 +533,17 @@ def grid(self, b=None, which='major', axis="both", **kwargs):
"""
Toggle the gridlines, and optionally set the properties of the lines.
"""
# their are some discrepancy between the behavior of grid in
# axes_grid and the original mpl's grid, because axes_grid
# explicitly set the visibility of the gridlines.
# There are some discrepancies in the behavior of grid() between
# axes_grid and Matplotlib, because axes_grid explicitly sets the
# visibility of the gridlines.
super().grid(b, which=which, axis=axis, **kwargs)
if not self._axisline_on:
return
if b is None:
b = (self.axes.xaxis._gridOnMinor
or self.axes.xaxis._gridOnMajor
or self.axes.yaxis._gridOnMinor
or self.axes.yaxis._gridOnMajor)
b = (self.axes.xaxis._minor_tick_kw["gridOn"]
or self.axes.xaxis._major_tick_kw["gridOn"]
or self.axes.yaxis._minor_tick_kw["gridOn"]
or self.axes.yaxis._major_tick_kw["gridOn"])
self.gridlines.set(which=which, axis=axis, visible=b)
self.gridlines.set(**kwargs)

Expand Down