Skip to content

Commit fb98a9a

Browse files
authored
Merge pull request #10321 from HHest/patch-1
Ability to scale axis by a fixed factor
2 parents 0d71eba + 5465a81 commit fb98a9a

File tree

4 files changed

+40
-1
lines changed

4 files changed

+40
-1
lines changed
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
Ability to scale axis by a fixed order of magnitude
2+
---------------------------------------------------
3+
4+
To scale an axis by a fixed order of magnitude, set the *scilimits* argument of
5+
``Axes.ticklabel_format`` to the same (non-zero) lower and upper limits. Say to scale
6+
the y axis by a million (1e6), use ``ax.ticklabel_format(style='sci', scilimits=(6, 6), axis='y')``.
7+
8+
The behavior of ``scilimits=(0, 0)`` is unchanged. With this setting, matplotlib will adjust
9+
the order of magnitude depending on the axis values, rather than keeping it fixed. Previously, setting
10+
``scilimits=(m, m)`` was equivalent to setting ``scilimits=(0, 0)``.

lib/matplotlib/axes/_base.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2719,6 +2719,8 @@ def ticklabel_format(self, *, axis='both', style='', scilimits=None,
27192719
be used for numbers outside the range
27202720
10`m`:sup: to 10`n`:sup:.
27212721
Use (0,0) to include all numbers.
2722+
Use (m,m) where m <> 0 to fix the order
2723+
of magnitude to 10`m`:sup:.
27222724
*useOffset* [ bool | offset ]; if True,
27232725
the offset will be calculated as needed;
27242726
if False, no offset will be used; if a

lib/matplotlib/tests/test_ticker.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,17 @@ class TestScalarFormatter(object):
226226

227227
use_offset_data = [True, False]
228228

229+
scilimits_data = [
230+
(False, (0, 0), (10.0, 20.0), 0),
231+
(True, (-2, 2), (-10, 20), 0),
232+
(True, (-2, 2), (-20, 10), 0),
233+
(True, (-2, 2), (-110, 120), 2),
234+
(True, (-2, 2), (-120, 110), 2),
235+
(True, (-2, 2), (-.001, 0.002), -3),
236+
(True, (0, 0), (-1e5, 1e5), 5),
237+
(True, (6, 6), (-1e5, 1e5), 6),
238+
]
239+
229240
@pytest.mark.parametrize('left, right, offset', offset_data)
230241
def test_offset_value(self, left, right, offset):
231242
fig, ax = plt.subplots()
@@ -255,6 +266,18 @@ def test_use_offset(self, use_offset):
255266
tmp_form = mticker.ScalarFormatter()
256267
assert use_offset == tmp_form.get_useOffset()
257268

269+
@pytest.mark.parametrize(
270+
'sci_type, scilimits, lim, orderOfMag', scilimits_data)
271+
def test_scilimits(self, sci_type, scilimits, lim, orderOfMag):
272+
tmp_form = mticker.ScalarFormatter()
273+
tmp_form.set_scientific(sci_type)
274+
tmp_form.set_powerlimits(scilimits)
275+
fig, ax = plt.subplots()
276+
ax.yaxis.set_major_formatter(tmp_form)
277+
ax.set_ylim(*lim)
278+
tmp_form.set_locs(ax.yaxis.get_majorticklocs())
279+
assert orderOfMag == tmp_form.orderOfMagnitude
280+
258281

259282
class FakeAxis(object):
260283
"""Allow Formatter to be called without having a "full" plot set up."""

lib/matplotlib/ticker.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -709,10 +709,14 @@ def _compute_offset(self):
709709
def _set_orderOfMagnitude(self, range):
710710
# if scientific notation is to be used, find the appropriate exponent
711711
# if using an numerical offset, find the exponent after applying the
712-
# offset
712+
# offset. When lower power limit = upper <> 0, use provided exponent.
713713
if not self._scientific:
714714
self.orderOfMagnitude = 0
715715
return
716+
if self._powerlimits[0] == self._powerlimits[1] != 0:
717+
# fixed scaling when lower power limit = upper <> 0.
718+
self.orderOfMagnitude = self._powerlimits[0]
719+
return
716720
locs = np.abs(self.locs)
717721
if self.offset:
718722
oom = math.floor(math.log10(range))

0 commit comments

Comments
 (0)