From 935a82b433ef93b65901e3f569a79fb5bca8f785 Mon Sep 17 00:00:00 2001 From: andrzejnovak Date: Fri, 9 Aug 2019 22:55:27 +0200 Subject: [PATCH 1/8] Add step option where='edges' --- lib/matplotlib/axes/_axes.py | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/lib/matplotlib/axes/_axes.py b/lib/matplotlib/axes/_axes.py index 44467581f446..ed1f2c27acb4 100644 --- a/lib/matplotlib/axes/_axes.py +++ b/lib/matplotlib/axes/_axes.py @@ -2079,7 +2079,7 @@ def step(self, x, y, *args, where='pre', data=None, **kwargs): An object with labelled data. If given, provide the label names to plot in *x* and *y*. - where : {'pre', 'post', 'mid'}, optional, default 'pre' + where : {'pre', 'post', 'mid', 'edges'}, optional, default 'pre' Define where the steps should be placed: - 'pre': The y value is continued constantly to the left from @@ -2089,6 +2089,8 @@ def step(self, x, y, *args, where='pre', data=None, **kwargs): every *x* position, i.e. the interval ``[x[i], x[i+1])`` has the value ``y[i]``. - 'mid': Steps occur half-way between the *x* positions. + - 'edges': Expects dim(x) = dim(y) + 1, steps have y[i] value on + the interval ``[x[i], x[i+1])`` Returns ------- @@ -2104,7 +2106,17 @@ def step(self, x, y, *args, where='pre', data=None, **kwargs): ----- .. [notes section required to get data note injection right] """ - cbook._check_in_list(('pre', 'post', 'mid'), where=where) + cbook._check_in_list(('pre', 'post', 'mid', 'edges'), where=where) + if where == 'edges': + if x.shape[0] != y.shape[0] + 1: + raise ValueError(f"When drawing with 'edges', x must have " + f"first dimension greater then y by exactly " + f"1, but x, y have shapes {x.shape} and" + f"{y.shape}") + else: + y = np.r_[y, y[-1]] + where = 'post' + kwargs['drawstyle'] = 'steps-' + where return self.plot(x, y, *args, data=data, **kwargs) From a6ff7562592d26c1038672700224ec4cdc295171 Mon Sep 17 00:00:00 2001 From: andrzejnovak Date: Mon, 12 Aug 2019 12:19:21 +0200 Subject: [PATCH 2/8] Add 'between' and 'edges' --- lib/matplotlib/axes/_axes.py | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/lib/matplotlib/axes/_axes.py b/lib/matplotlib/axes/_axes.py index ed1f2c27acb4..31f88d62c004 100644 --- a/lib/matplotlib/axes/_axes.py +++ b/lib/matplotlib/axes/_axes.py @@ -2089,8 +2089,10 @@ def step(self, x, y, *args, where='pre', data=None, **kwargs): every *x* position, i.e. the interval ``[x[i], x[i+1])`` has the value ``y[i]``. - 'mid': Steps occur half-way between the *x* positions. - - 'edges': Expects dim(x) = dim(y) + 1, steps have y[i] value on + - 'between': Expects len(x) = len(y) + 1, steps have y[i] value on the interval ``[x[i], x[i+1])`` + - 'edges': Expects len(x) = len(y) + 1, steps have y[i] value on + the interval ``[x[i], x[i+1]), shape is closed at x[0], x[-1]`` Returns ------- @@ -2106,16 +2108,23 @@ def step(self, x, y, *args, where='pre', data=None, **kwargs): ----- .. [notes section required to get data note injection right] """ - cbook._check_in_list(('pre', 'post', 'mid', 'edges'), where=where) - if where == 'edges': + cbook._check_in_list(('pre', 'post', 'mid', 'edges', 'between'), where=where) + if where == 'between' or where == 'edges': if x.shape[0] != y.shape[0] + 1: - raise ValueError(f"When drawing with 'edges', x must have " - f"first dimension greater then y by exactly " - f"1, but x, y have shapes {x.shape} and" + raise ValueError(f"When drawing with 'edges' or 'between', " + f"x must have first dimension greater " + f"then y by exactly 1, but x, y " + f"have shapes {x.shape} and " f"{y.shape}") - else: - y = np.r_[y, y[-1]] - where = 'post' + + if where == 'edges': + l_edgex, l_edgey = [x[0], x[0]], [0, y[0]] + r_edgex, r_edgey = [x[-1], x[-1]], [0, y[-1]] + self.add_line(mlines.Line2D(l_edgex, l_edgey)) + self.add_line(mlines.Line2D(r_edgex, r_edgey)) + + y = np.r_[y, y[-1]] + where = 'post' kwargs['drawstyle'] = 'steps-' + where return self.plot(x, y, *args, data=data, **kwargs) From e6383a54111f5c77b2197b450f174d3f208c5279 Mon Sep 17 00:00:00 2001 From: andrzejnovak Date: Tue, 13 Aug 2019 08:43:27 -0500 Subject: [PATCH 3/8] Add flip axis option --- lib/matplotlib/axes/_axes.py | 35 +++++++++++++++++++++++++++++------ 1 file changed, 29 insertions(+), 6 deletions(-) diff --git a/lib/matplotlib/axes/_axes.py b/lib/matplotlib/axes/_axes.py index 31f88d62c004..a288bd569e70 100644 --- a/lib/matplotlib/axes/_axes.py +++ b/lib/matplotlib/axes/_axes.py @@ -2043,7 +2043,7 @@ def xcorr(self, x, y, normed=True, detrend=mlab.detrend_none, #### Specialized plotting # @_preprocess_data() # let 'plot' do the unpacking.. - def step(self, x, y, *args, where='pre', data=None, **kwargs): + def step(self, x, y, *args, where='pre', data=None, bottom=None, flipxy=False, **kwargs): """ Make a step plot. @@ -2094,6 +2094,14 @@ def step(self, x, y, *args, where='pre', data=None, **kwargs): - 'edges': Expects len(x) = len(y) + 1, steps have y[i] value on the interval ``[x[i], x[i+1]), shape is closed at x[0], x[-1]`` + flipxy : bool, optional, default : False + If *True*, flip x and y axis. You may wish to rotate instead of + flipping by parsing y=y[::-1] + + bottom : scalar, optional, default : 0 + If plotting with 'edges', sets low bound. + + Returns ------- lines @@ -2117,13 +2125,28 @@ def step(self, x, y, *args, where='pre', data=None, **kwargs): f"have shapes {x.shape} and " f"{y.shape}") + if flipxy: + y = np.r_[y[0], y] + x, y = y, x + else: + y = np.r_[y, y[-1]] + if where == 'edges': - l_edgex, l_edgey = [x[0], x[0]], [0, y[0]] - r_edgex, r_edgey = [x[-1], x[-1]], [0, y[-1]] - self.add_line(mlines.Line2D(l_edgex, l_edgey)) - self.add_line(mlines.Line2D(r_edgex, r_edgey)) + if flipxy: + self.add_line( + mlines.Line2D([0 if bottom is None else bottom, x[0]], + [y[0], y[0]])) + self.add_line( + mlines.Line2D([0 if bottom is None else bottom, x[-1]], + [y[-1], y[-1]])) + else: + self.add_line( + mlines.Line2D([x[0], x[0]], + [0 if bottom is None else bottom, y[0]])) + self.add_line( + mlines.Line2D([x[-1], x[-1]], + [0 if bottom is None else bottom, y[-1]])) - y = np.r_[y, y[-1]] where = 'post' kwargs['drawstyle'] = 'steps-' + where From 829062b2d141b91d55da6d6118258ee3c2c9251e Mon Sep 17 00:00:00 2001 From: andrzejnovak Date: Tue, 13 Aug 2019 09:46:47 -0500 Subject: [PATCH 4/8] Make api in line with hist() --- lib/matplotlib/axes/_axes.py | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/lib/matplotlib/axes/_axes.py b/lib/matplotlib/axes/_axes.py index a288bd569e70..b418f0323750 100644 --- a/lib/matplotlib/axes/_axes.py +++ b/lib/matplotlib/axes/_axes.py @@ -2043,7 +2043,8 @@ def xcorr(self, x, y, normed=True, detrend=mlab.detrend_none, #### Specialized plotting # @_preprocess_data() # let 'plot' do the unpacking.. - def step(self, x, y, *args, where='pre', data=None, bottom=None, flipxy=False, **kwargs): + def step(self, x, y, *args, where='pre', data=None, + bottom=0, orientation='vertical', **kwargs): """ Make a step plot. @@ -2116,7 +2117,10 @@ def step(self, x, y, *args, where='pre', data=None, bottom=None, flipxy=False, * ----- .. [notes section required to get data note injection right] """ - cbook._check_in_list(('pre', 'post', 'mid', 'edges', 'between'), where=where) + cbook._check_in_list(('pre', 'post', 'mid', 'edges', 'between'), + where=where) + cbook._check_in_list(('horizontal', 'vertical'), + orientation=orientation) if where == 'between' or where == 'edges': if x.shape[0] != y.shape[0] + 1: raise ValueError(f"When drawing with 'edges' or 'between', " @@ -2125,28 +2129,23 @@ def step(self, x, y, *args, where='pre', data=None, bottom=None, flipxy=False, * f"have shapes {x.shape} and " f"{y.shape}") - if flipxy: + if orientation == 'horizontal': y = np.r_[y[0], y] x, y = y, x - else: + elif orientation == 'vertical': y = np.r_[y, y[-1]] if where == 'edges': - if flipxy: + if orientation == 'horizontal': self.add_line( - mlines.Line2D([0 if bottom is None else bottom, x[0]], - [y[0], y[0]])) + mlines.Line2D([bottom, x[0]], [y[0], y[0]])) self.add_line( - mlines.Line2D([0 if bottom is None else bottom, x[-1]], - [y[-1], y[-1]])) - else: + mlines.Line2D([bottom, x[-1]], [y[-1], y[-1]])) + elif orientation == 'vertical': self.add_line( - mlines.Line2D([x[0], x[0]], - [0 if bottom is None else bottom, y[0]])) + mlines.Line2D([x[0], x[0]], [bottom, y[0]])) self.add_line( - mlines.Line2D([x[-1], x[-1]], - [0 if bottom is None else bottom, y[-1]])) - + mlines.Line2D([x[-1], x[-1]], [bottom, y[-1]])) where = 'post' kwargs['drawstyle'] = 'steps-' + where From ead2cb9aa2eca383604bc45f8b5db019bdf23a0e Mon Sep 17 00:00:00 2001 From: andrzejnovak Date: Tue, 13 Aug 2019 12:27:40 -0500 Subject: [PATCH 5/8] Add tests --- .../test_axes/step_histlike.png | Bin 0 -> 8997 bytes lib/matplotlib/tests/test_axes.py | 22 ++++++++++++++++++ 2 files changed, 22 insertions(+) create mode 100644 lib/matplotlib/tests/baseline_images/test_axes/step_histlike.png diff --git a/lib/matplotlib/tests/baseline_images/test_axes/step_histlike.png b/lib/matplotlib/tests/baseline_images/test_axes/step_histlike.png new file mode 100644 index 0000000000000000000000000000000000000000..1d00412bb839343b1660b31ce490c7978af91522 GIT binary patch literal 8997 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 Cl)KOX literal 0 HcmV?d00001 diff --git a/lib/matplotlib/tests/test_axes.py b/lib/matplotlib/tests/test_axes.py index f7036342d720..3967d762dfd6 100644 --- a/lib/matplotlib/tests/test_axes.py +++ b/lib/matplotlib/tests/test_axes.py @@ -3696,6 +3696,28 @@ def test_step_linestyle(): ax.set_ylim([-1, 7]) +@image_comparison(['step_histlike'], remove_text=True, extensions=['png']) +def test_step_histlike(): + y = np.array([6, 14, 32, 37, 48, 32, 21, 4]) # hist + x = np.array([1., 2., 3., 4., 5., 6., 7., 8., 9.]) # bins + fig, ((ax1, ax2), (ax3, ax4), (ax5, ax6), (ax7, ax8)) = plt.subplots(4, 2) + ax1.step(x, y, where='between') + ax2.step(x, y, where='between', orientation='horizontal') + ax3.step(x, y, where='edges') + ax4.step(x, y, where='edges', orientation='horizontal') + + ax5.step(x, y, where='edges', bottom=-10) + ax6.step(x, y, where='edges', orientation='horizontal', bottom=-10) + ax7.step(x, y, where='edges', bottom=-10) + ax7.semilogy() + ax8.step(x, y, where='edges', orientation='horizontal', bottom=-10) + ax8.semilogx() + for ax in [ax1, ax3, ax5, ax7]: + ax.set_xlim(0, 10) + for ax in [ax2, ax4, ax6, ax8]: + ax.set_ylim(0, 10) + + @image_comparison(['mixed_collection'], remove_text=True) def test_mixed_collection(): from matplotlib import patches From 81b37fbb783d019e22936cc72980490e61927558 Mon Sep 17 00:00:00 2001 From: andrzejnovak Date: Tue, 13 Aug 2019 12:31:40 -0500 Subject: [PATCH 6/8] Fix description --- lib/matplotlib/axes/_axes.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/matplotlib/axes/_axes.py b/lib/matplotlib/axes/_axes.py index b418f0323750..f7c6f2f3fa6f 100644 --- a/lib/matplotlib/axes/_axes.py +++ b/lib/matplotlib/axes/_axes.py @@ -2095,9 +2095,9 @@ def step(self, x, y, *args, where='pre', data=None, - 'edges': Expects len(x) = len(y) + 1, steps have y[i] value on the interval ``[x[i], x[i+1]), shape is closed at x[0], x[-1]`` - flipxy : bool, optional, default : False - If *True*, flip x and y axis. You may wish to rotate instead of - flipping by parsing y=y[::-1] + orientation : {'vertical', 'horizontal'}, optional, default 'vertical' + If horizontal, switches x and y axes. You may wish to rotate + instead of flipping by parsing y=y[::-1] bottom : scalar, optional, default : 0 If plotting with 'edges', sets low bound. From 026337a32fec37f999abd898dda03584977e89ef Mon Sep 17 00:00:00 2001 From: andrzejnovak Date: Tue, 13 Aug 2019 15:24:04 -0500 Subject: [PATCH 7/8] Switch to testing with check_figures_equal() --- .../test_axes/step_histlike.png | Bin 8997 -> 0 bytes lib/matplotlib/tests/test_axes.py | 68 +++++++++++++----- 2 files changed, 50 insertions(+), 18 deletions(-) delete mode 100644 lib/matplotlib/tests/baseline_images/test_axes/step_histlike.png diff --git a/lib/matplotlib/tests/baseline_images/test_axes/step_histlike.png b/lib/matplotlib/tests/baseline_images/test_axes/step_histlike.png deleted file mode 100644 index 1d00412bb839343b1660b31ce490c7978af91522..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8997 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 Cl)KOX diff --git a/lib/matplotlib/tests/test_axes.py b/lib/matplotlib/tests/test_axes.py index 3967d762dfd6..efaa132d6540 100644 --- a/lib/matplotlib/tests/test_axes.py +++ b/lib/matplotlib/tests/test_axes.py @@ -3696,26 +3696,58 @@ def test_step_linestyle(): ax.set_ylim([-1, 7]) -@image_comparison(['step_histlike'], remove_text=True, extensions=['png']) -def test_step_histlike(): +@check_figures_equal() +def test_step_histlike(fig_test, fig_ref): + import matplotlib.lines as mlines y = np.array([6, 14, 32, 37, 48, 32, 21, 4]) # hist x = np.array([1., 2., 3., 4., 5., 6., 7., 8., 9.]) # bins - fig, ((ax1, ax2), (ax3, ax4), (ax5, ax6), (ax7, ax8)) = plt.subplots(4, 2) - ax1.step(x, y, where='between') - ax2.step(x, y, where='between', orientation='horizontal') - ax3.step(x, y, where='edges') - ax4.step(x, y, where='edges', orientation='horizontal') - - ax5.step(x, y, where='edges', bottom=-10) - ax6.step(x, y, where='edges', orientation='horizontal', bottom=-10) - ax7.step(x, y, where='edges', bottom=-10) - ax7.semilogy() - ax8.step(x, y, where='edges', orientation='horizontal', bottom=-10) - ax8.semilogx() - for ax in [ax1, ax3, ax5, ax7]: - ax.set_xlim(0, 10) - for ax in [ax2, ax4, ax6, ax8]: - ax.set_ylim(0, 10) + bottom = -10 + # Test + fig_test, test_axes = plt.subplots(4, 2) + test_axes = test_axes.flatten() + test_axes[0].step(x, y, where='between') + test_axes[1].step(x, y, where='between', orientation='horizontal') + test_axes[2].step(x, y, where='edges') + test_axes[3].step(x, y, where='edges', orientation='horizontal') + test_axes[4].step(x, y, where='edges', bottom=-10) + test_axes[5].step(x, y, where='edges', orientation='horizontal', + bottom=bottom) + test_axes[6].step(x, y, where='edges', bottom=-10) + test_axes[6].semilogy() + test_axes[7].step(x, y, where='edges', orientation='horizontal', + bottom=bottom) + test_axes[7].semilogy() + # Ref + fig_ref, ref_axes = plt.subplots(4, 2) + ref_axes = ref_axes.flatten() + ref_axes[0].plot(x, np.r_[y, y[-1]], drawstyle='steps-post') + ref_axes[1].plot(np.r_[y[0], y], x, drawstyle='steps-post') + + ref_axes[2].plot(x, np.r_[y, y[-1]], drawstyle='steps-post') + ref_axes[2].add_line(mlines.Line2D([x[0], x[0]], [0, y[0]])) + ref_axes[2].add_line(mlines.Line2D([x[-1], x[-1]], [0, y[-1]])) + + ref_axes[3].plot(np.r_[y[0], y], x, drawstyle='steps-post') + ref_axes[3].add_line(mlines.Line2D([0, y[0]], [x[0], x[0]])) + ref_axes[3].add_line(mlines.Line2D([0, y[-1]], [x[-1], x[-1]])) + + ref_axes[4].plot(x, np.r_[y, y[-1]], drawstyle='steps-post') + ref_axes[4].add_line(mlines.Line2D([x[0], x[0]], [bottom, y[0]])) + ref_axes[4].add_line(mlines.Line2D([x[-1], x[-1]], [bottom, y[-1]])) + + ref_axes[5].plot(np.r_[y[0], y], x, drawstyle='steps-post') + ref_axes[5].add_line(mlines.Line2D([bottom, y[0]], [x[0], x[0]])) + ref_axes[5].add_line(mlines.Line2D([bottom, y[-1]], [x[-1], x[-1]])) + + ref_axes[6].plot(x, np.r_[y, y[-1]], drawstyle='steps-post') + ref_axes[6].add_line(mlines.Line2D([x[0], x[0]], [bottom, y[0]])) + ref_axes[6].add_line(mlines.Line2D([x[-1], x[-1]], [bottom, y[-1]])) + ref_axes[6].semilogy() + + ref_axes[7].plot(np.r_[y[0], y], x, drawstyle='steps-post') + ref_axes[7].add_line(mlines.Line2D([bottom, y[0]], [x[0], x[0]])) + ref_axes[7].add_line(mlines.Line2D([bottom, y[-1]], [x[-1], x[-1]])) + ref_axes[7].semilogx() @image_comparison(['mixed_collection'], remove_text=True) From e6e37ed65ec8886f7bd8fd41d4de56edc31427a9 Mon Sep 17 00:00:00 2001 From: andrzejnovak Date: Thu, 15 Aug 2019 18:18:54 -0500 Subject: [PATCH 8/8] Add boilerplate/pyplot changes --- lib/matplotlib/pyplot.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/lib/matplotlib/pyplot.py b/lib/matplotlib/pyplot.py index 64b055479e7c..1699f38d7a60 100644 --- a/lib/matplotlib/pyplot.py +++ b/lib/matplotlib/pyplot.py @@ -2916,10 +2916,13 @@ def stem( # Autogenerated by boilerplate.py. Do not edit as changes will be lost. @docstring.copy(Axes.step) -def step(x, y, *args, where='pre', data=None, **kwargs): +def step( + x, y, *args, where='pre', data=None, bottom=0, + orientation='vertical', **kwargs): return gca().step( x, y, *args, where=where, **({"data": data} if data is not - None else {}), **kwargs) + None else {}), bottom=bottom, orientation=orientation, + **kwargs) # Autogenerated by boilerplate.py. Do not edit as changes will be lost.