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

Skip to content

Commit 06bdf1e

Browse files
committed
Change Locator MAXTICKS checking to emitting a log at WARNING level.
I chose not to create a new helper method and instead change the behavior of raise_if_exceeds, so that third-party locators also benefit from the change.
1 parent 9221a55 commit 06bdf1e

File tree

3 files changed

+30
-9
lines changed

3 files changed

+30
-9
lines changed
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
API changes
2+
```````````
3+
4+
When more than `Locator.MAXTICKS` ticks are generated, the behavior of
5+
`Locator.raise_if_exceeds` changed from raising a RuntimeError to emitting a
6+
log at WARNING level.

lib/matplotlib/tests/test_dates.py

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -143,12 +143,13 @@ def test_date_axvline():
143143
fig.autofmt_xdate()
144144

145145

146-
def test_too_many_date_ticks():
146+
def test_too_many_date_ticks(caplog):
147147
# Attempt to test SF 2715172, see
148148
# https://sourceforge.net/tracker/?func=detail&aid=2715172&group_id=80706&atid=560720
149149
# setting equal datetimes triggers and expander call in
150150
# transforms.nonsingular which results in too many ticks in the
151-
# DayLocator. This should trigger a Locator.MAXTICKS RuntimeError
151+
# DayLocator. This should emit a log at WARNING level.
152+
caplog.set_level("WARNING")
152153
t0 = datetime.datetime(2000, 1, 20)
153154
tf = datetime.datetime(2000, 1, 20)
154155
fig = plt.figure()
@@ -160,8 +161,13 @@ def test_too_many_date_ticks():
160161
'Attempting to set identical left == right' in str(rec[0].message)
161162
ax.plot([], [])
162163
ax.xaxis.set_major_locator(mdates.DayLocator())
163-
with pytest.raises(RuntimeError):
164-
fig.savefig('junk.png')
164+
fig.canvas.draw()
165+
# The warning is emitted multiple times because the major locator is also
166+
# called both when placing the minor ticks (for overstriking detection) and
167+
# during tick label positioning.
168+
assert caplog.records and all(
169+
record.name == "matplotlib.ticker" and record.levelname == "WARNING"
170+
for record in caplog.records)
165171

166172

167173
@image_comparison(baseline_images=['RRuleLocator_bounds'], extensions=['png'])

lib/matplotlib/ticker.py

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1455,12 +1455,21 @@ def __call__(self):
14551455
raise NotImplementedError('Derived must override')
14561456

14571457
def raise_if_exceeds(self, locs):
1458-
"""raise a RuntimeError if Locator attempts to create more than
1459-
MAXTICKS locs"""
1458+
"""
1459+
Log at WARNING level if *locs* is longer than `Locator.MAXTICKS`.
1460+
1461+
This is intended to be called immediately before returning *locs* from
1462+
``__call__`` to inform users in case their Locator returns a huge
1463+
number of ticks, causing Matplotlib to run out of memory.
1464+
1465+
The "strange" name of this method dates back to when it would raise an
1466+
exception instead of emitting a log.
1467+
"""
14601468
if len(locs) >= self.MAXTICKS:
1461-
raise RuntimeError("Locator attempting to generate {} ticks from "
1462-
"{} to {}: exceeds Locator.MAXTICKS".format(
1463-
len(locs), locs[0], locs[-1]))
1469+
_log.warning(
1470+
"Locator attempting to generate %s ticks ([%s, ..., %s]), "
1471+
"which exceeds Locator.MAXTICKS (%s).",
1472+
len(locs), locs[0], locs[-1], self.MAXTICKS)
14641473
return locs
14651474

14661475
def nonsingular(self, v0, v1):

0 commit comments

Comments
 (0)