From 1a85e2d1ff97ccf18359d6bbcb24ecca10e543eb Mon Sep 17 00:00:00 2001 From: David Stansby Date: Tue, 24 Oct 2017 20:29:01 +0100 Subject: [PATCH] Improve step performance --- doc/api/api_changes/2017-10-24-DS.rst | 10 ++++++ lib/matplotlib/axes/_axes.py | 13 ++++--- lib/matplotlib/container.py | 11 ++++-- lib/matplotlib/legend_handler.py | 34 ++++++++++++------ .../tests/baseline_images/test_axes/stem.png | Bin 0 -> 14306 bytes lib/matplotlib/tests/test_axes.py | 11 ++++++ 6 files changed, 61 insertions(+), 18 deletions(-) create mode 100644 doc/api/api_changes/2017-10-24-DS.rst create mode 100644 lib/matplotlib/tests/baseline_images/test_axes/stem.png diff --git a/doc/api/api_changes/2017-10-24-DS.rst b/doc/api/api_changes/2017-10-24-DS.rst new file mode 100644 index 000000000000..c1c3c6ec9c55 --- /dev/null +++ b/doc/api/api_changes/2017-10-24-DS.rst @@ -0,0 +1,10 @@ +`StemContainer` now stores `LineCollection` +------------------------------------------- + +`StemContainer` objects now store a `LineCollection` object instead of a list +of `Line2D` objects for stem lines plotted using `ax.stem`. This gives a very +large performance boost to displaying and moving `ax.stem` plots. + +Line segments can be extracted from the `LineCollection` using +`LineCollection.get_segements()`. See the `LineCollection` documentation for +other methods to retrieve the collection properties. diff --git a/lib/matplotlib/axes/_axes.py b/lib/matplotlib/axes/_axes.py index 9fa6e6650b00..67d5d5007aa1 100644 --- a/lib/matplotlib/axes/_axes.py +++ b/lib/matplotlib/axes/_axes.py @@ -2370,6 +2370,9 @@ def stem(self, *args, linefmt=None, markerfmt=None, basefmt=None, x = y y = np.asarray(args[0], dtype=float) args = args[1:] + self._process_unit_info(xdata=x, ydata=y) + x = self.convert_xunits(x) + y = self.convert_yunits(y) # defaults for formats if linefmt is None: @@ -2421,12 +2424,12 @@ def stem(self, *args, linefmt=None, markerfmt=None, basefmt=None, markerline, = self.plot(x, y, color=markercolor, linestyle=markerstyle, marker=markermarker, label="_nolegend_") - stemlines = [] + lines = [] for thisx, thisy in zip(x, y): - l, = self.plot([thisx, thisx], [bottom, thisy], - color=linecolor, linestyle=linestyle, - marker=linemarker, label="_nolegend_") - stemlines.append(l) + lines.append(((thisx, bottom), (thisx, thisy))) + stemlines = mcoll.LineCollection(lines, linestyles=linestyle, + colors=linecolor, label='_nolegend_') + self.add_collection(stemlines) baseline, = self.plot([np.min(x), np.max(x)], [bottom, bottom], color=basecolor, linestyle=basestyle, diff --git a/lib/matplotlib/container.py b/lib/matplotlib/container.py index 552d6da5a761..0f71c606fe5c 100644 --- a/lib/matplotlib/container.py +++ b/lib/matplotlib/container.py @@ -174,10 +174,17 @@ class StemContainer(Container): baseline : :class:`~matplotlib.lines.Line2D` The artist of the horizontal baseline. - """ - def __init__(self, markerline_stemlines_baseline, **kwargs): + ''' + Parameters + ---------- + markerline_stemlines_baseline : tuple + Tuple of ``(markerline, stemlines, baseline)``. + ``markerline`` contains the `LineCollection` of the markers, + ``stemlines`` is a `LineCollection` of the main lines, + ``baseline`` is the `Line2D` of the baseline. + ''' markerline, stemlines, baseline = markerline_stemlines_baseline self.markerline = markerline self.stemlines = stemlines diff --git a/lib/matplotlib/legend_handler.py b/lib/matplotlib/legend_handler.py index ad574dcf33d0..44f1afc0b236 100644 --- a/lib/matplotlib/legend_handler.py +++ b/lib/matplotlib/legend_handler.py @@ -589,7 +589,6 @@ def get_ydata(self, legend, xdescent, ydescent, width, height, fontsize): def create_artists(self, legend, orig_handle, xdescent, ydescent, width, height, fontsize, trans): - markerline, stemlines, baseline = orig_handle xdata, xdata_marker = self.get_xdata(legend, xdescent, ydescent, @@ -603,31 +602,44 @@ def create_artists(self, legend, orig_handle, else: bottom = self._bottom - leg_markerline = Line2D(xdata_marker, ydata[:len(xdata_marker)]) - self.update_prop(leg_markerline, markerline, legend) - leg_stemlines = [] - for thisx, thisy in zip(xdata_marker, ydata): - l = Line2D([thisx, thisx], [bottom, thisy]) - leg_stemlines.append(l) - for lm, m in zip(leg_stemlines, stemlines): - self.update_prop(lm, m, legend) + # update_prop() usually takes two Line2D collections; + # override temporarily to copy properties from a LineCollection + orig_update_func = self._update_prop_func + self._update_prop_func = self._copy_collection_props + + for thisx, thisy in zip(xdata_marker, ydata): + thisline = Line2D([thisx, thisx], [bottom, thisy]) + leg_stemlines.append(thisline) + self.update_prop(thisline, stemlines, legend) + # Reset update_prop_func + self._update_prop_func = orig_update_func leg_baseline = Line2D([np.min(xdata), np.max(xdata)], [bottom, bottom]) self.update_prop(leg_baseline, baseline, legend) - artists = [leg_markerline] - artists.extend(leg_stemlines) + leg_markerline = Line2D(xdata_marker, ydata[:len(xdata_marker)]) + self.update_prop(leg_markerline, markerline, legend) + + artists = leg_stemlines artists.append(leg_baseline) + artists.append(leg_markerline) for artist in artists: artist.set_transform(trans) return artists + def _copy_collection_props(self, legend_handle, orig_handle): + ''' + Method to copy properties from a LineCollection (orig_handle) to a + Line2D (legend_handle). + ''' + legend_handle._color = orig_handle.get_color()[0] + class HandlerTuple(HandlerBase): """ diff --git a/lib/matplotlib/tests/baseline_images/test_axes/stem.png b/lib/matplotlib/tests/baseline_images/test_axes/stem.png new file mode 100644 index 0000000000000000000000000000000000000000..407c977f5b72fca5104cec2881bcc5e3a67553e5 GIT binary patch literal 14306 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 KNfd|~`u#6fx#Ls- literal 0 HcmV?d00001 diff --git a/lib/matplotlib/tests/test_axes.py b/lib/matplotlib/tests/test_axes.py index 12197bd8e55f..8a6515dbe045 100644 --- a/lib/matplotlib/tests/test_axes.py +++ b/lib/matplotlib/tests/test_axes.py @@ -2876,6 +2876,17 @@ def test_hist_stacked_weighted(): ax.hist((d1, d2), weights=(w1, w2), histtype="stepfilled", stacked=True) +@image_comparison(baseline_images=['stem'], extensions=['png'], style='mpl20', + remove_text=True) +def test_stem(): + x = np.linspace(0.1, 2 * np.pi, 100) + + fig, ax = plt.subplots() + ax.stem(x, np.cos(x), linefmt='C2-', markerfmt='k+', basefmt='C1-.', + label='Stem') + ax.legend() + + def test_stem_args(): fig = plt.figure() ax = fig.add_subplot(1, 1, 1) pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy