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

Skip to content

Commit 4dfaca5

Browse files
committed
Support removing inner ticks in label_outer()
Up to now `label_outer()`, only affects tick labels, but not ticks. This introduces an optional parameter `remove_inner_ticks`, which removes the inner ticks if the corresponding tick labels are removed.
1 parent 5140177 commit 4dfaca5

File tree

4 files changed

+92
-24
lines changed

4 files changed

+92
-24
lines changed
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
Remove inner ticks in ``label_outer()``
2+
---------------------------------------
3+
Up to now, ``label_outer()`` has only removed the ticklabels. The ticks lines
4+
were left visible. This is now configurable through a new parameter
5+
``label_outer(remove_inner_ticks=True)``.
6+
7+
8+
.. plot::
9+
:include-source: true
10+
11+
import numpy as np
12+
import matplotlib.pyplot as plt
13+
14+
x = np.linspace(0, 2 * np.pi, 100)
15+
16+
fig, axs = plt.subplots(2, 2, sharex=True, sharey=True,
17+
gridspec_kw=dict(hspace=0, wspace=0))
18+
19+
axs[0, 0].plot(x, np.sin(x))
20+
axs[0, 1].plot(x, np.cos(x))
21+
axs[1, 0].plot(x, -np.cos(x))
22+
axs[1, 1].plot(x, -np.sin(x))
23+
24+
for ax in axs.flat:
25+
ax.grid(color='0.9')
26+
ax.label_outer(remove_inner_ticks=True)

lib/matplotlib/axes/_base.py

Lines changed: 28 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4490,18 +4490,28 @@ def get_shared_y_axes(self):
44904490
"""Return an immutable view on the shared y-axes Grouper."""
44914491
return cbook.GrouperView(self._shared_axes["y"])
44924492

4493-
def label_outer(self):
4493+
def label_outer(self, remove_inner_ticks=False):
44944494
"""
44954495
Only show "outer" labels and tick labels.
44964496
44974497
x-labels are only kept for subplots on the last row (or first row, if
44984498
labels are on the top side); y-labels only for subplots on the first
44994499
column (or last column, if labels are on the right side).
4500+
4501+
Parameters
4502+
----------
4503+
remove_inner_ticks : bool, default: False
4504+
If True, remove the inner ticks as well (not only tick labels).
4505+
4506+
.. versionadded:: 3.8
45004507
"""
4501-
self._label_outer_xaxis(skip_non_rectangular_axes=False)
4502-
self._label_outer_yaxis(skip_non_rectangular_axes=False)
4508+
self._label_outer_xaxis(skip_non_rectangular_axes=False,
4509+
remove_inner_ticks=remove_inner_ticks)
4510+
self._label_outer_yaxis(skip_non_rectangular_axes=False,
4511+
remove_inner_ticks=remove_inner_ticks)
45034512

4504-
def _label_outer_xaxis(self, *, skip_non_rectangular_axes):
4513+
def _label_outer_xaxis(self, *, skip_non_rectangular_axes,
4514+
remove_inner_ticks=False):
45054515
# see documentation in label_outer.
45064516
if skip_non_rectangular_axes and not isinstance(self.patch,
45074517
mpl.patches.Rectangle):
@@ -4513,17 +4523,22 @@ def _label_outer_xaxis(self, *, skip_non_rectangular_axes):
45134523
if not ss.is_first_row(): # Remove top label/ticklabels/offsettext.
45144524
if label_position == "top":
45154525
self.set_xlabel("")
4516-
self.xaxis.set_tick_params(which="both", labeltop=False)
4526+
top_kw = {'top': False} if remove_inner_ticks else {}
4527+
self.xaxis.set_tick_params(
4528+
which="both", labeltop=False, **top_kw)
45174529
if self.xaxis.offsetText.get_position()[1] == 1:
45184530
self.xaxis.offsetText.set_visible(False)
45194531
if not ss.is_last_row(): # Remove bottom label/ticklabels/offsettext.
45204532
if label_position == "bottom":
45214533
self.set_xlabel("")
4522-
self.xaxis.set_tick_params(which="both", labelbottom=False)
4534+
bottom_kw = {'bottom': False} if remove_inner_ticks else {}
4535+
self.xaxis.set_tick_params(
4536+
which="both", labelbottom=False, **bottom_kw)
45234537
if self.xaxis.offsetText.get_position()[1] == 0:
45244538
self.xaxis.offsetText.set_visible(False)
45254539

4526-
def _label_outer_yaxis(self, *, skip_non_rectangular_axes):
4540+
def _label_outer_yaxis(self, *, skip_non_rectangular_axes,
4541+
remove_inner_ticks=False):
45274542
# see documentation in label_outer.
45284543
if skip_non_rectangular_axes and not isinstance(self.patch,
45294544
mpl.patches.Rectangle):
@@ -4535,13 +4550,17 @@ def _label_outer_yaxis(self, *, skip_non_rectangular_axes):
45354550
if not ss.is_first_col(): # Remove left label/ticklabels/offsettext.
45364551
if label_position == "left":
45374552
self.set_ylabel("")
4538-
self.yaxis.set_tick_params(which="both", labelleft=False)
4553+
left_kw = {'left': False} if remove_inner_ticks else {}
4554+
self.yaxis.set_tick_params(
4555+
which="both", labelleft=False, **left_kw)
45394556
if self.yaxis.offsetText.get_position()[0] == 0:
45404557
self.yaxis.offsetText.set_visible(False)
45414558
if not ss.is_last_col(): # Remove right label/ticklabels/offsettext.
45424559
if label_position == "right":
45434560
self.set_ylabel("")
4544-
self.yaxis.set_tick_params(which="both", labelright=False)
4561+
right_kw = {'right': False} if remove_inner_ticks else {}
4562+
self.yaxis.set_tick_params(
4563+
which="both", labelright=False, **right_kw)
45454564
if self.yaxis.offsetText.get_position()[0] == 1:
45464565
self.yaxis.offsetText.set_visible(False)
45474566

lib/matplotlib/axes/_base.pyi

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -376,7 +376,7 @@ class _AxesBase(martist.Artist):
376376
def twiny(self) -> _AxesBase: ...
377377
def get_shared_x_axes(self) -> cbook.GrouperView: ...
378378
def get_shared_y_axes(self) -> cbook.GrouperView: ...
379-
def label_outer(self) -> None: ...
379+
def label_outer(self, remove_inner_ticks: bool = ...) -> None: ...
380380

381381
# The methods underneath this line are added via the `_axis_method_wrapper` class
382382
# Initially they are set to an object, but that object uses `__set_name__` to override

lib/matplotlib/tests/test_subplots.py

Lines changed: 37 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,8 @@ def check_shared(axs, x_shared, y_shared):
2424
i1, i2, "not " if shared[i1, i2] else "", name)
2525

2626

27-
def check_visible(axs, x_visible, y_visible):
27+
def check_ticklabel_visible(axs, x_visible, y_visible):
28+
"""Check that the x and y ticklabel visibility is as specified."""
2829
for i, (ax, vx, vy) in enumerate(zip(axs, x_visible, y_visible)):
2930
for l in ax.get_xticklabels() + [ax.xaxis.offsetText]:
3031
assert l.get_visible() == vx, \
@@ -40,6 +41,20 @@ def check_visible(axs, x_visible, y_visible):
4041
assert ax.get_ylabel() == ""
4142

4243

44+
def check_tick1_visible(axs, x_visible, y_visible):
45+
"""
46+
Check that the x and y tick visibility is as specified.
47+
48+
Note: This only checks the tick1line, i.e. bottom / left ticks.
49+
"""
50+
for ax, visible, in zip(axs, x_visible):
51+
for tick in ax.xaxis.get_major_ticks():
52+
assert tick.tick1line.get_visible() == visible
53+
for ax, y_visible, in zip(axs, y_visible):
54+
for tick in ax.yaxis.get_major_ticks():
55+
assert tick.tick1line.get_visible() == visible
56+
57+
4358
def test_shared():
4459
rdim = (4, 4, 2)
4560
share = {
@@ -90,16 +105,24 @@ def test_shared():
90105
f, ((a1, a2), (a3, a4)) = plt.subplots(2, 2, sharex=xo, sharey=yo)
91106
axs = [a1, a2, a3, a4]
92107
check_shared(axs, share[xo], share[yo])
93-
check_visible(axs, visible['x'][xo], visible['y'][yo])
108+
check_ticklabel_visible(axs, visible['x'][xo], visible['y'][yo])
94109
plt.close(f)
95110

96-
# test label_outer
97-
f, ((a1, a2), (a3, a4)) = plt.subplots(2, 2, sharex=True, sharey=True)
98-
axs = [a1, a2, a3, a4]
99-
for ax in axs:
111+
112+
@pytest.mark.parametrize('remove_ticks', [True, False])
113+
def test_label_outer(remove_ticks):
114+
f, axs = plt.subplots(2, 2, sharex=True, sharey=True)
115+
for ax in axs.flat:
100116
ax.set(xlabel="foo", ylabel="bar")
101-
ax.label_outer()
102-
check_visible(axs, [False, False, True, True], [True, False, True, False])
117+
ax.label_outer(remove_inner_ticks=remove_ticks)
118+
check_ticklabel_visible(
119+
axs.flat, [False, False, True, True], [True, False, True, False])
120+
if remove_ticks:
121+
check_tick1_visible(
122+
axs.flat, [False, False, True, True], [True, False, True, False])
123+
else:
124+
check_tick1_visible(
125+
axs.flat, [True, True, True, True], [True, True, True, True])
103126

104127

105128
def test_label_outer_span():
@@ -118,28 +141,28 @@ def test_label_outer_span():
118141
a4 = fig.add_subplot(gs[2, 1])
119142
for ax in fig.axes:
120143
ax.label_outer()
121-
check_visible(
144+
check_ticklabel_visible(
122145
fig.axes, [False, True, False, True], [True, True, False, False])
123146

124147

125148
def test_label_outer_non_gridspec():
126149
ax = plt.axes((0, 0, 1, 1))
127150
ax.label_outer() # Does nothing.
128-
check_visible([ax], [True], [True])
151+
check_ticklabel_visible([ax], [True], [True])
129152

130153

131154
def test_shared_and_moved():
132155
# test if sharey is on, but then tick_left is called that labels don't
133156
# re-appear. Seaborn does this just to be sure yaxis is on left...
134157
f, (a1, a2) = plt.subplots(1, 2, sharey=True)
135-
check_visible([a2], [True], [False])
158+
check_ticklabel_visible([a2], [True], [False])
136159
a2.yaxis.tick_left()
137-
check_visible([a2], [True], [False])
160+
check_ticklabel_visible([a2], [True], [False])
138161

139162
f, (a1, a2) = plt.subplots(2, 1, sharex=True)
140-
check_visible([a1], [False], [True])
163+
check_ticklabel_visible([a1], [False], [True])
141164
a2.xaxis.tick_bottom()
142-
check_visible([a1], [False], [True])
165+
check_ticklabel_visible([a1], [False], [True])
143166

144167

145168
def test_exceptions():

0 commit comments

Comments
 (0)