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

Skip to content

Commit 5a41aec

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 18a30ce commit 5a41aec

File tree

3 files changed

+30
-8
lines changed

3 files changed

+30
-8
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
@@ -135,12 +135,13 @@ def test_date_axvline():
135135
fig.autofmt_xdate()
136136

137137

138-
def test_too_many_date_ticks():
138+
def test_too_many_date_ticks(caplog):
139139
# Attempt to test SF 2715172, see
140140
# https://sourceforge.net/tracker/?func=detail&aid=2715172&group_id=80706&atid=560720
141141
# setting equal datetimes triggers and expander call in
142142
# transforms.nonsingular which results in too many ticks in the
143-
# DayLocator. This should trigger a Locator.MAXTICKS RuntimeError
143+
# DayLocator. This should emit a log at WARNING level.
144+
caplog.set_level("WARNING")
144145
t0 = datetime.datetime(2000, 1, 20)
145146
tf = datetime.datetime(2000, 1, 20)
146147
fig = plt.figure()
@@ -152,8 +153,13 @@ def test_too_many_date_ticks():
152153
'Attempting to set identical left == right' in str(rec[0].message)
153154
ax.plot([], [])
154155
ax.xaxis.set_major_locator(mdates.DayLocator())
155-
with pytest.raises(RuntimeError):
156-
fig.savefig('junk.png')
156+
fig.canvas.draw()
157+
# The warning is emitted multiple times because the major locator is also
158+
# called both when placing the minor ticks (for overstriking detection) and
159+
# during tick label positioning.
160+
assert caplog.records and all(
161+
record.name == "matplotlib.ticker" and record.levelname == "WARNING"
162+
for record in caplog.records)
157163

158164

159165
@image_comparison(['RRuleLocator_bounds.png'])

lib/matplotlib/ticker.py

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1690,11 +1690,21 @@ def __call__(self):
16901690
raise NotImplementedError('Derived must override')
16911691

16921692
def raise_if_exceeds(self, locs):
1693-
"""Raise a RuntimeError if ``len(locs) > self.MAXTICKS``."""
1693+
"""
1694+
Log at WARNING level if *locs* is longer than `Locator.MAXTICKS`.
1695+
1696+
This is intended to be called immediately before returning *locs* from
1697+
``__call__`` to inform users in case their Locator returns a huge
1698+
number of ticks, causing Matplotlib to run out of memory.
1699+
1700+
The "strange" name of this method dates back to when it would raise an
1701+
exception instead of emitting a log.
1702+
"""
16941703
if len(locs) >= self.MAXTICKS:
1695-
raise RuntimeError("Locator attempting to generate {} ticks from "
1696-
"{} to {}: exceeds Locator.MAXTICKS".format(
1697-
len(locs), locs[0], locs[-1]))
1704+
_log.warning(
1705+
"Locator attempting to generate %s ticks ([%s, ..., %s]), "
1706+
"which exceeds Locator.MAXTICKS (%s).",
1707+
len(locs), locs[0], locs[-1], self.MAXTICKS)
16981708
return locs
16991709

17001710
def nonsingular(self, v0, v1):

0 commit comments

Comments
 (0)