8000 Use FixedFormatter only with FixedLocator · matplotlib/matplotlib@c779568 · GitHub
[go: up one dir, main page]

Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit c779568

Browse files
committed
Use FixedFormatter only with FixedLocator
1 parent ea79c2a commit c779568

File tree

5 files changed

+56
-24
lines changed

5 files changed

+56
-24
lines changed

lib/matplotlib/axes/_base.py

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3412,10 +3412,15 @@ def set_xticklabels(self, labels, fontdict=None, minor=False, **kwargs):
34123412
"""
34133413
Set the x-tick labels with list of string labels.
34143414
3415+
.. warning::
3416+
This method should only be used after fixing the tick positions
3417+
using `~.axes.Axes.set_xticks`. Otherwise, the labels may end up
3418+
in unexpected positions.
3419+
34153420
Parameters
34163421
----------
3417-
labels : List[str]
3418-
List of string labels.
3422+
labels : list of str
3423+
The label texts.
34193424
34203425
fontdict : dict, optional
34213426
A dictionary controlling the appearance of the ticklabels.
@@ -3426,12 +3431,13 @@ def set_xticklabels(self, labels, fontdict=None, minor=False, **kwargs):
34263431
'verticalalignment': 'baseline',
34273432
'horizontalalignment': loc}
34283433
3429-
minor : bool, optional
3434+
minor : bool, default: False
34303435
Whether to set the minor ticklabels rather than the major ones.
34313436
34323437
Returns
34333438
-------
3434-
A list of `~.text.Text` instances.
3439+
labels
3440+
A list of `~.text.Text` instances.
34353441
34363442
Other Parameters
34373443
-----------------
@@ -3792,12 +3798,17 @@ def get_yticklabels(self, minor=False, which=None):
37923798

37933799
def set_yticklabels(self, labels, fontdict=None, minor=False, **kwargs):
37943800
"""
3795-
Set the y-tick labels with list of strings labels.
3801+
Set the y-tick labels with list of string labels.
3802+
3803+
.. warning::
3804+
This method should only be used after fixing the tick positions
3805+
using `~.axes.Axes.set_yticks`. Otherwise, the labels may end up
3806+
in unexpected positions.
37963807
37973808
Parameters
37983809
----------
3799-
labels : List[str]
3800-
list of string labels
3810+
labels : list of str
3811+
The label texts.
38013812
38023813
fontdict : dict, optional
38033814
A dictionary controlling the appearance of the ticklabels.
@@ -3808,12 +3819,13 @@ def set_yticklabels(self, labels, fontdict=None, minor=False, **kwargs):
38083819
'verticalalignment': 'baseline',
38093820
'horizontalalignment': loc}
38103821
3811-
minor : bool, optional
3822+
minor : bool, default: False
38123823
Whether to set the minor ticklabels rather than the major ones.
38133824
38143825
Returns
38153826
-------
3816-
A list of `~.text.Text` instances.
3827+
labels
3828+
A list of `~.text.Text` instances.
38173829
38183830
Other Parameters
38193831
----------------

lib/matplotlib/axis.py

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
import datetime
66
import logging
7+
import warnings
78

89
import numpy as np
910

@@ -1632,6 +1633,11 @@ def set_major_formatter(self, formatter):
16321633
formatter : `~matplotlib.ticker.Formatter`
16331634
"""
16341635
cbook._check_isinstance(mticker.Formatter, formatter=formatter)
1636+
if (isinstance(formatter, mticker.FixedFormatter)
1637+
and len(formatter.seq) > 0
1638+
and not isinstance(self.major.locator, mticker.FixedLocator)):
1639+
cbook._warn_external('FixedFormatter should only be used together '
1640+
'with FixedLocator')
16351641
self.isDefault_majfmt = False
16361642
self.major.formatter = formatter
16371643
formatter.set_axis(self)
@@ -1646,6 +1652,11 @@ def set_minor_formatter(self, formatter):
16461652
formatter : `~matplotlib.ticker.Formatter`
16471653
"""
16481654
cbook._check_isinstance(mticker.Formatter, formatter=formatter)
1655+
if (isinstance(formatter, mticker.FixedFormatter)
1656+
and len(formatter.seq) > 0
1657+
and not isinstance(self.minor.locator, mticker.FixedLocator)):
1658+
warnings.warn('FixedFormatter should only be used together with '
1659+
'FixedLocator', stacklevel=2)
16491660
self.isDefault_minfmt = False
16501661
self.minor.formatter = formatter
16511662
formatter.set_axis(self)
@@ -1697,6 +1708,11 @@ def set_ticklabels(self, ticklabels, *args, minor=False, **kwargs):
16971708
r"""
16981709
Set the text values of the tick labels.
16991710
1711+
.. warning::
1712+
This method should only be used after fixing the tick positions
1713+
using `.Axis.set_ticks`. Otherwise, the labels may end up in
1714+
unexpected positions.
1715+
17001716
Parameters
17011717
----------
17021718
ticklabels : sequence of str or of `Text`\s
@@ -1718,18 +1734,8 @@ def set_ticklabels(self, ticklabels, *args, minor=False, **kwargs):
17181734
"3.1", message="Additional positional arguments to "
17191735
"set_ticklabels are ignored, and deprecated since Matplotlib "
17201736
"3.1; passing them will raise a TypeError in Matplotlib 3.3.")
1721-
get_labels = []
1722-
for t in ticklabels:
1723-
# try calling get_text() to check whether it is Text object
1724-
# if it is Text, get label content
1725-
try:
1726-
get_labels.append(t.get_text())
1727-
# otherwise add the label to the list directly
1728-
except AttributeError:
1729-
get_labels.append(t)
1730-
# replace the ticklabels list with the processed one
1731-
ticklabels = get_labels
1732-
1737+
ticklabels = [t.get_text() if hasattr(t, 'get_text') else t
1738+
for t in ticklabels]
17331739
if minor:
17341740
self.set_minor_formatter(mticker.FixedFormatter(ticklabels))
17351741
ticks = self.get_minor_ticks()

lib/matplotlib/tests/test_axes.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5064,11 +5064,15 @@ def test_set_get_ticklabels():
50645064
ax[1].set_title(ha[1])
50655065

50665066
# set ticklabel to 1 plot in normal way
5067-
ax[0].set_xticklabels(('a', 'b', 'c', 'd'))
5068-
ax[0].set_yticklabels(('11', '12', '13', '14'))
5067+
ax[0].set_xticks(range(10))
5068+
ax[0].set_yticks(range(10))
5069+
ax[0].set_xticklabels(['a', 'b', 'c', 'd'])
5070+
ax[0].set_yticklabels(['11', '12', '13', '14'])
50695071

50705072
# set ticklabel to the other plot, expect the 2 plots have same label
50715073
# setting pass get_ticklabels return value as ticklabels argument
5074+
ax[1].set_xticks(ax[0].get_xticks())
5075+
ax[1].set_yticks(ax[0].get_yticks())
50725076
ax[1].set_xticklabels(ax[0].get_xticklabels())
50735077
ax[1].set_yticklabels(ax[0].get_yticklabels())
50745078

lib/matplotlib/tests/test_figure.py

Lines changed: 6 additions & 1 deletion
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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -345,6 +345,11 @@ def __call__(self, x, pos=None):
345345
class FixedFormatter(Formatter):
346346
"""
347347
Return fixed strings for tick labels based only on position, not value.
348+
349+
.. note::
350+
`.FixedFormatter` should only be used together with `.FixedLocator`.
351+
Otherwise, the labels may end up in unexpected positions.
352+
348353
"""
349354
def __init__(self, seq):
350355
"""

0 commit comments

Comments
 (0)
0