From dd8e4b53c55a175036d7d3b8d80a827ed1a83c28 Mon Sep 17 00:00:00 2001 From: Eric Firing Date: Tue, 28 Apr 2020 15:25:57 -1000 Subject: [PATCH 01/13] BUG fixed by @anntzer: correct tick labels with subsampled FixedLocator When explicitly setting the tick locations and then the corresponding tick labels, a FixedLocator is used for the locations. It has an nbins argument that can trigger subsampling. Previously, tick labels were made by FixedFormatter and based on position, not value, so subsampling caused a mismatch, yielding incorrect tick labels. This is changed to use FuncFormatter with a function to look up the label by value, ignoring the position. --- lib/matplotlib/axis.py | 11 +++++++++-- lib/matplotlib/ticker.py | 8 ++++++++ 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/lib/matplotlib/axis.py b/lib/matplotlib/axis.py index 359999c73720..e7d4117a89fa 100644 --- a/lib/matplotlib/axis.py +++ b/lib/matplotlib/axis.py @@ -1626,11 +1626,18 @@ def set_ticklabels(self, ticklabels, *, minor=False, **kwargs): """ ticklabels = [t.get_text() if hasattr(t, 'get_text') else t for t in ticklabels] + locator = (self.get_minor_locator() if minor + else self.get_major_locator()) + if isinstance(locator, mticker.FixedLocator): + formatter = mticker.FuncFormatter( + lambda x, pos: ticklabels[[*locator.locs].index(x)]) + else: + formatter = mticker.FixedFormatter(ticklabels) if minor: - self.set_minor_formatter(mticker.FixedFormatter(ticklabels)) + self.set_minor_formatter(formatter) ticks = self.get_minor_ticks() else: - self.set_major_formatter(mticker.FixedFormatter(ticklabels)) + self.set_major_formatter(formatter) ticks = self.get_major_ticks() ret = [] for tick_label, tick in zip(ticklabels, ticks): diff --git a/lib/matplotlib/ticker.py b/lib/matplotlib/ticker.py index 277f55a1afab..689db7fb6b6d 100644 --- a/lib/matplotlib/ticker.py +++ b/lib/matplotlib/ticker.py @@ -381,8 +381,10 @@ class FuncFormatter(Formatter): position ``pos``), and return a string containing the corresponding tick label. """ + def __init__(self, func): self.func = func + self.offset_string = "" def __call__(self, x, pos=None): """ @@ -392,6 +394,12 @@ def __call__(self, x, pos=None): """ return self.func(x, pos) + def get_offset(self): + return self.offset_string + + def set_offset_string(self, ofs): + self.offset_string = ofs + class FormatStrFormatter(Formatter): """ From e44d74afb3d825b964fec5fa68310156c1c1ce05 Mon Sep 17 00:00:00 2001 From: Eric Firing Date: Tue, 28 Apr 2020 21:06:59 -1000 Subject: [PATCH 02/13] Handle missing values. --- lib/matplotlib/axis.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/matplotlib/axis.py b/lib/matplotlib/axis.py index e7d4117a89fa..05e44e4cc5d0 100644 --- a/lib/matplotlib/axis.py +++ b/lib/matplotlib/axis.py @@ -1629,8 +1629,8 @@ def set_ticklabels(self, ticklabels, *, minor=False, **kwargs): locator = (self.get_minor_locator() if minor else self.get_major_locator()) if isinstance(locator, mticker.FixedLocator): - formatter = mticker.FuncFormatter( - lambda x, pos: ticklabels[[*locator.locs].index(x)]) + tickd = {loc:lab for loc, lab in zip(locator.locs, ticklabels)} + formatter = mticker.FuncFormatter(lambda x, pos: tickd.get(x, "")) else: formatter = mticker.FixedFormatter(ticklabels) if minor: From 433308c8cbb56cab26352b11c60533c6a981ca47 Mon Sep 17 00:00:00 2001 From: Eric Firing Date: Wed, 29 Apr 2020 13:09:02 -1000 Subject: [PATCH 03/13] Keep ticks and labels in sync; add a test. --- lib/matplotlib/axes/_base.py | 1 + lib/matplotlib/axis.py | 5 ++++- lib/matplotlib/tests/test_axes.py | 12 ++++++++++++ 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/lib/matplotlib/axes/_base.py b/lib/matplotlib/axes/_base.py index 5b105e13aeeb..eb0d365fa0c2 100644 --- a/lib/matplotlib/axes/_base.py +++ b/lib/matplotlib/axes/_base.py @@ -3016,6 +3016,7 @@ def locator_params(self, axis='both', tight=None, **kwargs): self.yaxis.get_major_locator().set_params(**kwargs) self._request_autoscale_view(tight=tight, scalex=update_x, scaley=update_y) + self.stale = True def tick_params(self, axis='both', **kwargs): """ diff --git a/lib/matplotlib/axis.py b/lib/matplotlib/axis.py index 05e44e4cc5d0..d57e640ace1d 100644 --- a/lib/matplotlib/axis.py +++ b/lib/matplotlib/axis.py @@ -1639,8 +1639,11 @@ def set_ticklabels(self, ticklabels, *, minor=False, **kwargs): else: self.set_major_formatter(formatter) ticks = self.get_major_ticks() + + self._update_ticks() ret = [] - for tick_label, tick in zip(ticklabels, ticks): + for pos, tick in enumerate(ticks): + tick_label = formatter(tick._loc, pos) # deal with label1 tick.label1.set_text(tick_label) tick.label1.update(kwargs) diff --git a/lib/matplotlib/tests/test_axes.py b/lib/matplotlib/tests/test_axes.py index faf024a02512..9f8aea250ef2 100644 --- a/lib/matplotlib/tests/test_axes.py +++ b/lib/matplotlib/tests/test_axes.py @@ -4452,6 +4452,18 @@ def test_set_get_ticklabels(): ax[1].set_yticklabels(ax[0].get_yticklabels()) +def test_subsampled_ticklabels(): + # test issue 11937 + fig, ax = plt.subplots() + ax.plot(np.arange(10)) + ax.xaxis.set_ticks(np.arange(10) + 0.1) + ax.locator_params(nbins=5) + ax.xaxis.set_ticklabels([c for c in "bcdefghijk"]) + plt.draw() + labels = [t.get_text() for t in ax.xaxis.get_ticklabels()] + assert labels == ['b', 'd', 'f', 'h', 'j'] + + @image_comparison(['retain_tick_visibility.png']) def test_retain_tick_visibility(): fig, ax = plt.subplots() From 775db02973c1d0aa4ffb633ffb067eaf474d6b8d Mon Sep 17 00:00:00 2001 From: Eric Firing Date: Wed, 29 Apr 2020 13:22:40 -1000 Subject: [PATCH 04/13] Flake8: space added --- lib/matplotlib/axis.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/matplotlib/axis.py b/lib/matplotlib/axis.py index d57e640ace1d..385c8da19d5a 100644 --- a/lib/matplotlib/axis.py +++ b/lib/matplotlib/axis.py @@ -1629,7 +1629,7 @@ def set_ticklabels(self, ticklabels, *, minor=False, **kwargs): locator = (self.get_minor_locator() if minor else self.get_major_locator()) if isinstance(locator, mticker.FixedLocator): - tickd = {loc:lab for loc, lab in zip(locator.locs, ticklabels)} + tickd = {loc: lab for loc, lab in zip(locator.locs, ticklabels)} formatter = mticker.FuncFormatter(lambda x, pos: tickd.get(x, "")) else: formatter = mticker.FixedFormatter(ticklabels) From 94f04a956eb693f11b2dabe243c79b862d483e69 Mon Sep 17 00:00:00 2001 From: Eric Firing Date: Wed, 29 Apr 2020 14:30:22 -1000 Subject: [PATCH 05/13] Make pickles work again. --- lib/matplotlib/axis.py | 7 ++++++- lib/matplotlib/ticker.py | 8 +++++--- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/lib/matplotlib/axis.py b/lib/matplotlib/axis.py index 385c8da19d5a..9748cb10b14b 100644 --- a/lib/matplotlib/axis.py +++ b/lib/matplotlib/axis.py @@ -1599,6 +1599,11 @@ def set_pickradius(self, pickradius): """ self.pickradius = pickradius + # Helper for set_ticklabels. Defining it here makes it pickleable. + @staticmethod + def _format_with_dict(x, pos, tickd): + return tickd.get(x, "") + def set_ticklabels(self, ticklabels, *, minor=False, **kwargs): r""" Set the text values of the tick labels. @@ -1630,7 +1635,7 @@ def set_ticklabels(self, ticklabels, *, minor=False, **kwargs): else self.get_major_locator()) if isinstance(locator, mticker.FixedLocator): tickd = {loc: lab for loc, lab in zip(locator.locs, ticklabels)} - formatter = mticker.FuncFormatter(lambda x, pos: tickd.get(x, "")) + formatter = mticker.FuncFormatter(self._format_with_dict, tickd) else: formatter = mticker.FixedFormatter(ticklabels) if minor: diff --git a/lib/matplotlib/ticker.py b/lib/matplotlib/ticker.py index 689db7fb6b6d..82f9db472339 100644 --- a/lib/matplotlib/ticker.py +++ b/lib/matplotlib/ticker.py @@ -379,11 +379,13 @@ class FuncFormatter(Formatter): The function should take in two inputs (a tick value ``x`` and a position ``pos``), and return a string containing the corresponding - tick label. + tick label. The function may take additional arguments that are + supplied upon instantiation. """ - def __init__(self, func): + def __init__(self, func, *args): self.func = func + self.args = args self.offset_string = "" def __call__(self, x, pos=None): @@ -392,7 +394,7 @@ def __call__(self, x, pos=None): *x* and *pos* are passed through as-is. """ - return self.func(x, pos) + return self.func(x, pos, *self.args) def get_offset(self): return self.offset_string From 6bfbb6c87dd5a33f78fdfe8b05f6f1005acb0d42 Mon Sep 17 00:00:00 2001 From: Eric Firing Date: Thu, 30 Apr 2020 11:13:54 -1000 Subject: [PATCH 06/13] Use partial in set_ticklabels instead of an argument in FuncFormatter. --- lib/matplotlib/axis.py | 6 ++++-- lib/matplotlib/ticker.py | 8 +++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/lib/matplotlib/axis.py b/lib/matplotlib/axis.py index 9748cb10b14b..3e8125cf0a04 100644 --- a/lib/matplotlib/axis.py +++ b/lib/matplotlib/axis.py @@ -3,6 +3,7 @@ """ import datetime +import functools import logging import numpy as np @@ -1601,7 +1602,7 @@ def set_pickradius(self, pickradius): # Helper for set_ticklabels. Defining it here makes it pickleable. @staticmethod - def _format_with_dict(x, pos, tickd): + def _format_with_dict(tickd, x, pos): return tickd.get(x, "") def set_ticklabels(self, ticklabels, *, minor=False, **kwargs): @@ -1635,7 +1636,8 @@ def set_ticklabels(self, ticklabels, *, minor=False, **kwargs): else self.get_major_locator()) if isinstance(locator, mticker.FixedLocator): tickd = {loc: lab for loc, lab in zip(locator.locs, ticklabels)} - formatter = mticker.FuncFormatter(self._format_with_dict, tickd) + func = functools.partial(self._format_with_dict, tickd) + formatter = mticker.FuncFormatter(func) else: formatter = mticker.FixedFormatter(ticklabels) if minor: diff --git a/lib/matplotlib/ticker.py b/lib/matplotlib/ticker.py index 82f9db472339..689db7fb6b6d 100644 --- a/lib/matplotlib/ticker.py +++ b/lib/matplotlib/ticker.py @@ -379,13 +379,11 @@ class FuncFormatter(Formatter): The function should take in two inputs (a tick value ``x`` and a position ``pos``), and return a string containing the corresponding - tick label. The function may take additional arguments that are - supplied upon instantiation. + tick label. """ - def __init__(self, func, *args): + def __init__(self, func): self.func = func - self.args = args self.offset_string = "" def __call__(self, x, pos=None): @@ -394,7 +392,7 @@ def __call__(self, x, pos=None): *x* and *pos* are passed through as-is. """ - return self.func(x, pos, *self.args) + return self.func(x, pos) def get_offset(self): return self.offset_string From b217c3fd5634184e2e3c90dad7895ee2c2015db7 Mon Sep 17 00:00:00 2001 From: Eric Firing Date: Thu, 30 Apr 2020 11:47:15 -1000 Subject: [PATCH 07/13] Update selectively instead of using _update_ticks. --- lib/matplotlib/axis.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/lib/matplotlib/axis.py b/lib/matplotlib/axis.py index 3e8125cf0a04..cdc702db3691 100644 --- a/lib/matplotlib/axis.py +++ b/lib/matplotlib/axis.py @@ -1640,16 +1640,19 @@ def set_ticklabels(self, ticklabels, *, minor=False, **kwargs): formatter = mticker.FuncFormatter(func) else: formatter = mticker.FixedFormatter(ticklabels) + if minor: self.set_minor_formatter(formatter) - ticks = self.get_minor_ticks() + locs = self.get_minorticklocs() + ticks = self.get_minor_ticks(len(locs)) else: self.set_major_formatter(formatter) - ticks = self.get_major_ticks() + locs = self.get_majorticklocs() + ticks = self.get_major_ticks(len(locs)) - self._update_ticks() ret = [] - for pos, tick in enumerate(ticks): + for pos, (loc, tick) in enumerate(zip(locs, ticks)): + tick.update_position(loc) tick_label = formatter(tick._loc, pos) # deal with label1 tick.label1.set_text(tick_label) From 6c71b67f4fa66b333d107b1f7bd033286ddb422f Mon Sep 17 00:00:00 2001 From: Eric Firing Date: Thu, 30 Apr 2020 12:41:29 -1000 Subject: [PATCH 08/13] Slight simplification. --- lib/matplotlib/axis.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/matplotlib/axis.py b/lib/matplotlib/axis.py index cdc702db3691..ef5b96f2b39e 100644 --- a/lib/matplotlib/axis.py +++ b/lib/matplotlib/axis.py @@ -1653,7 +1653,7 @@ def set_ticklabels(self, ticklabels, *, minor=False, **kwargs): ret = [] for pos, (loc, tick) in enumerate(zip(locs, ticks)): tick.update_position(loc) - tick_label = formatter(tick._loc, pos) + tick_label = formatter(loc, pos) # deal with label1 tick.label1.set_text(tick_label) tick.label1.update(kwargs) From dbe6f358d347108e0ef7c31b77a7ce0c7ec39225 Mon Sep 17 00:00:00 2001 From: Eric Firing Date: Mon, 4 May 2020 11:02:07 -1000 Subject: [PATCH 09/13] Require a match between fixed ticks and ticklabels. --- lib/matplotlib/axis.py | 5 +++++ lib/matplotlib/tests/test_axes.py | 12 ++++++++++-- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/lib/matplotlib/axis.py b/lib/matplotlib/axis.py index ef5b96f2b39e..1ab6eaf4bc39 100644 --- a/lib/matplotlib/axis.py +++ b/lib/matplotlib/axis.py @@ -1635,6 +1635,11 @@ def set_ticklabels(self, ticklabels, *, minor=False, **kwargs): locator = (self.get_minor_locator() if minor else self.get_major_locator()) if isinstance(locator, mticker.FixedLocator): + if len(locator.locs) != len(ticklabels): + raise ValueError( + "The number of FixedLocator locations" + f" ({len(locator.locs)}) does not match" + f" the number of ticklabels ({len(ticklabels)}).") tickd = {loc: lab for loc, lab in zip(locator.locs, ticklabels)} func = functools.partial(self._format_with_dict, tickd) formatter = mticker.FuncFormatter(func) diff --git a/lib/matplotlib/tests/test_axes.py b/lib/matplotlib/tests/test_axes.py index 9f8aea250ef2..7635336b78e7 100644 --- a/lib/matplotlib/tests/test_axes.py +++ b/lib/matplotlib/tests/test_axes.py @@ -4441,8 +4441,8 @@ def test_set_get_ticklabels(): # set ticklabel to 1 plot in normal way ax[0].set_xticks(range(10)) ax[0].set_yticks(range(10)) - ax[0].set_xticklabels(['a', 'b', 'c', 'd']) - ax[0].set_yticklabels(['11', '12', '13', '14']) + ax[0].set_xticklabels(['a', 'b', 'c', 'd'] + 6 * ['']) + ax[0].set_yticklabels(['11', '12', '13', '14'] + 6 * ['']) # set ticklabel to the other plot, expect the 2 plots have same label # setting pass get_ticklabels return value as ticklabels argument @@ -4464,6 +4464,14 @@ def test_subsampled_ticklabels(): assert labels == ['b', 'd', 'f', 'h', 'j'] +def test_mismatched_ticklabels(): + fig, ax = plt.subplots() + ax.plot(np.arange(10)) + ax.xaxis.set_ticks([1.5, 2.5]) + with pytest.raises(ValueError): + ax.xaxis.set_ticklabels(['a', 'b', 'c']) + + @image_comparison(['retain_tick_visibility.png']) def test_retain_tick_visibility(): fig, ax = plt.subplots() From 629143041791ab6b87f0de7a96cb3cd6f1c880ff Mon Sep 17 00:00:00 2001 From: Eric Firing Date: Mon, 4 May 2020 13:05:03 -1000 Subject: [PATCH 10/13] Fix broken example, add to api_changes, tweak error message. --- doc/api/api_changes_3.3/behaviour.rst | 7 +++++++ .../images_contours_and_fields/image_annotated_heatmap.py | 2 +- lib/matplotlib/axis.py | 3 ++- 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/doc/api/api_changes_3.3/behaviour.rst b/doc/api/api_changes_3.3/behaviour.rst index 70a02d81b9d4..f64f27d6e1d3 100644 --- a/doc/api/api_changes_3.3/behaviour.rst +++ b/doc/api/api_changes_3.3/behaviour.rst @@ -37,6 +37,13 @@ did nothing, when passed an unsupported value. It now raises a ``ValueError``. `.pyplot.tick_params`) used to accept any value for ``which`` and silently did nothing, when passed an unsupported value. It now raises a ``ValueError``. +``Axis.set_ticklabels()`` must match ``FixedLocator.locs`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +If an axis is using a `.tickers.FixedLocator`, typically set by a call to +`.Axis.set_ticks`, then the number of ticklabels supplied must match the +number of locations available (``FixedFormattor.locs``). If not, a +``ValueError`` is raised. + ``backend_pgf.LatexManager.latex`` ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ``backend_pgf.LatexManager.latex`` is now created with ``encoding="utf-8"``, so diff --git a/examples/images_contours_and_fields/image_annotated_heatmap.py b/examples/images_contours_and_fields/image_annotated_heatmap.py index 3aac185f0e82..1623e5847b03 100644 --- a/examples/images_contours_and_fields/image_annotated_heatmap.py +++ b/examples/images_contours_and_fields/image_annotated_heatmap.py @@ -289,7 +289,7 @@ def annotate_heatmap(im, data=None, valfmt="{x:.2f}", # `matplotlib.ticker.FuncFormatter`. corr_matrix = np.corrcoef(np.random.rand(6, 5)) -im, _ = heatmap(corr_matrix, vegetables, vegetables, ax=ax4, +im, _ = heatmap(corr_matrix, vegetables, farmers, ax=ax4, cmap="PuOr", vmin=-1, vmax=1, cbarlabel="correlation coeff.") diff --git a/lib/matplotlib/axis.py b/lib/matplotlib/axis.py index 1ab6eaf4bc39..77e2714f2496 100644 --- a/lib/matplotlib/axis.py +++ b/lib/matplotlib/axis.py @@ -1638,7 +1638,8 @@ def set_ticklabels(self, ticklabels, *, minor=False, **kwargs): if len(locator.locs) != len(ticklabels): raise ValueError( "The number of FixedLocator locations" - f" ({len(locator.locs)}) does not match" + f" ({len(locator.locs)}), usually from a call to" + " set_ticks, does not match" f" the number of ticklabels ({len(ticklabels)}).") tickd = {loc: lab for loc, lab in zip(locator.locs, ticklabels)} func = functools.partial(self._format_with_dict, tickd) From 6339f654bec052dde1612d46b7196fe1c8cb7be3 Mon Sep 17 00:00:00 2001 From: Eric Firing Date: Mon, 4 May 2020 13:48:25 -1000 Subject: [PATCH 11/13] Fix example: second try. --- .../images_contours_and_fields/image_annotated_heatmap.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/images_contours_and_fields/image_annotated_heatmap.py b/examples/images_contours_and_fields/image_annotated_heatmap.py index 1623e5847b03..fd912dffa755 100644 --- a/examples/images_contours_and_fields/image_annotated_heatmap.py +++ b/examples/images_contours_and_fields/image_annotated_heatmap.py @@ -288,8 +288,8 @@ def annotate_heatmap(im, data=None, valfmt="{x:.2f}", # the diagonal elements (which are all 1) by using a # `matplotlib.ticker.FuncFormatter`. -corr_matrix = np.corrcoef(np.random.rand(6, 5)) -im, _ = heatmap(corr_matrix, vegetables, farmers, ax=ax4, +corr_matrix = np.corrcoef(harvest) +im, _ = heatmap(corr_matrix, vegetables, vegetables, ax=ax4, cmap="PuOr", vmin=-1, vmax=1, cbarlabel="correlation coeff.") From da16bcebfacc915708cb31d54caf8eed1cdbfa6c Mon Sep 17 00:00:00 2001 From: Eric Firing Date: Mon, 4 May 2020 14:40:46 -1000 Subject: [PATCH 12/13] Typo in api_changes entry --- doc/api/api_changes_3.3/behaviour.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/api/api_changes_3.3/behaviour.rst b/doc/api/api_changes_3.3/behaviour.rst index f64f27d6e1d3..483f93448b7c 100644 --- a/doc/api/api_changes_3.3/behaviour.rst +++ b/doc/api/api_changes_3.3/behaviour.rst @@ -39,7 +39,7 @@ did nothing, when passed an unsupported value. It now raises a ``ValueError``. ``Axis.set_ticklabels()`` must match ``FixedLocator.locs`` ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -If an axis is using a `.tickers.FixedLocator`, typically set by a call to +If an axis is using a `.ticker.FixedLocator`, typically set by a call to `.Axis.set_ticks`, then the number of ticklabels supplied must match the number of locations available (``FixedFormattor.locs``). If not, a ``ValueError`` is raised. From 3eb471dadd2fd397c840bc98db90a06845697131 Mon Sep 17 00:00:00 2001 From: Eric Firing Date: Mon, 4 May 2020 20:26:51 -1000 Subject: [PATCH 13/13] Improvements to docstring and to API docs. --- doc/api/axis_api.rst | 11 +++++++---- lib/matplotlib/axis.py | 5 +++-- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/doc/api/axis_api.rst b/doc/api/axis_api.rst index beff96184ec9..23874127b062 100644 --- a/doc/api/axis_api.rst +++ b/doc/api/axis_api.rst @@ -226,17 +226,20 @@ Other Discouraged ----------- -These methods implicitly use `~matplotlib.ticker.FixedLocator` and -`~matplotlib.ticker.FixedFormatter`. They can be convenient, but if -not used together may de-couple your tick labels from your data. +These methods should be used together with care, calling ``set_ticks`` +to specify the desired tick locations **before** calling ``set_ticklabels`` to +specify a matching series of labels. Calling ``set_ticks`` makes a +`~matplotlib.ticker.FixedLocator`; it's list of locations is then used by +``set_ticklabels`` to make an appropriate +`~matplotlib.ticker.FuncFormatter`. .. autosummary:: :toctree: _as_gen :template: autosummary.rst :nosignatures: - Axis.set_ticklabels Axis.set_ticks + Axis.set_ticklabels diff --git a/lib/matplotlib/axis.py b/lib/matplotlib/axis.py index 77e2714f2496..6566af285278 100644 --- a/lib/matplotlib/axis.py +++ b/lib/matplotlib/axis.py @@ -1617,8 +1617,9 @@ def set_ticklabels(self, ticklabels, *, minor=False, **kwargs): Parameters ---------- ticklabels : sequence of str or of `.Text`\s - List of texts for tick labels; must include values for non-visible - labels. + Texts for labeling each tick location in the sequence set by + `.Axis.set_ticks`; the number of labels must match the number of + locations. minor : bool If True, set minor ticks instead of major ticks. **kwargs