Skip to content

Fix default label visibility for top-or-left-labeled shared subplots(). #19472

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
Feb 18, 2021
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
10 changes: 10 additions & 0 deletions doc/users/next_whats_new/top-left-shared-subplots.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
Shared-axes ``subplots`` tick label visibility is now correct for top or left labels
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
When calling ``subplots(..., sharex=True, sharey=True)``, Matplotlib
automatically hides x tick labels for axes not in the first column and y tick
labels for axes not in the last row. This behavior is incorrect if rcParams
specify that axes should be labeled on the top (``rcParams["xtick.labeltop"] =
True``) or on the right (``rcParams["ytick.labelright"] = True``).

Such cases are now handled correctly (adjusting visibility as needed on the
first row and last column of axes).
26 changes: 16 additions & 10 deletions lib/matplotlib/gridspec.py
Original file line number Diff line number Diff line change
Expand Up @@ -309,17 +309,23 @@ def subplots(self, *, sharex=False, sharey=False, squeeze=True,

# turn off redundant tick labeling
if sharex in ["col", "all"]:
# turn off all but the bottom row
for ax in axarr[:-1, :].flat:
ax.xaxis.set_tick_params(which='both',
labelbottom=False, labeltop=False)
ax.xaxis.offsetText.set_visible(False)
for ax in axarr[:-1, :].flat: # Remove bottom labels/offsettexts.
ax.xaxis.set_tick_params(which="both", labelbottom=False)
if ax.xaxis.offsetText.get_position()[1] == 0:
ax.xaxis.offsetText.set_visible(False)
for ax in axarr[1:, :].flat: # Remove top labels/offsettexts.
ax.xaxis.set_tick_params(which="both", labeltop=False)
if ax.xaxis.offsetText.get_position()[1] == 1:
ax.xaxis.offsetText.set_visible(False)
if sharey in ["row", "all"]:
# turn off all but the first column
for ax in axarr[:, 1:].flat:
ax.yaxis.set_tick_params(which='both',
labelleft=False, labelright=False)
ax.yaxis.offsetText.set_visible(False)
for ax in axarr[:, 1:].flat: # Remove left labels/offsettexts.
ax.yaxis.set_tick_params(which="both", labelleft=False)
if ax.yaxis.offsetText.get_position()[0] == 0:
ax.yaxis.offsetText.set_visible(False)
for ax in axarr[:, :-1].flat: # Remove right labels/offsettexts.
ax.yaxis.set_tick_params(which="both", labelright=False)
if ax.yaxis.offsetText.get_position()[0] == 1:
ax.yaxis.offsetText.set_visible(False)

if squeeze:
# Discarding unneeded dimensions that equal 1. If we only have one
Expand Down
22 changes: 22 additions & 0 deletions lib/matplotlib/tests/test_subplots.py
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,28 @@ def test_subplots_offsettext():
axs[1, 1].plot(y, x)


@pytest.mark.parametrize("top", [True, False])
@pytest.mark.parametrize("bottom", [True, False])
@pytest.mark.parametrize("left", [True, False])
@pytest.mark.parametrize("right", [True, False])
def test_subplots_hide_labels(top, bottom, left, right):
# Ideally, we would also test offset-text visibility (and remove
# test_subplots_offsettext), but currently, setting rcParams fails to move
# the offset texts as well.
with plt.rc_context({"xtick.labeltop": top, "xtick.labelbottom": bottom,
"ytick.labelleft": left, "ytick.labelright": right}):
axs = plt.figure().subplots(3, 3, sharex=True, sharey=True)
for (i, j), ax in np.ndenumerate(axs):
xtop = ax.xaxis._major_tick_kw["label2On"]
xbottom = ax.xaxis._major_tick_kw["label1On"]
yleft = ax.yaxis._major_tick_kw["label1On"]
yright = ax.yaxis._major_tick_kw["label2On"]
assert xtop == (top and i == 0)
assert xbottom == (bottom and i == 2)
assert yleft == (left and j == 0)
assert yright == (right and j == 2)


def test_get_gridspec():
# ahem, pretty trivial, but...
fig, ax = plt.subplots()
Expand Down