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

Skip to content

Commit 81086b3

Browse files
committed
Merge pull request #1531 from pierre-haessig/master
fix rendering slowdown with big invisible lines (issue #1256)
2 parents 47b13a0 + c94c730 commit 81086b3

File tree

4 files changed

+66
-2
lines changed

4 files changed

+66
-2
lines changed

lib/matplotlib/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1097,6 +1097,7 @@ def tk_window_focus():
10971097
'matplotlib.tests.test_figure',
10981098
'matplotlib.tests.test_image',
10991099
'matplotlib.tests.test_legend',
1100+
'matplotlib.tests.test_lines',
11001101
'matplotlib.tests.test_mathtext',
11011102
'matplotlib.tests.test_mlab',
11021103
'matplotlib.tests.test_patches',

lib/matplotlib/lines.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -484,6 +484,9 @@ def _is_sorted(self, x):
484484

485485
@allow_rasterization
486486
def draw(self, renderer):
487+
"""draw the Line with `renderer` unless visiblity is False"""
488+
if not self.get_visible(): return
489+
487490
if self._invalidy or self._invalidx:
488491
self.recache()
489492
self.ind_offset = 0 # Needed for contains() method.
@@ -498,8 +501,6 @@ def draw(self, renderer):
498501

499502
transformed_path = self._get_transformed_path()
500503

501-
if not self.get_visible(): return
502-
503504
renderer.open_group('line2d', self.get_gid())
504505
gc = renderer.new_gc()
505506
self._set_gc_clip(gc)

lib/matplotlib/tests/README

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
About Matplotlib Testing Infrastructure
2+
---------------------------------------
3+
4+
Information on the testing infrastructure is provided in
5+
the Testing section of the Matplotlib Developers’ Guide:
6+
7+
* http://matplotlib.org/devel/testing.html
8+
* <mpl_source_dir>/doc/devel/coding_guide.rst (equivalent, but in reST format)
9+

lib/matplotlib/tests/test_lines.py

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
"""
2+
Tests specific to the lines module.
3+
"""
4+
5+
from nose.tools import assert_true
6+
from timeit import repeat
7+
import numpy as np
8+
import matplotlib as mpl
9+
import matplotlib.pyplot as plt
10+
from matplotlib.testing.decorators import cleanup
11+
12+
@cleanup
13+
def test_invisible_Line_rendering():
14+
"""
15+
Github issue #1256 identified a bug in Line.draw method
16+
17+
Despite visibility attribute set to False, the draw method was not
18+
returning early enough and some pre-rendering code was executed
19+
though not necessary.
20+
21+
Consequence was an excessive draw time for invisible Line instances
22+
holding a large number of points (Npts> 10**6)
23+
"""
24+
# Creates big x and y data:
25+
N = 10**7
26+
x = np.linspace(0,1,N)
27+
y = np.random.normal(size=N)
28+
29+
# Create a plot figure:
30+
fig = plt.figure()
31+
ax = plt.subplot(111)
32+
33+
# Create a "big" Line instance:
34+
l = mpl.lines.Line2D(x,y)
35+
l.set_visible(False)
36+
# but don't add it to the Axis instance `ax`
37+
38+
# [here Interactive panning and zooming is pretty responsive]
39+
# Time the canvas drawing:
40+
t_no_line = min(repeat(fig.canvas.draw, number=1, repeat=3))
41+
# (gives about 25 ms)
42+
43+
# Add the big invisible Line:
44+
ax.add_line(l)
45+
46+
# [Now interactive panning and zooming is very slow]
47+
# Time the canvas drawing:
48+
t_unvisible_line = min(repeat(fig.canvas.draw, number=1, repeat=3))
49+
# gives about 290 ms for N = 10**7 pts
50+
51+
slowdown_factor = (t_unvisible_line/t_no_line)
52+
slowdown_threshold = 2 # trying to avoid false positive failures
53+
assert_true(slowdown_factor < slowdown_threshold)

0 commit comments

Comments
 (0)