Skip to content

Commit 642b034

Browse files
authored
Merge pull request #15507 from timhoffm/fixed-formatter
Use FixedFormatter only with FixedLocator
2 parents 8d06cbc + 4b5284f commit 642b034

File tree

5 files changed

+55
-24
lines changed

5 files changed

+55
-24
lines changed

lib/matplotlib/axes/_base.py

+21-9
Original file line numberDiff line numberDiff line change
@@ -3402,10 +3402,15 @@ def set_xticklabels(self, labels, fontdict=None, minor=False, **kwargs):
34023402
"""
34033403
Set the x-tick labels with list of string labels.
34043404
3405+
.. warning::
3406+
This method should only be used after fixing the tick positions
3407+
using `~.axes.Axes.set_xticks`. Otherwise, the labels may end up
3408+
in unexpected positions.
3409+
34053410
Parameters
34063411
----------
3407-
labels : List[str]
3408-
List of string labels.
3412+
labels : list of str
3413+
The label texts.
34093414
34103415
fontdict : dict, optional
34113416
A dictionary controlling the appearance of the ticklabels.
@@ -3416,12 +3421,13 @@ def set_xticklabels(self, labels, fontdict=None, minor=False, **kwargs):
34163421
'verticalalignment': 'baseline',
34173422
'horizontalalignment': loc}
34183423
3419-
minor : bool, optional
3424+
minor : bool, default: False
34203425
Whether to set the minor ticklabels rather than the major ones.
34213426
34223427
Returns
34233428
-------
3424-
A list of `~.text.Text` instances.
3429+
labels : list of `~.Text`
3430+
The labels.
34253431
34263432
Other Parameters
34273433
-----------------
@@ -3780,12 +3786,17 @@ def get_yticklabels(self, minor=False, which=None):
37803786

37813787
def set_yticklabels(self, labels, fontdict=None, minor=False, **kwargs):
37823788
"""
3783-
Set the y-tick labels with list of strings labels.
3789+
Set the y-tick labels with list of string labels.
3790+
3791+
.. warning::
3792+
This method should only be used after fixing the tick positions
3793+
using `~.axes.Axes.set_yticks`. Otherwise, the labels may end up
3794+
in unexpected positions.
37843795
37853796
Parameters
37863797
----------
3787-
labels : List[str]
3788-
list of string labels
3798+
labels : list of str
3799+
The label texts.
37893800
37903801
fontdict : dict, optional
37913802
A dictionary controlling the appearance of the ticklabels.
@@ -3796,12 +3807,13 @@ def set_yticklabels(self, labels, fontdict=None, minor=False, **kwargs):
37963807
'verticalalignment': 'baseline',
37973808
'horizontalalignment': loc}
37983809
3799-
minor : bool, optional
3810+
minor : bool, default: False
38003811
Whether to set the minor ticklabels rather than the major ones.
38013812
38023813
Returns
38033814
-------
3804-
A list of `~.text.Text` instances.
3815+
labels
3816+
A list of `~.text.Text` instances.
38053817
38063818
Other Parameters
38073819
----------------

lib/matplotlib/axis.py

+17-12
Original file line numberDiff line numberDiff line change
@@ -1536,6 +1536,11 @@ def set_major_formatter(self, formatter):
15361536
formatter : `~matplotlib.ticker.Formatter`
15371537
"""
15381538
cbook._check_isinstance(mticker.Formatter, formatter=formatter)
1539+
if (isinstance(formatter, mticker.FixedFormatter)
1540+
and len(formatter.seq) > 0
1541+
and not isinstance(self.major.locator, mticker.FixedLocator)):
1542+
cbook._warn_external('FixedFormatter should only be used together '
1543+
'with FixedLocator')
15391544
self.isDefault_majfmt = False
15401545
self.major.formatter = formatter
15411546
formatter.set_axis(self)
@@ -1550,6 +1555,11 @@ def set_minor_formatter(self, formatter):
15501555
formatter : `~matplotlib.ticker.Formatter`
15511556
"""
15521557
cbook._check_isinstance(mticker.Formatter, formatter=formatter)
1558+
if (isinstance(formatter, mticker.FixedFormatter)
1559+
and len(formatter.seq) > 0
1560+
and not isinstance(self.minor.locator, mticker.FixedLocator)):
1561+
cbook._warn_external('FixedFormatter should only be used together '
1562+
'with FixedLocator')
15531563
self.isDefault_minfmt = False
15541564
self.minor.formatter = formatter
15551565
formatter.set_axis(self)
@@ -1601,6 +1611,11 @@ def set_ticklabels(self, ticklabels, *args, minor=False, **kwargs):
16011611
r"""
16021612
Set the text values of the tick labels.
16031613
1614+
.. warning::
1615+
This method should only be used after fixing the tick positions
1616+
using `.Axis.set_ticks`. Otherwise, the labels may end up in
1617+
unexpected positions.
1618+
16041619
Parameters
16051620
----------
16061621
ticklabels : sequence of str or of `Text`\s
@@ -1622,18 +1637,8 @@ def set_ticklabels(self, ticklabels, *args, minor=False, **kwargs):
16221637
"3.1", message="Additional positional arguments to "
16231638
"set_ticklabels are ignored, and deprecated since Matplotlib "
16241639
"3.1; passing them will raise a TypeError in Matplotlib 3.3.")
1625-
get_labels = []
1626-
for t in ticklabels:
1627-
# try calling get_text() to check whether it is Text object
1628-
# if it is Text, get label content
1629-
try:
1630-
get_labels.append(t.get_text())
1631-
# otherwise add the label to the list directly
1632-
except AttributeError:
1633-
get_labels.append(t)
1634-
# replace the ticklabels list with the processed one
1635-
ticklabels = get_labels
1636-
1640+
ticklabels = [t.get_text() if hasattr(t, 'get_text') else t
1641+
for t in ticklabels]
16371642
if minor:
16381643
self.set_minor_formatter(mticker.FixedFormatter(ticklabels))
16391644
ticks = self.get_minor_ticks()

lib/matplotlib/tests/test_axes.py

+6-2
Original file line numberDiff line numberDiff line change
@@ -5194,11 +5194,15 @@ def test_set_get_ticklabels():
51945194
ax[1].set_title(ha[1])
51955195

51965196
# set ticklabel to 1 plot in normal way
5197-
ax[0].set_xticklabels(('a', 'b', 'c', 'd'))
5198-
ax[0].set_yticklabels(('11', '12', '13', '14'))
5197+
ax[0].set_xticks(range(10))
5198+
ax[0].set_yticks(range(10))
5199+
ax[0].set_xticklabels(['a', 'b', 'c', 'd'])
5200+
ax[0].set_yticklabels(['11', '12', '13', '14'])
51995201

52005202
# set ticklabel to the other plot, expect the 2 plots have same label
52015203
# setting pass get_ticklabels return value as ticklabels argument
5204+
ax[1].set_xticks(ax[0].get_xticks())
5205+
ax[1].set_yticks(ax[0].get_yticks())
52025206
ax[1].set_xticklabels(ax[0].get_xticklabels())
52035207
ax[1].set_yticklabels(ax[0].get_yticklabels())
52045208

lib/matplotlib/tests/test_figure.py

+6-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from datetime import datetime
22
from pathlib import Path
33
import platform
4+
import warnings
45

56
from matplotlib import rcParams
67
from matplotlib.testing.decorators import image_comparison, check_figures_equal
@@ -317,7 +318,11 @@ def test_autofmt_xdate(which):
317318
ax.xaxis_date()
318319

319320
ax.xaxis.set_minor_locator(AutoMinorLocator(2))
320-
ax.xaxis.set_minor_formatter(FixedFormatter(minors))
321+
with warnings.catch_warnings():
322+
warnings.filterwarnings(
323+
'ignore',
324+
'FixedFormatter should only be used together with FixedLocator')
325+
ax.xaxis.set_minor_formatter(FixedFormatter(minors))
321326

322327
fig.autofmt_xdate(0.2, angle, 'right', which)
323328

lib/matplotlib/ticker.py

+5
Original file line numberDiff line numberDiff line change
@@ -341,6 +341,11 @@ def __call__(self, x, pos=None):
341341
class FixedFormatter(Formatter):
342342
"""
343343
Return fixed strings for tick labels based only on position, not value.
344+
345+
.. note::
346+
`.FixedFormatter` should only be used together with `.FixedLocator`.
347+
Otherwise, the labels may end up in unexpected positions.
348+
344349
"""
345350
def __init__(self, seq):
346351
"""

0 commit comments

Comments
 (0)