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

Skip to content

Commit c539736

Browse files
committed
Make ticklabel_format work both for 2D and 3D axes.
... instead of duplicating its implementation in axes3d with just minor changes. Note that ticklabel_format was not used anywhere either in the tests or in the examples. Exercise it in the scalarformatter example, which also gets slightly updated -- ScalarFormatter has been the default formatter for years, so doesn't really warrant the label "The new formatter".
1 parent 9e7a235 commit c539736

File tree

4 files changed

+87
-115
lines changed

4 files changed

+87
-115
lines changed

examples/ticks_and_spines/scalarformatter.py

Lines changed: 16 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,36 @@
11
"""
2-
=========================================
3-
Tick formatting using the ScalarFormatter
4-
=========================================
2+
==========================
3+
The default tick formatter
4+
==========================
55
6-
The example shows use of ScalarFormatter with different settings.
6+
The example shows use of the default `ScalarFormatter` with different settings.
77
88
Example 1 : Default
99
1010
Example 2 : With no Numerical Offset
1111
1212
Example 3 : With Mathtext
1313
"""
14+
1415
import matplotlib.pyplot as plt
1516
import numpy as np
16-
from matplotlib.ticker import ScalarFormatter
1717

1818
###############################################################################
1919
# Example 1
2020

2121
x = np.arange(0, 1, .01)
2222
fig, [[ax1, ax2], [ax3, ax4]] = plt.subplots(2, 2, figsize=(6, 6))
23-
fig.text(0.5, 0.975, 'The new formatter, default settings',
23+
fig.text(0.5, 0.975, 'Default settings',
2424
horizontalalignment='center',
2525
verticalalignment='top')
2626

2727
ax1.plot(x * 1e5 + 1e10, x * 1e-10 + 1e-5)
28-
ax1.xaxis.set_major_formatter(ScalarFormatter())
29-
ax1.yaxis.set_major_formatter(ScalarFormatter())
3028

3129
ax2.plot(x * 1e5, x * 1e-4)
32-
ax2.xaxis.set_major_formatter(ScalarFormatter())
33-
ax2.yaxis.set_major_formatter(ScalarFormatter())
3430

3531
ax3.plot(-x * 1e5 - 1e10, -x * 1e-5 - 1e-10)
36-
ax3.xaxis.set_major_formatter(ScalarFormatter())
37-
ax3.yaxis.set_major_formatter(ScalarFormatter())
3832

3933
ax4.plot(-x * 1e5, -x * 1e-4)
40-
ax4.xaxis.set_major_formatter(ScalarFormatter())
41-
ax4.yaxis.set_major_formatter(ScalarFormatter())
4234

4335
fig.subplots_adjust(wspace=0.7, hspace=0.6)
4436

@@ -47,25 +39,21 @@
4739

4840
x = np.arange(0, 1, .01)
4941
fig, [[ax1, ax2], [ax3, ax4]] = plt.subplots(2, 2, figsize=(6, 6))
50-
fig.text(0.5, 0.975, 'The new formatter, no numerical offset',
42+
fig.text(0.5, 0.975, 'No numerical offset',
5143
horizontalalignment='center',
5244
verticalalignment='top')
5345

5446
ax1.plot(x * 1e5 + 1e10, x * 1e-10 + 1e-5)
55-
ax1.xaxis.set_major_formatter(ScalarFormatter(useOffset=False))
56-
ax1.yaxis.set_major_formatter(ScalarFormatter(useOffset=False))
47+
ax1.ticklabel_format(useOffset=False)
5748

5849
ax2.plot(x * 1e5, x * 1e-4)
59-
ax2.xaxis.set_major_formatter(ScalarFormatter(useOffset=False))
60-
ax2.yaxis.set_major_formatter(ScalarFormatter(useOffset=False))
50+
ax2.ticklabel_format(useOffset=False)
6151

6252
ax3.plot(-x * 1e5 - 1e10, -x * 1e-5 - 1e-10)
63-
ax3.xaxis.set_major_formatter(ScalarFormatter(useOffset=False))
64-
ax3.yaxis.set_major_formatter(ScalarFormatter(useOffset=False))
53+
ax3.ticklabel_format(useOffset=False)
6554

6655
ax4.plot(-x * 1e5, -x * 1e-4)
67-
ax4.xaxis.set_major_formatter(ScalarFormatter(useOffset=False))
68-
ax4.yaxis.set_major_formatter(ScalarFormatter(useOffset=False))
56+
ax4.ticklabel_format(useOffset=False)
6957

7058
fig.subplots_adjust(wspace=0.7, hspace=0.6)
7159

@@ -74,25 +62,21 @@
7462

7563
x = np.arange(0, 1, .01)
7664
fig, [[ax1, ax2], [ax3, ax4]] = plt.subplots(2, 2, figsize=(6, 6))
77-
fig.text(0.5, 0.975, 'The new formatter, with mathtext',
65+
fig.text(0.5, 0.975, 'With mathtext',
7866
horizontalalignment='center',
7967
verticalalignment='top')
8068

8169
ax1.plot(x * 1e5 + 1e10, x * 1e-10 + 1e-5)
82-
ax1.xaxis.set_major_formatter(ScalarFormatter(useMathText=True))
83-
ax1.yaxis.set_major_formatter(ScalarFormatter(useMathText=True))
70+
ax1.ticklabel_format(useMathText=True)
8471

8572
ax2.plot(x * 1e5, x * 1e-4)
86-
ax2.xaxis.set_major_formatter(ScalarFormatter(useMathText=True))
87-
ax2.yaxis.set_major_formatter(ScalarFormatter(useMathText=True))
73+
ax2.ticklabel_format(useMathText=True)
8874

8975
ax3.plot(-x * 1e5 - 1e10, -x * 1e-5 - 1e-10)
90-
ax3.xaxis.set_major_formatter(ScalarFormatter(useMathText=True))
91-
ax3.yaxis.set_major_formatter(ScalarFormatter(useMathText=True))
76+
ax3.ticklabel_format(useMathText=True)
9277

9378
ax4.plot(-x * 1e5, -x * 1e-4)
94-
ax4.xaxis.set_major_formatter(ScalarFormatter(useMathText=True))
95-
ax4.yaxis.set_major_formatter(ScalarFormatter(useMathText=True))
79+
ax4.ticklabel_format(useMathText=True)
9680

9781
fig.subplots_adjust(wspace=0.7, hspace=0.6)
9882

lib/matplotlib/axes/_base.py

Lines changed: 33 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -2486,6 +2486,24 @@ def tol(x): return 1e-5 * abs(x) + 1e-8
24862486
def _get_axis_list(self):
24872487
return (self.xaxis, self.yaxis)
24882488

2489+
def _get_axis_map(self):
2490+
"""
2491+
Return a mapping of `Axis` "names" to `Axis` instances.
2492+
2493+
The `Axis` name is derived from the attribute under which the instance
2494+
is stored, so e.g. for polar axes, the theta-axis is still named "x"
2495+
and the r-axis is still named "y" (for back-compatibility).
2496+
2497+
In practice, this means that the entries are typically "x" and "y", and
2498+
additionally "z" for 3D axes.
2499+
"""
2500+
d = {}
2501+
axis_list = self._get_axis_list()
2502+
for k, v in vars(self).items():
2503+
if k.endswith("axis") and v in axis_list:
2504+
d[k[:-len("axis")]] = v
2505+
return d
2506+
24892507
def _update_title_position(self, renderer):
24902508
"""
24912509
Update the title position based on the bounding box enclosing
@@ -2825,35 +2843,24 @@ def ticklabel_format(self, *, axis='both', style='', scilimits=None,
28252843
sb = None
28262844
else:
28272845
raise ValueError("%s is not a valid style value")
2846+
axis_map = {**{k: [v] for k, v in self._get_axis_map().items()},
2847+
'both': self._get_axis_list()}
2848+
axises = cbook._check_getitem(axis_map, axis=axis)
28282849
try:
2829-
if sb is not None:
2830-
if axis == 'both' or axis == 'x':
2831-
self.xaxis.major.formatter.set_scientific(sb)
2832-
if axis == 'both' or axis == 'y':
2833-
self.yaxis.major.formatter.set_scientific(sb)
2834-
if scilimits is not None:
2835-
if axis == 'both' or axis == 'x':
2836-
self.xaxis.major.formatter.set_powerlimits(scilimits)
2837-
if axis == 'both' or axis == 'y':
2838-
self.yaxis.major.formatter.set_powerlimits(scilimits)
2839-
if useOffset is not None:
2840-
if axis == 'both' or axis == 'x':
2841-
self.xaxis.major.formatter.set_useOffset(useOffset)
2842-
if axis == 'both' or axis == 'y':
2843-
self.yaxis.major.formatter.set_useOffset(useOffset)
2844-
if useLocale is not None:
2845-
if axis == 'both' or axis == 'x':
2846-
self.xaxis.major.formatter.set_useLocale(useLocale)
2847-
if axis == 'both' or axis == 'y':
2848-
self.yaxis.major.formatter.set_useLocale(useLocale)
2849-
if useMathText is not None:
2850-
if axis == 'both' or axis == 'x':
2851-
self.xaxis.major.formatter.set_useMathText(useMathText)
2852-
if axis == 'both' or axis == 'y':
2853-
self.yaxis.major.formatter.set_useMathText(useMathText)
2850+
for axis in axises:
2851+
if sb is not None:
2852+
axis.major.formatter.set_scientific(sb)
2853+
if scilimits is not None:
2854+
axis.major.formatter.set_powerlimits(scilimits)
2855+
if useOffset is not None:
2856+
axis.major.formatter.set_useOffset(useOffset)
2857+
if useLocale is not None:
2858+
axis.major.formatter.set_useLocale(useLocale)
2859+
if useMathText is not None:
2860+
axis.major.formatter.set_useMathText(useMathText)
28542861
except AttributeError:
28552862
raise AttributeError(
2856-
"This method only works with the ScalarFormatter.")
2863+
"This method only works with the ScalarFormatter")
28572864

28582865
def locator_params(self, axis='both', tight=None, **kwargs):
28592866
"""

lib/matplotlib/tests/test_axes.py

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6495,3 +6495,41 @@ def test_set_ticks_inverted():
64956495
ax.invert_xaxis()
64966496
ax.set_xticks([.3, .7])
64976497
assert ax.get_xlim() == (1, 0)
6498+
6499+
6500+
@check_figures_equal(extensions=["png"])
6501+
def test_ticklabel_format(fig_test, fig_ref):
6502+
axs = fig_test.subplots(3, 5)
6503+
for ax in axs.flat:
6504+
ax.set_xlim(1e7, 1e7 + 10)
6505+
for row, name in zip(axs, ["x", "y", "both"]):
6506+
row[0].ticklabel_format(
6507+
axis=name, style="plain")
6508+
row[1].ticklabel_format(
6509+
axis=name, scilimits=(-2, 2))
6510+
row[2].ticklabel_format(
6511+
axis=name, useOffset=not mpl.rcParams["axes.formatter.useoffset"])
6512+
row[3].ticklabel_format(
6513+
axis=name, useLocale=not mpl.rcParams["axes.formatter.use_locale"])
6514+
row[4].ticklabel_format(
6515+
axis=name,
6516+
useMathText=not mpl.rcParams["axes.formatter.use_mathtext"])
6517+
6518+
def get_formatters(ax, names):
6519+
return [getattr(ax, name).get_major_formatter() for name in names]
6520+
6521+
axs = fig_ref.subplots(3, 5)
6522+
for ax in axs.flat:
6523+
ax.set_xlim(1e7, 1e7 + 10)
6524+
for row, names in zip(axs, [["xaxis"], ["yaxis"], ["xaxis", "yaxis"]]):
6525+
for fmt in get_formatters(row[0], names):
6526+
fmt.set_scientific(False)
6527+
for fmt in get_formatters(row[1], names):
6528+
fmt.set_powerlimits((-2, 2))
6529+
for fmt in get_formatters(row[2], names):
6530+
fmt.set_useOffset(not mpl.rcParams["axes.formatter.useoffset"])
6531+
for fmt in get_formatters(row[3], names):
6532+
fmt.set_useLocale(not mpl.rcParams["axes.formatter.use_locale"])
6533+
for fmt in get_formatters(row[4], names):
6534+
fmt.set_useMathText(
6535+
not mpl.rcParams["axes.formatter.use_mathtext"])

lib/mpl_toolkits/mplot3d/axes3d.py

Lines changed: 0 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -1295,63 +1295,6 @@ def grid(self, b=True, **kwargs):
12951295
self._draw_grid = b
12961296
self.stale = True
12971297

1298-
def ticklabel_format(
1299-
self, *, style='', scilimits=None, useOffset=None, axis='both'):
1300-
"""
1301-
Convenience method for manipulating the ScalarFormatter
1302-
used by default for linear axes in Axed3D objects.
1303-
1304-
See :meth:`matplotlib.axes.Axes.ticklabel_format` for full
1305-
documentation. Note that this version applies to all three
1306-
axes of the Axes3D object. Therefore, the *axis* argument
1307-
will also accept a value of 'z' and the value of 'both' will
1308-
apply to all three axes.
1309-
1310-
.. versionadded :: 1.1.0
1311-
This function was added, but not tested. Please report any bugs.
1312-
"""
1313-
style = style.lower()
1314-
axis = axis.lower()
1315-
if scilimits is not None:
1316-
try:
1317-
m, n = scilimits
1318-
m+n+1 # check that both are numbers
1319-
except (ValueError, TypeError):
1320-
raise ValueError("scilimits must be a sequence of 2 integers")
1321-
if style[:3] == 'sci':
1322-
sb = True
1323-
elif style == 'plain':
1324-
sb = False
1325-
elif style == '':
1326-
sb = None
1327-
else:
1328-
raise ValueError("%s is not a valid style value")
1329-
try:
1330-
if sb is not None:
1331-
if axis in ['both', 'z']:
1332-
self.xaxis.major.formatter.set_scientific(sb)
1333-
if axis in ['both', 'y']:
1334-
self.yaxis.major.formatter.set_scientific(sb)
1335-
if axis in ['both', 'z']:
1336-
self.zaxis.major.formatter.set_scientific(sb)
1337-
if scilimits is not None:
1338-
if axis in ['both', 'x']:
1339-
self.xaxis.major.formatter.set_powerlimits(scilimits)
1340-
if axis in ['both', 'y']:
1341-
self.yaxis.major.formatter.set_powerlimits(scilimits)
1342-
if axis in ['both', 'z']:
1343-
self.zaxis.major.formatter.set_powerlimits(scilimits)
1344-
if useOffset is not None:
1345-
if axis in ['both', 'x']:
1346-
self.xaxis.major.formatter.set_useOffset(useOffset)
1347-
if axis in ['both', 'y']:
1348-
self.yaxis.major.formatter.set_useOffset(useOffset)
1349-
if axis in ['both', 'z']:
1350-
self.zaxis.major.formatter.set_useOffset(useOffset)
1351-
except AttributeError:
1352-
raise AttributeError(
1353-
"This method only works with the ScalarFormatter.")
1354-
13551298
def locator_params(self, axis='both', tight=None, **kwargs):
13561299
"""
13571300
Convenience method for controlling tick locators.

0 commit comments

Comments
 (0)