Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 3744780

Browse files
committed
Automatically create tick formatters for str and callable inputs.
1 parent 1b8ede6 commit 3744780

File tree

6 files changed

+112
-34
lines changed

6 files changed

+112
-34
lines changed
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
Allow tick formatters to be set with str or function inputs
2+
------------------------------------------------------------------------
3+
`~.Axis.set_major_formatter` and `~.Axis.set_minor_formatter`
4+
now accept `str` or function inputs in addition to `~.ticker.Formatter`
5+
instances. For a `str` a `~.ticker.StrMethodFormatter` is automatically
6+
created and used. For a function a `~.ticker.FuncFormatter` is automatically
7+
created and used.

examples/ticks_and_spines/tick-formatters.py

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ def setup(ax, title):
3434
fontsize=14, fontname='Monospace', color='tab:blue')
3535

3636

37-
fig, axs = plt.subplots(7, 1, figsize=(8, 6))
37+
fig, axs = plt.subplots(9, 1, figsize=(8, 8))
3838

3939
# Null formatter
4040
setup(axs[0], title="NullFormatter()")
@@ -59,21 +59,30 @@ def major_formatter(x, pos):
5959
setup(axs[2], title='FuncFormatter(lambda x, pos: "[%.2f]" % x)')
6060
axs[2].xaxis.set_major_formatter(major_formatter)
6161

62-
# FormatStr formatter
63-
setup(axs[3], title="FormatStrFormatter('#%d')")
64-
axs[3].xaxis.set_major_formatter(ticker.FormatStrFormatter("#%d"))
62+
# FuncFormatter can be automatically created directly with a function input
63+
# without needing to manually create the formatter
64+
setup(axs[3], title="lambda x, pos: str(x-5)")
65+
axs[3].xaxis.set_major_formatter(lambda x, pos: str(x-5))
66+
67+
# StrMethod formatter
68+
setup(axs[4], title="StrMethodFormatter('{x:.3f}')")
69+
axs[4].xaxis.set_major_formatter(ticker.StrMethodFormatter("{x:.3f}"))
70+
71+
# StrMethodFormatter can also be created directly with a string input.
72+
setup(axs[5], title="'{x} km'")
73+
axs[5].xaxis.set_major_formatter('{x} km')
6574

6675
# Scalar formatter
67-
setup(axs[4], title="ScalarFormatter()")
68-
axs[4].xaxis.set_major_formatter(ticker.ScalarFormatter(useMathText=True))
76+
setup(axs[6], title="ScalarFormatter()")
77+
axs[6].xaxis.set_major_formatter(ticker.ScalarFormatter(useMathText=True))
6978

70-
# StrMethod formatter
71-
setup(axs[5], title="StrMethodFormatter('{x:.3f}')")
72-
axs[5].xaxis.set_major_formatter(ticker.StrMethodFormatter("{x:.3f}"))
79+
# FormatStr formatter
80+
setup(axs[7], title="FormatStrFormatter('#%d')")
81+
axs[7].xaxis.set_major_formatter(ticker.FormatStrFormatter("#%d"))
7382

7483
# Percent formatter
75-
setup(axs[6], title="PercentFormatter(xmax=5)")
76-
axs[6].xaxis.set_major_formatter(ticker.PercentFormatter(xmax=5))
84+
setup(axs[8], title="PercentFormatter(xmax=5)")
85+
axs[8].xaxis.set_major_formatter(ticker.PercentFormatter(xmax=5))
7786

7887
plt.tight_layout()
7988
plt.show()

lib/matplotlib/axis.py

Lines changed: 47 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1529,37 +1529,68 @@ def set_major_formatter(self, formatter):
15291529
"""
15301530
Set the formatter of the major ticker.
15311531
1532+
In addition to a `~matplotlib.ticker.Formatter` instance,
1533+
this also accepts a `str` or function.
1534+
For a `str` a `~matplotlib.ticker.StrMethodFormatter` is used.
1535+
For a function a `~matplotlib.ticker.FuncFormatter` is used.
1536+
15321537
Parameters
15331538
----------
1534-
formatter : `~matplotlib.ticker.Formatter`
1539+
formatter : `~matplotlib.ticker.Formatter`, str, or function
15351540
"""
1536-
cbook._check_isinstance(mticker.Formatter, formatter=formatter)
1537-
if (isinstance(formatter, mticker.FixedFormatter)
1538-
and len(formatter.seq) > 0
1539-
and not isinstance(self.major.locator, mticker.FixedLocator)):
1540-
cbook._warn_external('FixedFormatter should only be used together '
1541-
'with FixedLocator')
1542-
self.isDefault_majfmt = False
1543-
self.major.formatter = formatter
1544-
formatter.set_axis(self)
1545-
self.stale = True
1541+
self._set_formatter(formatter, self.major)
15461542

15471543
def set_minor_formatter(self, formatter):
15481544
"""
15491545
Set the formatter of the minor ticker.
15501546
1547+
In addition to a `~matplotlib.ticker.Formatter` instance,
1548+
this also accepts a `str` or function.
1549+
For a `str` a `~matplotlib.ticker.StrMethodFormatter` is used.
1550+
For a function a `~matplotlib.ticker.FuncFormatter` is used.
1551+
15511552
Parameters
15521553
----------
1553-
formatter : `~matplotlib.ticker.Formatter`
1554+
formatter : `~matplotlib.ticker.Formatter`, str, or function
1555+
"""
1556+
self._set_formatter(formatter, self.minor)
1557+
1558+
def _set_formatter(self, formatter, level):
15541559
"""
1555-
cbook._check_isinstance(mticker.Formatter, formatter=formatter)
1560+
Set the formatter of the major or minor ticker.
1561+
1562+
In addition to a `~matplotlib.ticker.Formatter` instance,
1563+
this also accepts a `str` or function.
1564+
For a `str` a `~matplotlib.ticker.StrMethodFormatter` is used.
1565+
For a function a `~matplotlib.ticker.FuncFormatter` is used.
1566+
1567+
Parameters
1568+
----------
1569+
formatter : `~matplotlib.ticker.Formatter`, str, or function
1570+
level : `self.major` or `self.minor`
1571+
"""
1572+
if isinstance(formatter, str):
1573+
formatter = mticker.StrMethodFormatter(formatter)
1574+
# Don't allow any other TickHelper to avoid easy-to-make errors,
1575+
# like using a Locator instead of a Formatter.
1576+
elif (callable(formatter) and
1577+
not isinstance(formatter, mticker.TickHelper)):
1578+
formatter = mticker.FuncFormatter(formatter)
1579+
else:
1580+
cbook._check_isinstance(mticker.Formatter, formatter=formatter)
1581+
15561582
if (isinstance(formatter, mticker.FixedFormatter)
15571583
and len(formatter.seq) > 0
1558-
and not isinstance(self.minor.locator, mticker.FixedLocator)):
1584+
and not isinstance(level.locator, mticker.FixedLocator)):
15591585
cbook._warn_external('FixedFormatter should only be used together '
15601586
'with FixedLocator')
1561-
self.isDefault_minfmt = False
1562-
self.minor.formatter = formatter
1587+
1588+
if level == self.major:
1589+
self.isDefault_majfmt = False
1590+
else:
1591+
self.isDefault_minfmt = False
1592+
1593+
level.formatter = formatter
15631594
formatter.set_axis(self)
15641595
self.stale = True
15651596

lib/matplotlib/tests/test_axes.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,28 @@ def test_formatter_ticker():
203203
ax.autoscale_view()
204204

205205

206+
def test_auto_formatter():
207+
def _formfunc(x, pos):
208+
return ''
209+
210+
formstr = '{x}_{pos}'
211+
212+
ax = plt.figure().subplots()
213+
ax.xaxis.set_major_formatter(_formfunc)
214+
ax.yaxis.set_major_formatter(formstr)
215+
216+
targ_funcformatter = mticker.FuncFormatter(_formfunc)
217+
targ_strformatter = mticker.StrMethodFormatter(formstr)
218+
219+
assert isinstance(ax.xaxis.get_major_formatter(),
220+
mticker.FuncFormatter)
221+
assert isinstance(ax.yaxis.get_major_formatter(),
222+
mticker.StrMethodFormatter)
223+
224+
assert ax.xaxis.get_major_formatter().func == targ_funcformatter.func
225+
assert ax.yaxis.get_major_formatter().fmt == targ_strformatter.fmt
226+
227+
206228
@image_comparison(["twin_axis_locators_formatters"])
207229
def test_twin_axis_locators_formatters():
208230
vals = np.linspace(0, 1, num=5, endpoint=True)

lib/matplotlib/ticker.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,12 @@
159159
ax.yaxis.set_major_formatter(ymajor_formatter)
160160
ax.yaxis.set_minor_formatter(yminor_formatter)
161161
162+
For `.StrMethodFormatter`, `~.Axis.set_major_formatter` and
163+
`~.Axis.set_minor_formatter` accept a ``str``. In that case a
164+
`.StrMethodFormatter` will be automatically created and applied based on
165+
the given ``str``. Similalry, a `.FuncFormatter` will be automatically
166+
created and applied if a function is provided.
167+
162168
See :doc:`/gallery/ticks_and_spines/major_minor_demo` for an
163169
example of setting major and minor ticks. See the :mod:`matplotlib.dates`
164170
module for more information and examples of using date locators and formatters.

tutorials/text/text_intro.py

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -291,25 +291,26 @@
291291
axs[0].plot(x1, y1)
292292
axs[1].plot(x1, y1)
293293
ticks = np.arange(0., 8.1, 2.)
294-
# list comprehension to get all tick labels...
295294
formatter = matplotlib.ticker.StrMethodFormatter('{x:1.1f}')
296295
axs[1].xaxis.set_ticks(ticks)
297296
axs[1].xaxis.set_major_formatter(formatter)
298297
axs[1].set_xlim(axs[0].get_xlim())
299298
plt.show()
300299

301300
#############################################################################
301+
# A `matplotlib.ticker.StrMethodFormatter` can also be created by simply
302+
# passing a ``str`` without having to explicitly create the formatter.
303+
#
302304
# And of course we could have used a non-default locator to set the
303305
# tick locations. Note we still pass in the tick values, but the
304306
# x-limit fix used above is *not* needed.
305307

306308
fig, axs = plt.subplots(2, 1, figsize=(5, 3), tight_layout=True)
307309
axs[0].plot(x1, y1)
308310
axs[1].plot(x1, y1)
309-
formatter = matplotlib.ticker.FormatStrFormatter('%1.1f')
310311
locator = matplotlib.ticker.FixedLocator(ticks)
311312
axs[1].xaxis.set_major_locator(locator)
312-
axs[1].xaxis.set_major_formatter(formatter)
313+
axs[1].xaxis.set_major_formatter('±{x}°')
313314
plt.show()
314315

315316
#############################################################################
@@ -350,27 +351,29 @@
350351

351352
##############################################################################
352353
# Finally, we can specify functions for the formatter using
353-
# `matplotlib.ticker.FuncFormatter`.
354+
# `matplotlib.ticker.FuncFormatter`. Further, like
355+
# `matplotlib.ticker.StrMethodFormatter`, simply passing a function will
356+
# automatically create a `matplotlib.ticker.FuncFormatter`.
354357

355358

356359
def formatoddticks(x, pos):
357360
"""Format odd tick positions
358361
"""
359362
if x % 2:
360-
return '%1.2f' % x
363+
return '{:1.2f}'.format(x)
361364
else:
362365
return ''
363366

364367

365368
fig, ax = plt.subplots(figsize=(5, 3), tight_layout=True)
366369
ax.plot(x1, y1)
367-
formatter = matplotlib.ticker.FuncFormatter(formatoddticks)
368370
locator = matplotlib.ticker.MaxNLocator(nbins=6)
369-
ax.xaxis.set_major_formatter(formatter)
371+
ax.xaxis.set_major_formatter(formatoddticks)
370372
ax.xaxis.set_major_locator(locator)
371373

372374
plt.show()
373375

376+
374377
##############################################################################
375378
# Dateticks
376379
# ~~~~~~~~~

0 commit comments

Comments
 (0)