From 9e5b1d6589043c8f530ce64c67274d314b742f22 Mon Sep 17 00:00:00 2001 From: Tim Hoffmann <2836374+timhoffm@users.noreply.github.com> Date: Thu, 22 Apr 2021 23:46:13 +0200 Subject: [PATCH] Add labels parameter to set_ticks() --- doc/users/next_whats_new/set_ticks_labels.rst | 16 +++++ lib/matplotlib/axes/_secondary_axes.py | 16 ++--- lib/matplotlib/axis.py | 67 ++++++++++++------- lib/matplotlib/tests/test_axes.py | 22 ++++++ 4 files changed, 85 insertions(+), 36 deletions(-) create mode 100644 doc/users/next_whats_new/set_ticks_labels.rst diff --git a/doc/users/next_whats_new/set_ticks_labels.rst b/doc/users/next_whats_new/set_ticks_labels.rst new file mode 100644 index 000000000000..7cb6692d5260 --- /dev/null +++ b/doc/users/next_whats_new/set_ticks_labels.rst @@ -0,0 +1,16 @@ +Settings tick positions and labels simultaneously in ``set_ticks`` +------------------------------------------------------------------ +`.Axis.set_ticks` (and the corresponding `.Axes.set_xticks` / +`.Axes.set_yticks`) got a new parameter *labels* allowing to set tick positions +and labels simultaneously. + +Previously, setting tick labels was done using `.Axis.set_ticklabels` (or +the corresponding `.Axes.set_xticklabels` / `.Axes.set_yticklabels`). This +usually only makes sense if you previously fix the position with +`~.Axis.set_ticks`. Both functionality is now available in `~.Axis.set_ticks`. +The use of `.Axis.set_ticklabels` is discouraged, but it will stay available +for backward compatibility. + +Note: This addition makes the API of `~.Axis.set_ticks` also more similar to +`.pyplot.xticks` / `.pyplot.yticks`, which already had the additional *labels* +parameter. diff --git a/lib/matplotlib/axes/_secondary_axes.py b/lib/matplotlib/axes/_secondary_axes.py index 98a612013a16..874a36c9d60f 100644 --- a/lib/matplotlib/axes/_secondary_axes.py +++ b/lib/matplotlib/axes/_secondary_axes.py @@ -4,6 +4,7 @@ import matplotlib.docstring as docstring import matplotlib.ticker as mticker from matplotlib.axes._base import _AxesBase, _TransformedBoundsLocator +from matplotlib.axis import Axis class SecondaryAxis(_AxesBase): @@ -123,18 +124,9 @@ def apply_aspect(self, position=None): self._set_lims() super().apply_aspect(position) - def set_ticks(self, ticks, *, minor=False): - """ - Set the x ticks with list of *ticks* - - Parameters - ---------- - ticks : list - List of x-axis tick locations. - minor : bool, default: False - If ``False`` sets major ticks, if ``True`` sets minor ticks. - """ - ret = self._axis.set_ticks(ticks, minor=minor) + @docstring.copy(Axis.set_ticks) + def set_ticks(self, ticks, labels=None, *, minor=False, **kwargs): + ret = self._axis.set_ticks(ticks, labels, minor=minor, **kwargs) self.stale = True self._ticks_set = True return ret diff --git a/lib/matplotlib/axis.py b/lib/matplotlib/axis.py index 39fa5d40fb97..9a7dffe1bf56 100644 --- a/lib/matplotlib/axis.py +++ b/lib/matplotlib/axis.py @@ -1661,10 +1661,16 @@ def set_ticklabels(self, ticklabels, *, minor=False, **kwargs): r""" Set the text values of the tick labels. - .. warning:: - This method should only be used after fixing the tick positions - using `.Axis.set_ticks`. Otherwise, the labels may end up in - unexpected positions. + .. admonition:: Discouraged + + The use of this method is discouraged, because of the dependency + on tick positions. In most cases, you'll want to use + ``set_[x/y]ticks(positions, labels)`` instead. + + If you are using this method, you should always fix the tick + positions before, e.g. by using `.Axis.set_ticks` or by explicitly + setting a `~.ticker.FixedLocator`. Otherwise, ticks are free to + move and the labels may end up in unexpected positions. Parameters ---------- @@ -1772,27 +1778,9 @@ def _set_ticklabels(self, labels, fontdict=None, minor=False, **kwargs): kwargs.update(fontdict) return self.set_ticklabels(labels, minor=minor, **kwargs) - def set_ticks(self, ticks, *, minor=False): - """ - Set this Axis' tick locations. - - If necessary, the view limits of the Axis are expanded so that all - given ticks are visible. + def _set_tick_locations(self, ticks, *, minor=False): + # see docstring of set_ticks - Parameters - ---------- - ticks : list of floats - List of tick locations. - minor : bool, default: False - If ``False``, set the major ticks; if ``True``, the minor ticks. - - Notes - ----- - The mandatory expansion of the view limits is an intentional design - choice to prevent the surprise of a non-visible tick. If you need - other limits, you should set the limits explicitly after setting the - ticks. - """ # XXX if the user changes units, the information will be lost here ticks = self.convert_units(ticks) if self is self.axes.xaxis: @@ -1827,6 +1815,37 @@ def set_ticks(self, ticks, *, minor=False): self.set_major_locator(mticker.FixedLocator(ticks)) return self.get_major_ticks(len(ticks)) + def set_ticks(self, ticks, labels=None, *, minor=False, **kwargs): + """ + Set this Axis' tick locations and optionally labels. + + If necessary, the view limits of the Axis are expanded so that all + given ticks are visible. + + Parameters + ---------- + ticks : list of floats + List of tick locations. + labels : list of str, optional + List of tick labels. If not set, the labels show the data value. + minor : bool, default: False + If ``False``, set the major ticks; if ``True``, the minor ticks. + **kwargs + `.Text` properties for the labels. These take effect only if you + pass *labels*. In other cases, please use `~.Axes.tick_params`. + + Notes + ----- + The mandatory expansion of the view limits is an intentional design + choice to prevent the surprise of a non-visible tick. If you need + other limits, you should set the limits explicitly after setting the + ticks. + """ + result = self._set_tick_locations(ticks, minor=minor) + if labels is not None: + self.set_ticklabels(labels, minor=minor, **kwargs) + return result + def _get_tick_boxes_siblings(self, renderer): """ Get the bounding boxes for this `.axis` and its siblings diff --git a/lib/matplotlib/tests/test_axes.py b/lib/matplotlib/tests/test_axes.py index b8685ba790d0..ee28041a1f4e 100644 --- a/lib/matplotlib/tests/test_axes.py +++ b/lib/matplotlib/tests/test_axes.py @@ -5107,6 +5107,28 @@ def test_set_get_ticklabels(): ax[1].set_yticklabels(ax[0].get_yticklabels()) +@check_figures_equal(extensions=["png"]) +def test_set_ticks_with_labels(fig_test, fig_ref): + """ + Test that these two are identical:: + + set_xticks(ticks); set_xticklabels(labels, **kwargs) + set_xticks(ticks, labels, **kwargs) + + """ + ax = fig_ref.subplots() + ax.set_xticks([1, 2, 4, 6]) + ax.set_xticklabels(['a', 'b', 'c', 'd'], fontweight='bold') + ax.set_yticks([1, 3, 5]) + ax.set_yticks([2, 4], minor=True) + ax.set_yticklabels(['A', 'B'], minor=True) + + ax = fig_test.subplots() + ax.set_xticks([1, 2, 4, 6], ['a', 'b', 'c', 'd'], fontweight='bold') + ax.set_yticks([1, 3, 5]) + ax.set_yticks([2, 4], ['A', 'B'], minor=True) + + def test_subsampled_ticklabels(): # test issue 11937 fig, ax = plt.subplots()
Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.
Alternative Proxies: