1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
|
From 3cc6610597ee16a0cce39f7b033ae529972177e7 Mon Sep 17 00:00:00 2001
From: Elliott Sales de Andrade <quantum.analyst@gmail.com>
Date: Thu, 10 Aug 2023 00:09:53 -0400
Subject: [PATCH] TST: Improve test for Legend(loc='best') warning
By patching the timer instead of using actually large data, we can both
a) speed up these tests (~7.5s vs <0.2s for both), and b) consistently
trigger the warning even on systems which are fast (such as the M1
systems on Cirrus.)
Also, copy the test data from `test_legend_auto3`, which correctly hits
all candidate locations for the 'best' legend locator without having to
fill up the entire Axes with data.
---
lib/matplotlib/tests/test_legend.py | 38 ++++++++++++++++++++---------
1 file changed, 27 insertions(+), 11 deletions(-)
diff --git a/lib/matplotlib/tests/test_legend.py b/lib/matplotlib/tests/test_legend.py
index 759ac6aadaff..1549354ba56b 100644
--- a/lib/matplotlib/tests/test_legend.py
+++ b/lib/matplotlib/tests/test_legend.py
@@ -1,5 +1,7 @@
import collections
+import itertools
import platform
+import time
from unittest import mock
import warnings
@@ -1109,29 +1111,43 @@ def test_usetex_no_warn(caplog):
assert "Font family ['serif'] not found." not in caplog.text
-def test_warn_big_data_best_loc():
+def test_warn_big_data_best_loc(monkeypatch):
+ # Force _find_best_position to think it took a long time.
+ counter = itertools.count(0, step=1.5)
+ monkeypatch.setattr(time, 'perf_counter', lambda: next(counter))
+
fig, ax = plt.subplots()
fig.canvas.draw() # So that we can call draw_artist later.
- for idx in range(1000):
- ax.plot(np.arange(5000), label=idx)
+
+ # Place line across all possible legend locations.
+ x = [0.9, 0.1, 0.1, 0.9, 0.9, 0.5]
+ y = [0.95, 0.95, 0.05, 0.05, 0.5, 0.5]
+ ax.plot(x, y, 'o-', label='line')
+
with rc_context({'legend.loc': 'best'}):
legend = ax.legend()
- with pytest.warns(UserWarning) as records:
+ with pytest.warns(UserWarning,
+ match='Creating legend with loc="best" can be slow with large '
+ 'amounts of data.') as records:
fig.draw_artist(legend) # Don't bother drawing the lines -- it's slow.
# The _find_best_position method of Legend is called twice, duplicating
# the warning message.
assert len(records) == 2
- for record in records:
- assert str(record.message) == (
- 'Creating legend with loc="best" can be slow with large '
- 'amounts of data.')
-def test_no_warn_big_data_when_loc_specified():
+def test_no_warn_big_data_when_loc_specified(monkeypatch):
+ # Force _find_best_position to think it took a long time.
+ counter = itertools.count(0, step=1.5)
+ monkeypatch.setattr(time, 'perf_counter', lambda: next(counter))
+
fig, ax = plt.subplots()
fig.canvas.draw()
- for idx in range(1000):
- ax.plot(np.arange(5000), label=idx)
+
+ # Place line across all possible legend locations.
+ x = [0.9, 0.1, 0.1, 0.9, 0.9, 0.5]
+ y = [0.95, 0.95, 0.05, 0.05, 0.5, 0.5]
+ ax.plot(x, y, 'o-', label='line')
+
legend = ax.legend('best')
fig.draw_artist(legend) # Check that no warning is emitted.
|