8000 Support removing inner ticks in label_outer() · matplotlib/matplotlib@42ed78f · GitHub
[go: up one dir, main page]

Skip to content

Commit 42ed78f

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 3d6c3da commit 42ed78f

File tree

3 files changed

+87
-23
lines changed

3 files changed

+87
-23
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: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4586,18 +4586,25 @@ def get_shared_y_axes(self):
45864586
"""Return an immutable view on the shared y-axes Grouper."""
45874587
return cbook.GrouperView(self._shared_axes["y"])
45884588

4589-
def label_outer(self):
4589+
def label_outer(self, remove_inner_ticks=False):
45904590
"""
45914591
Only show "outer" labels and tick labels.
45924592
45934593
x-labels are only kept for subplots on the last row (or first row, if
45944594
labels are on the top side); y-labels only for subplots on the first
45954595
column (or last column, if labels are on the right side).
4596+
4597+
Parameters
4598+
----------
4599+
remove_inner_ticks : bool, default: False
4600+
If True, remove the inner ticks as well (not only tick labels).
45964601
"""
4597-
self._label_outer_xaxis(check_patch=False)
4598-
self._label_outer_yaxis(check_patch=False)
4602+
self._label_outer_xaxis(check_patch=False,
4603+
remove_inner_ticks=remove_inner_ticks)
4604+
self._label_outer_yaxis(check_patch=False,
4605+
remove_inner_ticks=remove_inner_ticks)
45994606

4600-
def _label_outer_xaxis(self, *, check_patch):
4607+
def _label_outer_xaxis(self, *, check_patch, remove_inner_ticks=False):
46014608
# see documentation in label_outer.
46024609
if check_patch and not isinstance(self.patch, mpl.patches.Rectangle):
46034610
return
@@ -4608,17 +4615,21 @@ def _label_outer_xaxis(self, *, check_patch):
46084615
if not ss.is_first_row(): # Remove top label/ticklabels/offsettext.
46094616
if label_position == "top":
46104617
self.set_xlabel("")
4611-
self.xaxis.set_tick_params(which="both", labeltop=False)
4618+
top_kw = {'top': False} if remove_inner_ticks else {}
4619+
self.xaxis.set_tick_params(
4620+
which="both", labeltop=False, **top_kw)
46124621
if self.xaxis.offsetText.get_position()[1] == 1:
46134622
self.xaxis.offsetText.set_visible(False)
46144623
if not ss.is_last_row(): # Remove bottom label/ticklabels/offsettext.
46154624
if label_position == "bottom":
46164625
self.set_xlabel("")
4617-
self.xaxis.set_tick_params(which="both", labelbottom=False)
4626+
bottom_kw = {'bottom': False} if remove_inner_ticks else {}
4627+
self.xaxis.set_tick_params(
4628+
which="both", labelbottom=False, **bottom_kw)
46184629
if self.xaxis.offsetText.get_position()[1] == 0:
46194630
self.xaxis.offsetText.set_visible(False)
46204631

4621-
def _label_outer_yaxis(self, *, check_patch):
4632+
def _label_outer_yaxis(self, *, check_patch, remove_inner_ticks=False):
46224633
# see documentation in label_outer.
46234634
if check_patch and not isinstance(self.patch, mpl.patches.Rectangle):
46244635
return
@@ -4629,12 +4640,16 @@ def _label_outer_yaxis(self, *, check_patch):
46294640
if not ss.is_first_col(): # Remove left label/ticklabels/offsettext.
46304641
if label_position == "left":
46314642
self.set_ylabel("")
4632-
self.yaxis.set_tick_params(which="both", labelleft=False)
4643+
left_kw = {'left': False} if remove_inner_ticks else {}
4644+
self.yaxis.set_tick_params(
4645+
which="both", labelleft=False, **left_kw)
46334646
if self.yaxis.offsetText.get_position()[0] == 0:
46344647
self.yaxis.offsetText.set_visible(False)
46354648
if not ss.is_last_col(): # Remove right label/ticklabels/offsettext.
46364649
if label_position == "right":
46374650
self.set_ylabel("")
4638-
self.yaxis.set_tick_params(which="both", labelright=False)
4651+
right_kw = {'right': False} if remove_inner_ticks else {}
4652+
self.yaxis.set_tick_params(
4653+
which="both", labelright=False, **right_kw)
46394654
if self.yaxis.offsetText.get_position()[0] == 1:
46404655
self.yaxis.offsetText.set_visible(False)

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)
0