8000 Improve step performance · matplotlib/matplotlib@72131a9 · GitHub
[go: up one dir, main page]

Skip to content

Commit 72131a9

Browse files
committed
Improve step performance
1 parent 46ba49a commit 72131a9

File tree

6 files changed

+61
-18
lines changed

6 files changed

+61
-18
lines changed

doc/api/api_changes/2017-10-24-DS.rst

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
`StemContainer` now stores `LineCollection`
2+
-------------------------------------------
3+
4+
`StemContainer` objects now store a `LineCollection` object instead of a list
5+
of `Line2D` objects for stem lines plotted using `ax.stem`. This gives a very
6+
large performance boost to displaying and moving `ax.stem` plots.
7+
8+
Line segments can be extracted from the `LineCollection` using
9+
`LineCollection.get_segements()`. See the `LineCollection` documentation for
10+
other methods to retrieve the collection properties.

lib/matplotlib/axes/_axes.py

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2614,6 +2614,9 @@ def stem(self, *args, linefmt=None, markerfmt=None, basefmt=None,
26142614
x = y
26152615
y = np.asarray(args[0], dtype=float)
26162616
args = args[1:]
2617+
self._process_unit_info(xdata=x, ydata=y)
2618+
x = self.convert_xunits(x)
2619+
y = self.convert_yunits(y)
26172620

26182621
# defaults for formats
26192622
if linefmt is None:
@@ -2665,12 +2668,12 @@ def stem(self, *args, linefmt=None, markerfmt=None, basefmt=None,
26652668
markerline, = self.plot(x, y, color=markercolor, linestyle=markerstyle,
26662669
marker=markermarker, label="_nolegend_")
26672670

2668-
stemlines = []
2671+
lines = []
26692672
for thisx, thisy in zip(x, y):
2670-
l, = self.plot([thisx, thisx], [bottom, thisy],
2671-
color=linecolor, linestyle=linestyle,
2672-
marker=linemarker, label="_nolegend_")
2673-
stemlines.append(l)
2673+
lines.append(((thisx, bottom), (thisx, thisy)))
2674+
stemlines = mcoll.LineCollection(lines, linestyles=linestyle,
2675+
colors=linecolor, label='_nolegend_')
2676+
self.add_collection(stemlines)
26742677

26752678
baseline, = self.plot([np.min(x), np.max(x)], [bottom, bottom],
26762679
color=basecolor, linestyle=basestyle,

lib/matplotlib/container.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -174,10 +174,17 @@ class StemContainer(Container):
174174
175175
baseline : :class:`~matplotlib.lines.Line2D`
176176
The artist of the horizontal baseline.
177-
178177
"""
179-
180178
def __init__(self, markerline_stemlines_baseline, **kwargs):
179+
'''
180+
Parameters
181+
----------
182+
markerline_stemlines_baseline : tuple
183+
Tuple of ``(markerline, stemlines, baseline)``.
184+
``markerline`` contains the `LineCollection` of the markers,
185+
``stemlines`` is a `LineCollection` of the main lines,
186+
``baseline`` is the `Line2D` of the baseline.
187+
'''
181188
markerline, stemlines, baseline = markerline_stemlines_baseline
182189
self.markerline = markerline
183190
self.stemlines = stemlines

lib/matplotlib/legend_handler.py

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -589,7 +589,6 @@ def get_ydata(self, legend, xdescent, ydescent, width, height, fontsize):
589589
def create_artists(self, legend, orig_handle,
590590
xdescent, ydescent, width, height, fontsize,
591591
trans):
592-
593592
markerline, stemlines, baseline = orig_handle
594593

595594
xdata, xdata_marker = self.get_xdata(legend, xdescent, ydescent,
@@ -603,31 +602,44 @@ def create_artists(self, legend, orig_handle,
603602
else:
604603
bottom = self._bottom
605604

606-
leg_markerline = Line2D(xdata_marker, ydata[:len(xdata_marker)])
607-
self.update_prop(leg_markerline, markerline, legend)
608-
609605
leg_stemlines = []
610-
for thisx, thisy in zip(xdata_marker, ydata):
611-
l = Line2D([thisx, thisx], [bottom, thisy])
612-
leg_stemlines.append(l)
613606

614-
for lm, m in zip(leg_stemlines, stemlines):
615-
self.update_prop(lm, m, legend)
607+
# update_prop() usually takes two Line2D collections;
608+
# override temporarily to copy properties from a LineCollection
609+
orig_update_func = self._update_prop_func
610+
self._update_prop_func = self._copy_collection_props
611+
612+
for thisx, thisy in zip(xdata_marker, ydata):
613+
thisline = Line2D([thisx, thisx], [bottom, thisy])
614+
leg_stemlines.append(thisline)
615+
self.update_prop(thisline, stemlines, legend)
616+
# Reset update_prop_func
617+
self._update_prop_func = orig_update_func
616618

617619
leg_baseline = Line2D([np.min(xdata), np.max(xdata)],
618620
[bottom, bottom])
619621

620622
self.update_prop(leg_baseline, baseline, legend)
621623

622-
artists = [leg_markerline]
623-
artists.extend(leg_stemlines)
624+
leg_markerline = Line2D(xdata_marker, ydata[:len(xdata_marker)])
625+
self.update_prop(leg_markerline, markerline, legend)
626+
627+
artists = leg_stemlines
624628
artists.append(leg_baseline)
629+
artists.append(leg_markerline)
625630

626631
for artist in artists:
627632
artist.set_transform(trans)
628633

629634
return artists
630635

636+
def _copy_collection_props(self, legend_handle, orig_handle):
637+
'''
638+
Method to copy properties from a LineCollection (orig_handle) to a
639+
Line2D (legend_handle).
640+
'''
641+
legend_handle._color = orig_handle.get_color()[0]
642+
631643

632644
class HandlerTuple(HandlerBase):
633645
"""
Loading

lib/matplotlib/tests/test_axes.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2958,6 +2958,17 @@ def test_hist_stacked_weighted():
29582958
ax.hist((d1, d2), weights=(w1, w2), histtype="stepfilled", stacked=True)
29592959

29602960

2961+
@image_comparison(baseline_images=['stem'], extensions=['png'], style='mpl20',
2962+
remove_text=True)
2963+
def test_stem():
2964+
x = np.linspace(0.1, 2 * np.pi, 100)
2965+
2966+
fig, ax = plt.subplots()
2967+
ax.stem(x, np.cos(x), linefmt='C2-', markerfmt='k+', basefmt='C1-.',
2968+
label='Stem')
2969+
ax.legend()
2970+
2971+
29612972
def test_stem_args():
29622973
fig = plt.figure()
29632974
ax = fig.add_subplot(1, 1, 1)

0 commit comments

Comments
 (0)
0