Skip to content

Commit 9e1b7ae

Browse files
committed
Avoid draw_marker optimization on large paths
Fix #3626
1 parent 0202f3b commit 9e1b7ae

File tree

2 files changed

+30
-4
lines changed

2 files changed

+30
-4
lines changed

lib/matplotlib/collections.py

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -274,22 +274,31 @@ def draw(self, renderer):
274274
trans = self.get_transforms()
275275
facecolors = self.get_facecolor()
276276
edgecolors = self.get_edgecolor()
277+
do_single_path_optimization = False
277278
if (len(paths) == 1 and len(trans) <= 1 and
278279
len(facecolors) == 1 and len(edgecolors) == 1 and
279280
len(self._linewidths) == 1 and
280281
self._linestyles == [(None, None)] and
281282
len(self._antialiaseds) == 1 and len(self._urls) == 1 and
282283
self.get_hatch() is None):
284+
if len(trans):
285+
combined_transform = (transforms.Affine2D(trans[0]) +
286+
transform)
287+
else:
288+
combined_transform = transform
289+
extents = paths[0].get_extents(combined_transform)
290+
if (extents.width < renderer.width and
291+
extents.height < renderer.height):
292+
do_single_path_optimization = True
293+
294+
if do_single_path_optimization:
283295
gc.set_foreground(tuple(edgecolors[0]))
284296
gc.set_linewidth(self._linewidths[0])
285297
gc.set_linestyle(self._linestyles[0])
286298
gc.set_antialiased(self._antialiaseds[0])
287299
gc.set_url(self._urls[0])
288-
if len(trans):
289-
transform = (transforms.Affine2D(trans[0]) +
290-
transform)
291300
renderer.draw_markers(
292-
gc, paths[0], transform.frozen(),
301+
gc, paths[0], combined_transform.frozen(),
293302
mpath.Path(offsets), transOffset, tuple(facecolors[0]))
294303
else:
295304
renderer.draw_path_collection(

lib/matplotlib/tests/test_agg.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,14 @@
66
import io
77
import os
88

9+
import numpy as np
910
from numpy.testing import assert_array_almost_equal
1011

1112
from matplotlib.image import imread
1213
from matplotlib.backends.backend_agg import FigureCanvasAgg as FigureCanvas
1314
from matplotlib.figure import Figure
1415
from matplotlib.testing.decorators import cleanup
16+
from matplotlib import pyplot as plt
1517

1618

1719
@cleanup
@@ -47,6 +49,21 @@ def test_repeated_save_with_alpha():
4749
decimal=3)
4850

4951

52+
@cleanup
53+
def test_large_single_path_collection():
54+
buff = io.BytesIO()
55+
56+
# Generates a too-large single path in a path collection that
57+
# would cause a segfault if the draw_markers optimization is
58+
# applied.
59+
f, ax = plt.subplots()
60+
x = np.logspace(-10, 5, 20)
61+
data = np.random.random((2, 20))
62+
ax.stackplot(x, *data)
63+
ax.set_xlim(10**-3, 1) # broken
64+
plt.savefig(buff)
65+
66+
5067
def report_memory(i):
5168
pid = os.getpid()
5269
a2 = os.popen('ps -p %d -o rss,sz' % pid).readlines()

0 commit comments

Comments
 (0)