From 2098d1aa72a1f47bef542f2a0381dcd9432ace43 Mon Sep 17 00:00:00 2001 From: David Stansby Date: Tue, 24 Oct 2017 20:29:01 +0100 Subject: [PATCH 01/13] Improve step performance Do deprecation better Fix linestyle --- doc/api/next_api_changes/2017-10-24-DS.rst | 14 ++++++ lib/matplotlib/axes/_axes.py | 43 ++++++++++++++---- lib/matplotlib/container.py | 11 ++++- lib/matplotlib/legend_handler.py | 40 ++++++++++++++-- .../tests/baseline_images/test_axes/stem.png | Bin 0 -> 17812 bytes lib/matplotlib/tests/test_axes.py | 22 +++++++++ 6 files changed, 114 insertions(+), 16 deletions(-) create mode 100644 doc/api/next_api_changes/2017-10-24-DS.rst create mode 100644 lib/matplotlib/tests/baseline_images/test_axes/stem.png diff --git a/doc/api/next_api_changes/2017-10-24-DS.rst b/doc/api/next_api_changes/2017-10-24-DS.rst new file mode 100644 index 000000000000..d44b4a22c36f --- /dev/null +++ b/doc/api/next_api_changes/2017-10-24-DS.rst @@ -0,0 +1,14 @@ +`StemContainer` now stores `LineCollection` +------------------------------------------- + +`StemContainer` objects can 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. + +This will become the default behaviour in Matplotlib 3.3. To use it now, the +``use_line_collection`` keyword argument to ~`.axes.stem` can be set to +``True``. + +Individual 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 686ef9ee76f5..64503c7fd5f9 100644 --- a/lib/matplotlib/axes/_axes.py +++ b/lib/matplotlib/axes/_axes.py @@ -2480,7 +2480,7 @@ def broken_barh(self, xranges, yrange, **kwargs): @_preprocess_data() def stem(self, *args, linefmt=None, markerfmt=None, basefmt=None, bottom=0, - label=None): + label=None, use_line_collection=False): """ Create a stem plot. @@ -2539,6 +2539,12 @@ def stem(self, *args, linefmt=None, markerfmt=None, basefmt=None, bottom=0, label : str, optional, default: None The label to use for the stems in legends. + use_line_collection : bool, optional, default: False + If ``True``, store and plot the stem lines as a + ~`.collections.LineCollection` instead of individual lines. This + significantly increases performance, and will become the default + option in Matplotlib 3.3. If ``False``, defaults to old behaviour. + Returns ------- @@ -2570,6 +2576,9 @@ def stem(self, *args, linefmt=None, markerfmt=None, basefmt=None, bottom=0, 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: @@ -2618,16 +2627,33 @@ def stem(self, *args, linefmt=None, markerfmt=None, basefmt=None, bottom=0, else: basestyle, basemarker, basecolor = _process_plot_format(basefmt) + # New behaviour in 3.1 is to use a LineCollection for the stemlines + if use_line_collection: + stemlines = [] + for thisx, thisy in zip(x, y): + stemlines.append(((thisx, bottom), (thisx, thisy))) + stemlines = mcoll.LineCollection(stemlines, linestyles=linestyle, + colors=linecolor, + label='_nolegend_') + self.add_collection(stemlines) + # Old behaviour is to plot each of the lines individually + else: + warnings.warn( + 'In Matplotlib 3.3 individual lines on a stem plot will be ' + 'added as a LineCollection instead of individual lines.\n' + 'This significantly improves the performance of a stem plot.\n' + 'To remove this warning and switch to the new behaviour, ' + 'set the "use_line_collection" keyword argument to True.') + stemlines = [] + 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) + markerline, = self.plot(x, y, color=markercolor, linestyle=markerstyle, marker=markermarker, label="_nolegend_") - stemlines = [] - 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) - baseline, = self.plot([np.min(x), np.max(x)], [bottom, bottom], color=basecolor, linestyle=basestyle, marker=basemarker, label="_nolegend_") @@ -2635,7 +2661,6 @@ def stem(self, *args, linefmt=None, markerfmt=None, basefmt=None, bottom=0, stem_container = StemContainer((markerline, stemlines, baseline), label=label) self.add_container(stem_container) - return stem_container @_preprocess_data(replace_names=["x", "explode", "labels", "colors"]) 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 5d4e55a351da..cb5ed2a0edd3 100644 --- a/lib/matplotlib/legend_handler.py +++ b/lib/matplotlib/legend_handler.py @@ -589,8 +589,11 @@ 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 + # Check to see if the stemcontainer is storing lines as a list or a + # LineCollection. Eventually using a list will be removed, and this + # logic can also be removed. + using_linecoll = isinstance(stemlines, mcoll.LineCollection) xdata, xdata_marker = self.get_xdata(legend, xdescent, ydescent, width, height, fontsize) @@ -609,23 +612,50 @@ def create_artists(self, legend, orig_handle, leg_stemlines = [Line2D([x, x], [bottom, y]) for x, y in zip(xdata_marker, ydata)] - for lm, m in zip(leg_stemlines, stemlines): - self.update_prop(lm, m, legend) + if using_linecoll: + # 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) + + self._update_prop_func = orig_update_func + else: + for thisx, thisy in zip(xdata_marker, ydata): + thisline = Line2D([thisx, thisx], [bottom, thisy]) + leg_stemlines.append(thisline) + for lm, m in zip(leg_stemlines, stemlines): + self.update_prop(lm, m, legend) 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.set_color(orig_handle.get_color()[0]) + legend_handle.set_linestyle(orig_handle.get_linestyle()[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..4c6b3af3205bf7f61001e3fecb5c406f57b8ce2a GIT binary patch literal 17812 zcmeHvWmr_*`|cha6X)G$7{Hp*n7>|Yd>*6_j9ia(b7<&AcK=Z5JZ7gzODm71SklC zeJ3Rb?}&DfPJ#c3+~twFq~M=Fsr57P`lPF}kvjxY-p2pIa^$k@z?-@rHw-;)y4ZSn z-FCBqoNjx#I=Xl`+F7#Pw{df~b8%)7<`?7_bhEm`@9N_2A#zoM-`eKBAkQ5etE;x6 zw&FI{yexM;JX|FO1paj{zl+-)fuU{^7zD9E$m`d1y0XlGGa8CZW=3 zF&vuq(=Bm|bf2h*P$vvatV1$(PWFBKcGne{ZiBy?np#d>os18&_+^3y0@kDeMn=Yy z;8x}c*)G@HbUbkZxA@#;hzNoN83+*IMa;$jix)IaE8F=PjCmktVlJ(Zm7syFF@zEl zj7i*^*x%Ty{zYc+ydj(=YMo!9pU*aZnU>w($xSG^Gi zPPHoN_k%RiY_y?`Vf@$2lM)iNZr+Uf($v)d?VF)%Uz zE2jDJ=7C1rqwbNlw~DH(t63X^B+P=an`^uN%>fWZ&!sI<>@*?BinBIcDI&Ba*Uu_d3~~E|SeJk6i9rxFQBkeblvE4S(%>iKY?1dw4ZjLn2w@#7CHf zz7#8Rd$~rOPkn)IE}a>Bclc2IGASfzY=2l!!tC!lP!=*=2PS7ye=jr;`?07T3@j-n zrH4tYS7Q_7Abz0x{%QSI6frSLndK}QvZvl}dp=r;srz!IbXqHajapCe>5_><+&06t z6HpFm(1ubFYf5MQeM%|U-zfY^Yw0{}$VI8a{QP{?|;B?}5Pgw1VFxwm38`GFwx8cL~1DpG;e3e=>lu*LW3LBL>j6Z6ocFyt{ z)jal73%(4!y%+-jpy{~#823vP$Lo~gnr8kTxS8;P5fQ|~2pp6$U{1kzCh<QjH|k<0de>KcZ!Nhvbo#n*Z@hl- zP4Qkatt%|=Hs1%}>s6+OM!g%Go4FVaM*0K+q#OQOhP8O+pl!)sk79d82VC?QVB$;T zby7}Gw#LVA`P7Y1#Shw-=V34@RRl1|X#ao>$0Qdx`p)gmds2v}%frK1!Q~6a(X6#Y za~54!dT=;g7&lJ$)F~L`-YnLTu1_4$rrW-~V)=%+D`V8T5(Gz9E-Q<#U%x)9 zUr%27y0U$foD>putbj4=_(xfon=@}egkOj5>I@}$*Hl-dKOL-K4g>YcVJNuxAd1rX zkv*LQ%petn45vt!-ioG5F8Y(Uj&xG(%jq?2$e3uP)h$6N^)0ynd;9z4AcF1s%VI~q zW9&XHF|sxeZm9p-Z_Z1JUAiS=0H>xCMbU85hR%Q92{|&XMm6`A`zm}ZPTgR7Po6xX zrzU_zoo7&yh^wjYny+K1&3na*SK^z3xWeOSk4J#9Si4l@JKsyL7<>bCdy-xz^IfLs2>sX>(U}944zw7p?<=NUr=y8TOpT(U! z*{sdQ!x!h}g;5@FFr=-GFob84Lxa-dfPT4?%Ou?8>?wi|wXA!gtbsBFP+sWB(u>a7 z-iGfe{a>aR=Rcw%AAEq7JK9}&|Cp150Ac-3bmT5Ego2|DXWHjI@=8mE(=)S6OK)!3 z)_lmkF40XCb_zTluBb$|{Nnid)dI?q%}oz{$?q&weKiLnLVcZ&+K$>9D;02JzWfN5 zy4T%9NPw6s%lC@E?>O*KNu>4Z^=7 zF(D!@u`|bf?AEf*8y!JXBJwZzvrNHRr%#>ENyj|W#;_|S6Qxf-hG;!;$5%Vq7-r{EJ1cVzGURFgyx z6>z`1ym={+SW~oz-FhZEw!*30FkH3tKnDbc8&=xMudZ?-hr6mSGC%}Si@;#4fX=~d zp?<+ko7VXD{aY4u0qjb^{L~vxaO%;xv7Fc1{^5-5`QH8rj5KE9A}FG6IZ++3=#h5# z7-TVz_PD{W&k#hMnD3`?Yz?jZlIFb=LP1)xAFY&32-_~7!f9YL(a#W;ib_J+~KVFqTo~P=wmWzvvTT0U;uuRB;UnBcwKtKS| zqXZgJluu4kkpXzs94X9@*yl76u8G=>J6z-e%TV{N;#-$U?moc^>73FdIW#MF`Uj>j z61Sz~`~5rN!Z`g(ZR-hA=(&KwqAKUv9^9Sn*45KbUsQbA@1pTd?ws|>RD1OE67&|) zZK&Is5-7WCsPmZ z6#ksLp~8wKr;U9=DD`7E3Du3+?S0WeThp^QKS78qHYWGDOcu!n>FgnGkEgXy6X3*< z3X4f4+}QjbRUec#cYkxaCt^v88r<2*4~(J*zg^vsmqKzuttbeGu{`ep-fyM%l;8)# zc-A`W2@G}6Uhz{$@T{&kZ(AzmR5(Os6IXCZ2C-D`w(Sm9)D?_2%EzTsvZ&bGg5!h1 z@l#3b0>zOMheuzRG56{e6pU8qd$k?&l^MpO!Y@rbP;AvS^-dyz76cwL z1Z4QYQU9fL^+DEAbXCl5p7ohHT-Yw3?@+fZx>A0qVs4%S!t}atB-C(9XI~xTIb>4) zsa&BmU`nFEv{*-H+H|%x8t=-DmRHirwF>|^@9XQ!SY5p*DkcUud-Yt@oyg?aL)~-* zMNv@HSXWn+DSy1bEVD2d^_guKux7+V1hs{Q{QR~6)&g`!0LDtDNRDIWD=_Cq+Km9v z+$9n`CBp>QtXG5(S*GhaaD=*=dXAIN%fg)k9_}qk^E?qweh`en5|{5Xi>acCU6^7s z%9e=z9=)+6Yu>N8<8l)?rf8)Y-8vs3D(Om!&*828roq3b&cLo4*}SCva#WS1RKZ|~ zs#z@Kk?oMINNnw9n=fe@YkAE8)Hbq>B`7~p33jt+`luDh_QXxX+ zkftjs9hugC0v#2CPc?a`YW`=|TZc@-O!;$y-14n2Xemye78GECdX+c4Y#SKE5ELxj z4}tG>bZ8(g!B~(=7~m05Ld~M9?!Z5Om!~?mkG{}mdS#b$)#EX-R{o6eYN@k;SFVL3 z5sD_K!#I1w9J}A#gchm@*SOhIJ5h-X=<&6i9?@r?i0SL-@rWYUDmVr`BBC;xodJ{X zd&>b6{e-VcKs3k|VBRkoUmK`Q_$i5r0tTkaOB>2y_RL=N%9S@+S?uAFk@>~N-E%+t z%8n2zKY%iOCkS#*nhu72!oJjQ00xq!0Ip2Gu%qXs+G&c^B#?dZ)^Xv{#k&L@3Y^qB zoYX4Lnn$H}-JIUn2d;>*rvN5B5~ozr8NUCh?n9Tzv}9ms(AM1vnSHl8n2%dRB!MZ!USQGl9JGeN433<`bd9`s%%PR^Bb71410iL<{M%`%IQ2UI?cVoM~o^-lKB2;(I02`JOqx| zgJv@8>u-T+v&lsOFxvX_MOlDwC0NhpN%4MhHfBPE=+{c-((b__6)9Ys6Ez)-C66FE z6Q=vJiaj8USvc(aIaip9Ua&M+VFBsw6Ud%yu|O3t1-gDdArW=9^C=-xU5=vVX zWD!tIqwv!e0V^w-N=&8q2^5xpks;D}qU!ZE76_UO!J8>TyVyM5Oucz|{YuB)t-*xP zKxy3FZ{P^FM2DVPkc7bC`pcFu36N6sLQeNX+#yGpv2|F<2NdmmCWZs2;(*unozf?P zS;T%8(S6{`k{${0$Wc(w;RVUXR&eb!gxbZEFR9Pw(!=Z#=Uh*e7{B%P8mWoFV=~6% zFLRR|6`CoM1*Mnou-Qb^#u#28Ld<90mopl!)-^B>Ecd9|sGxC)(H$D>vVY&fQK4=6 z!jP9%xSFc}d1FTSAOK`n*7#}iA3>bu{}}oVTfx~;OfKwtoO{jK!u)(RHHLJ1YpZ2( zlU?9r9}WgZfi=+MGdbsCU_giY2#f7=JSV5>A$M&W)Rzcg=!1v7o9K+}`_gP6##3w& zEA-L_9GKeS4n~6bxnvh*q1YbNb8Zj&@q6z_Aw`=YHYg)Rn!R zp&lYQL0B!J7H!Bf2f$I{OtspdC@B{~>IXODR;8>@zGM4*r9pa8WVu_i(yAb729&vQ z9UgvTbG zOp@@xlii{()vT^&YJFEk@M@bra9{fK^=Ie&w{qJVDC&A5e*Z0>$n=Ts4g7=qEE!6G#rE) zYU@HhIpfNTJSRVss?ZbEk7ZFgcE{z*l?A$nhgD0>~XH(LrOrpBOqudJg_l`Mg*2V6WsJs^8T-c^I{}C zzz#{V&$W3-A?i5laKcO2S^xEG#PAcz&NKv)j zF7)Nk0h?r9Y}nV`7wyl>Wi>J)BqYXFMfTMO6Oi~s^esg)qagzk;?{E?K9RjW z!*HAH_lzuy4cq4Ab$MuG3T6MPNr+HTNmA9C(w_<>=^Ez8LK6T64YiNuF9yrMncDjN z`SF9y5Aw&Bac`A4s@Ie!s0&O3kXq6k+uL_csaX^E=!l>`xIN^+EQ&fs(A@f3#!p06 z_Vt0++Eg?8JO}+r`;p0!vZYlgGR21s$5!9Sn@)}Sw!OXG+suf{@J0>x_h<49n7vW@ z!W_+7=RPLo*;vi9VSw4;858qn9MmH0Nqvt`H~|553yX`Yfv*gCv(8O&9Mx<`@qsQs ztS4AIP)0`PAde)9I<#@)OVPwLIsLaegYv+2`VAHT7DH>tJP8N)vN5fToAOv;=>S6# zh%j`eVP^p!VJ&_kdBE$|UIY{NkV$Xi@WP5zn`qzrqg(~ExOVkH9$kPxU@hJU^%9+m zv5aMg8rlHMp>-8LAbvRc5}iR=J4uKy*D8l8)U7sFL$$vE6YlHnO;;94`!Ak|Eo4}( z;jvD9fV*U}sRGa2Fi!p?6uDL&_Y_D5%b&*386RGfuyHxnd>FU53r~+U|0Ps7QmMhQ zr}>u>WlEt&84H!lxw4t2VJrU^iYD-Hrvyrs#wOq z9;B!@}4_22t<+71r65&Iv*dWdL9J%clIpkOFoVy?ALgh-?!i z&Qc+kRN8hK{^fKj=ZP%kG}Z;|&xxWMPK9LtFl3~MwDR%26e_}x7W^VGLNvf}7o_g1 zoql=QiZ%6fk1L8nkmZ!EJVdGtmyyg<_i|PlY3gxBIH@kJjCkCO>28FzJZHB+=p1{5 z^@Wpj>$_9;Ybf|HqAb%f0&QV%1Y$KS1&_5_=ueVDhyp-eYN;;9cT_uh;FqsONQ_@- zwmJ&MFlD@Znf_#ptm9zX%niGFo~1oqioq_OtZS==|K=&`ZG@zKg?Pd#PEMzLV(|R? zpmX@xNebn)w!s^YNjYmTO2vbhgxfAjs0Ti8^r>Crlr(Uyd2x?bBHD zx6cMo|JeUDfBNUU*HQ=66xsU^(*uz@oM-cf7h@7zp8W*$HUTK`WrFs0{}eSKOHA`# zMh%|>F`v2j@C~>@#uffXLq+b2=FIuUz-mC@P?qByy*%P?j_28&(($RtEq2ww1*amA z5@>`52{Y$P=mPD$OC_$LOwYK^tvq9)S~d}XGVudyltxB*c=toZQYy26&b>o+h?kT@ z%gL&YMN0~hR8wwMAOzF@hAmH|oqT`kM%tNx6}pKS*19|Weym(hBevy74isM+24ZjY z-Rp92Tr{iQ*b~oDX%t+Ge2}9w?o8ti3JaLZCi$iR%mvQx#Od+Q$Ef|~KfzDpz5*#~q9I7GsQB4AuG|9YWH!(BmrDxZc02`vy!uV$|~nX;g#sw<8dwm?D?@{Qa0Sz_P_k|xGg_#7z?7lBjL(Py z5XnIq&1wfIO;1lxEo4gqK#0e1bv`R*JMn)kmApSv_! z>Re5zU-3`k3Z0fG?tTV7Nvm2*W=lzIDrvNQ&bk(%p?VX>7ojL>SEm(HdlepM!(^k@ zDh03CdS|FhrrB~PoI3%%;@_H3(Ww)UcH!Nv75Ra*Pk483ETulrX72;CIDwc>V zhir44MW;o#O}2lrjQbTqK5`Qia#${r@!9W8qDl~ECce0g)8=GmE-J(DK-91kqttub z&X>E>pN-GAHMr@A#ld=he*8j*xqjB=9*>*`e~!#=WxAEhc~WwBOgtoU5>q@QcdW}* zD{joLhpR+e;C5~I!`_ND>oZT#g(83O&Q84AwcQQl^+aPo?#4@Nu0<~iw|L^F<6J5_ zIh%IlBTZAZU#ze6<=&L^T!>|z&ladnC9c`%oeg^1HDxs4k8*7Hq^lpyo%L_omR=e@ zm)LeVY?a*oPHgk#`gCY!O3>~tzmFdnQo46Va#vd8!;*Ymx*BI8r^;h!7Wc%s#Q)lz_1#MT z{t0pZkfP?DCz^Z16nmOAW+MiYF^giSgKo!-Gj#|cP983sE%;6{vmrZixI^^h2M1C6 za{Kj#xaLjfY)Z4DYV(7uMgHZhoisa-F#3Q2FtN=!zCQ`EA5j#ga*?o;I`kLOi>Nm$=s=*cokj$E&AvvFXuSt z19Q5b4S`e_6JQyGz%m?DvUSw9 zDAZBl(EZk~;=pKXN0;X0?znW$lg=iRC)n}4%6UgKGye%M+4yZyOW*!}GHi2t^X9!E z-@U;SB1M{mIZBV|-XLxy+<3RClV7&^Ns93y zs}~b7YV{E{ubYK)qy<)Gi9f<_q^%wuI#tY0r<0%aE2W!IKsIVilJ*jPqFS>!j*#M0RRj=Ldm$ib-n_Hcn_i$`$8n1$Om9b$DXB`5SI6AYE z2RoAk`B(gx^i2j9uPs!xCmohI*%q`Wtx&q`-M%*XT2j?)EoloZRr6UFm*`IwSF1Xm z+kMR05dWbF(4%#MJiS}Pa(##mPDl%BB@z!kj`FE$~5M>e?jPQnGi zK64sSSe$K_x)(CjSi9EVO%z|?bA?$V={o_sy8dSmDA%z&hXINmHU-sNj4#=ca_?6e zM891id;CaZ`vx2K_ovmDhQMtl(z?CjN}&Y3F$=Pzd?vhELHm=;$~~`qIC?&_%B=sG zMPojS%av%;f&q3p(B=Gm6ICr&g;!GhlMZZ{NDov7ai3P~S}eOGoqhDt8&W}DnY4|T z?lZ#chGP?>m$+{ErG3pP#O_b%eY5PwjIB8y7`}0@-ukV#&TVB3M~<0C%DMdh!mQG5 zXSN&O@P1*R z*Oa*_(U#g~`(CR;IF{*JT%D3wOVXM&()UL&okx3?`d;M&nA5j+*BDy-!&6^=C8!C> zn9;u82lbE$3V<>;uc#UJ@;@6W*@e*f<0iACl7eoUcc2XVILww>aeX_Zv8suBKl zca~cXE={;1qKls?zNYWatx=jbt=f~Hh`T}29D4Y6Ux%n*z#E>gCmD1YV#sfrGutL5 zs{Y(Mr9Cz&+`4|9%c`(;DIzSOmp1fa>2&g>XGSq!hxChbevA-%PsYIKWX!6PPNWx3 zCPkCsP8KrH!~0RS%xb1PZ^p+8b3?W?yw99egV2oe}YQ3%*8jXR3W>3}CMFsf0E zm^^X%77R+gjz>*;KuqIs(B`dpX!4W~_lajDQW&BG*Fb$T{q%!1i76S@_|{DIv6mtT zzu#qeADYCsvVlirla=eq2Q7*eELyC&>8Ht!j0hS=|8y!?k)X(3SXzo3T+}l#h-Y0@ zIF&#MV}Vi^t|oVcoxzxynKeUH4ZrRZ5Ua3)>zZ%U0E+{7GzjVeC@;1lt@_5EcT>}* z`N~1jUjLn-%m}>;#sH;kCz~JmYmcQ(O(gDf^8ps4C{AdgWl?Z%N4S!0Z-RjQ_TNr| zp&GoD0S-sEPNO?#(~Za=Zc==+;6a)SF9k;RDnF!$F)Z@ku9iOwiHM)t;BRt2@E(<23t6W%z+z4%XuY1ov} zqOHnu@`jIHM5a())RkUPp!DT(0lNGTd>#bNKl^v$oc{^H#U%gz8qj6V6Ozeua&JJR z*UWudlz{f(zBssd+SA7HLeQWG-ET7)-*VPw`(pOP`kJLNyM0^dqxySLg~4Ik6I2~u z^_$6(Z_bqng`Ci$vWLhU1W4PSTw_7pYtt{~@2;fXoy4hwJ0_&24x?@|4RF}s+e7F7 zh7y>MkA*m8Ktsh5Ps|auu!EdYU381%aQk2nhn+Au?)jP>Y7VNRUk|Uw0#O2oiwTwDQS5`L$J@eCloVr$%QuQufeZ}>iA`4!sdy+lYKor| zCy#ypKMKe0dfd~x0lIU-`XtEy!NDeV%B;!l{pnS2P}JwHDj@$9qExip+Jv0bOw(T} zsBDErL_jcLOX+MvQN~i^i*A_0l<@^??2}Enue-9#90gw}|IOrbjoxlMiaH5u%~IaL zn`&eHHu(CV$L4L^p!UM#;jgw%RwOtA#>sbVcGL>?1x-oi4t)XdO^);~@Lv>Uj|uJe zS>yiYHGcZlO#}q9ceG@KWW2{jP_K#WJ|YYaZWmy>|tV~ zB@&lhRrCrlvw;P%#rn6Diq`{oo8$3KBo)si+sTsS)q?+z-El~ZbnnwgQhd3a5Rcv8 z?v!*p2SufrVsA4L5yaA-yEcoL^}(5$HE~itYZ=`)39nt%@k9yl1D9A7KJ$BS~CVz z6ZnU39h$XhkSC=x`ycrUVio8?;69euvo(^1syR{fAZF{LhO$1AJ|-+-&fcYiw4{kp z5UON#9}AZgeqD~q|NOZVQ3Y~}E`8QV1fSG@<&+?Uf6FN_chDEf5mXC)U|ex5M!Cqf z-QxnOL_$%)k?AEXr7+)C7Dody*O%ox1ggXu!5yv1bVYhwS^y-WSVY7b?OrnA{eDwNazO*vK#B&YCXE+W+u zL=#di3R~PWB$j9OGO-}wEwpUXigN;Gx7?9EneFi{_QkfpVsv9gGTTPf@JnUE;-IG8B6~)6o`p3 z9-9iFaphr!xbfpC0nq3usRD#w$M&0c7c;BLs9jYSXgBO`>-=v^Ftu4LmJ0+$6kAWG z0;{h;aSz}P1i#4%6yGSwa-ZCGVSfk|B(NA+!nj~yvMPdUXZypDDGyrYK`>_n zGX$-AQ+@+CRvWxTWFlyHDyX|7`@X%9P;T?rjQg_X!c}}+Ruld`V7aH&0AJg_A-U!= zuKv`e=Lw}tS3ZY1-^U@!)NgYdLH!D_doH z@!c==yBS7v>n(VXdO7dew(V1I;4iuA#UXM)_o+Gqdlr_%3zA1%f|KRkQOls_8XF;` z%SeEL5ZXJ~!0;3X1AJ$AGnIAz*pZaeQnmhc_Yyqg^?fW5 z z4sk~NwUA<~=#{chGg|*NYQO8G4ZH&@5HLrW@YGQh1sH;?Wd&4=e3O4HAy!p;X^v1C zGNjUA(S=LSq@VwX;hkH5n)ey|61Y*;R1$sCOA&~L2F7A>_RW0M*1;kZvIjRYCIF_i z>AA^ZSF-f7^N*EJdmc279LlG=MA+N=s-*0HnPo*j0(?oNavwio|C4gm1Gs3Z6%O=W zG%>ic*MV3&b){_K3Lvum>nGEm-ZHlUW-$wx?#JsF;#kL)>&=eTU8+ox*>`98Q9YpF zmZJ>>)K(2j|747tCXZ@=EsSMe81YhW8N*N`Hd!DdHP*j?YMaaX+t<(|v0y}5z=pty zJRpdJAc$Q71cymC_0xRF4}%X&MBNz>&bed6XGKwJ2d8x93J(zB>p-v-qcE{rEQO9V zsjN_`jIYtnp#=x&5F*&AN%9y$&<_WV7xzsJ-m=I(k)CUo;$0X3Xg5{4t*gKotbrQP~oC1>YUGR>9 zxkov_@8XTT(g7rT;jQN$wjY!7Pwx<;Z~pW%7`>q6vt@BYcW{nAp0c#J@7dXT4`*Zy z=LdQgyo;<8WP#3`RfKp902#;LL*$=hH;Oq4k$*h-*giG~7VGBqdv?Y}iB|Pxu!uzpQ^qX%W zHGk<0JFfJ#&>KIC>89UFu!1hOAUV)DwQ(KSyBzUR3Y(JuiGy}(gZ?^Q6X1YlJxgL@1~SG>G*Bb8a8^-g~x+X+eZ=iV$go|NDo8Ut7Rd6g7&NYDGuTxS8K_izg$G8xBh$g%YL04phTfBQ&RvrE820b@Z)WNy*C z3{zXU;JMNj%@HxzUNeCg92@cJ*MXuJ>~>(2#Q>$g4&I<>_9cf|4dPWpokHUpz<07X z<2RBi(xn*}Cy2D!-@U60mK4aDEYjq6v4Nl}16KpmhO98l2|ORLewHklnk*PS0^E-H z1u*xssaN0|3F&Sd9T_Yd3d3;WCF<-_g1<;r9h)Wo1oawzlr4hZ4nx zH%%f7=|)CIc#wedu%Q^@j=uYa10rJSCVCbBC;k`8Kk;dM3sbwGMfFFXYh10Yx#X>a z_Q1-S2_Sv#n{NI^Z#?=*Ix}WYMUy`!d<;Rbq5+!3^?a$#=i4+F{_F-iTV94BP;U@{ z&Hj;ADbf)NUN7{40YyEKUWjZ>UJ1uxa}F?*@xAkXLtR5*(zeUTxeV8TCcTaHP1z6dJ!qIL85{z#7NC9+e{Jg|t-i1& z-y18m;+Dn5x`M%em{=IE+g=C=+NrmOzLp6+aCAqJN{9CW%Sq~xj@kd>{B4mgr_<<@8&b=2h+&?`MpM7F5B%}&var80!6;4*L4PrwT02Q*x zU>lbTM$?uBr6q2Z{27RVGs&^{W5$-M!(Sdmzul^Z4%!90g_a0_eZYLtLh+Ztxz(Gw zCZ2o6y`b7V_jaoJnD!eO)gNgP>y%UMgG7K!7Vf+Tz7mIf~ZjX+cp!jn~1YI|A)3 z*vpl+ScH*v3c~lnSEt3z3PqVs(~Bm4dm?+D;&v6#8Q}Tm6xz)lkKVZXz$Sn{yIPuq zYa1a!{2geqm(348mWZB_)T!uJ`nvB4zZg zt6L9gM`#_at*_U3t%!LRaH4)%Q7Oabu9H#Q&agzy&y}4H+J1-Is0+%wlj0{Pt2Nc` zz3w_#!ryPSC~_hBwR=iNo{IYvkJ83q(B`1T1P5^d)Yyo93B6-^g+Sac2`3Qi{c3@k z5QuC_cN(eSf`_ZL)U^O)gjjV2+421pz$}-dpJiodhx4mwe_OiW-`~$*25Ona{9t9F z{syXJby!|@_ES9|$fJQ-oWwWH01r+@N^cgM21*3uDz{Aj>bXnlp%3ALBlZ__2^9t$ zP19ZEwwwxlN4SI2ZwIW))pH^7J3v@!`d=4o>gZ+oEc9oyBBSqSq;8*q)^30RV4E)= zp_uMF9cQ3xV2};&B%g5^r^HB5`SV6gI0J(=3ssj*yqTgp%X6U723)hMiVH!VK|(Wp6626vf4s1`0OIi<8U8yUhfB>D zyT!&;-_kT0DaT(qVir^W8o`!|-?f2GOiI!bf$RDC)xhEKFn*2hvWkj@^1)j-ubyXz zu6J8I{9IaC=mF727n3%gszYO7&6^g@p*ZEVx$vV%_SIHUuES;F?}P{mD(FQ*zrAQR z=?%T5@`N0wrby;LMQR4Q!w>c?^;7C!F^xrlBPWg*ku#}u>2Gq`f1fc*C<~?b0ngH< z&hE`^e<{BBi5cfQjO#NlnQ3o_``M~xFU#r`!z=*oi{?<;*l5&T{5cRB^Wc|&CQfIm zb%YJMw6ux=-lFA9gwkWVqDK_)(1IAC4D-Xi!P2dhYHG9rt>Vtz--NA*<2~-pIb)zsMS<rRQR!AhUdZsOzyJ=;@niexe< zR)(X>tHAEMfnU_(5I3MdQF*`T(jyl>kT9!_#OE8mABE{1mmR*V$pY+3JM2mR9FJB- z11_8fHTKLn1*2GO`CEtuXy)H0_F87(;_SUFO)auMTX&CCIK==}tO&;T$8|0JhzFO} zFZ>{f;vRx+oIcX8jX1v8H#bQ2|4?Qy|%x`?cORvtz~_ocpzV%Dl!OLTg? z@@G5S?@ttn8!SN9bR1SCI6|k{3EIYZrEjKX@pr4eDtO^)>l)9eektV+ZjQmMerC-l z@^`?B--OAiI0Vr?17FIPKFS^W0afcv>76gjC4#)P7V1KXX@O^u&``u4= z-~%DHKf7G-jyHjwonasd_Yiyg?=5ROEJ+P6OvjrK$ZU^(A~lEf9zlYXZ?u%(bOkeh z`TY61QG|m-MXskq{tJN@UKD=dw+ZU;zYAb~>%}Cj{}+BUE{%a{^xHH3hx-#nmz5%v z(fEzLY&K%&4u6x#^*I#PW`V7W-3DpsjLVwmyD^x9l_cMLD(H>xgp>>B^_v2Aoi$z) zb#^0RzfWlK{i&S89x#v#ZNA*irXcD6W|-YL^1>_!nGm7ed$Ad>Y8hHL+j#M@g-kc( zdg*VlGc{g+@qW_Tc?In)hXn{fs_FYKa7LHi{s3&7eqHQ#64Dg{wf(Q5 zQY8=$HSoIljBxo^l>t06$z|7iO3};4_g90H1(>68tDPDBFEf%Ss^1;D45&OX&%Dzm z_c~}7#T^T54eS9hJ2sLRDvunUT@@007de zMZlJGzvU{90v~ZtjgHU72`^3}L@z=jAICoJ%4PGj{RX>KyqRbne3PWix!;;1D4JZa40^@Rfy?&BXAd_SOIl+jR7C>@7lM1yT zuHWWQn0l$ZVvR8x*iNP0cBoaap&7-{YV2=O!O95{vEnsJ3E`gg(Z+aH& zh%yh^uSld5X92%g0DixK6@;**quEX^j#jyY%37$J{>i(~ZRc^cobYgaZ*N1@7rf1W zw`xN|PL@|zE`r@{S!U0C`D>NjCuNctSGq^NBWJ$&iB#JAMuKeDkt~%Bs@sJ7_QIfb zVNq^e?l#@>aP6+6xvpAq=*>b3y5nh=22z%{Fx zfgNXS{?dzoqh$p}QfS!Qk-!`c_>TdLnRwg%D7uf%8CL4Ghu@s;dA0;{Uh? a2Zy=7Xo8sDq99-@5b}n`^+I`zhyM!(O@{se literal 0 HcmV?d00001 diff --git a/lib/matplotlib/tests/test_axes.py b/lib/matplotlib/tests/test_axes.py index ed7e0ac8168e..c7230dd6b592 100644 --- a/lib/matplotlib/tests/test_axes.py +++ b/lib/matplotlib/tests/test_axes.py @@ -3072,6 +3072,28 @@ def test_hist_stacked_weighted(): ax.hist((d1, d2), weights=(w1, w2), histtype="stepfilled", stacked=True) +@pytest.mark.parametrize("use_line_collection", [True, False], + ids=['w/ line collection', 'w/o line collection']) +@image_comparison(baseline_images=['stem'], extensions=['png'], style='mpl20', + remove_text=True) +def test_stem(use_line_collection): + x = np.linspace(0.1, 2 * np.pi, 100) + args = (x, np.cos(x)) + # Label is a single space to force a legend to be drawn, but to avoid any + # text being drawn + kwargs = dict(linefmt='C2-.', markerfmt='k+', basefmt='C1-.', + label=' ', use_line_collection=use_line_collection) + + fig, ax = plt.subplots() + if use_line_collection: + ax.stem(*args, **kwargs) + else: + with pytest.warns(UserWarning): + ax.stem(*args, **kwargs) + + ax.legend() + + def test_stem_args(): fig = plt.figure() ax = fig.add_subplot(1, 1, 1) From cdaadb84ca4ba231e089e652c18401088fa16409 Mon Sep 17 00:00:00 2001 From: David Stansby Date: Wed, 10 Oct 2018 21:17:14 +0100 Subject: [PATCH 02/13] Update pyplot --- lib/matplotlib/pyplot.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/lib/matplotlib/pyplot.py b/lib/matplotlib/pyplot.py index 73c43302cbce..440c1ea05c72 100644 --- a/lib/matplotlib/pyplot.py +++ b/lib/matplotlib/pyplot.py @@ -2899,11 +2899,12 @@ def stackplot(x, *args, data=None, **kwargs): @docstring.copy_dedent(Axes.stem) def stem( *args, linefmt=None, markerfmt=None, basefmt=None, bottom=0, - label=None, data=None): + label=None, use_line_collection=False, data=None): return gca().stem( *args, linefmt=linefmt, markerfmt=markerfmt, basefmt=basefmt, - bottom=bottom, label=label, **({"data": data} if data is not - None else {})) + bottom=bottom, label=label, + use_line_collection=use_line_collection, **({"data": data} if + data is not None else {})) # Autogenerated by boilerplate.py. Do not edit as changes will be lost. From 00de51bc617356aa0564d9e29801d6ca6cc32b79 Mon Sep 17 00:00:00 2001 From: David Stansby Date: Tue, 1 Jan 2019 16:55:34 +0000 Subject: [PATCH 03/13] Fix doc tilde --- lib/matplotlib/axes/_axes.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/matplotlib/axes/_axes.py b/lib/matplotlib/axes/_axes.py index 64503c7fd5f9..d112158cb919 100644 --- a/lib/matplotlib/axes/_axes.py +++ b/lib/matplotlib/axes/_axes.py @@ -2541,7 +2541,7 @@ def stem(self, *args, linefmt=None, markerfmt=None, basefmt=None, bottom=0, use_line_collection : bool, optional, default: False If ``True``, store and plot the stem lines as a - ~`.collections.LineCollection` instead of individual lines. This + `~.collections.LineCollection` instead of individual lines. This significantly increases performance, and will become the default option in Matplotlib 3.3. If ``False``, defaults to old behaviour. From be0dc01a3e42ceda6132ebf64d7dc269add192cd Mon Sep 17 00:00:00 2001 From: Jody Klymak Date: Fri, 4 Jan 2019 09:38:49 -0800 Subject: [PATCH 04/13] ...Fix warnings.warn->cbook._warn_external --- lib/matplotlib/axes/_axes.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/matplotlib/axes/_axes.py b/lib/matplotlib/axes/_axes.py index d112158cb919..b5d7ffc6aa49 100644 --- a/lib/matplotlib/axes/_axes.py +++ b/lib/matplotlib/axes/_axes.py @@ -2638,7 +2638,7 @@ def stem(self, *args, linefmt=None, markerfmt=None, basefmt=None, bottom=0, self.add_collection(stemlines) # Old behaviour is to plot each of the lines individually else: - warnings.warn( + cbook._warn_extrnal( 'In Matplotlib 3.3 individual lines on a stem plot will be ' 'added as a LineCollection instead of individual lines.\n' 'This significantly improves the performance of a stem plot.\n' From a986013f212b3c8ff55d714ac11139a6045c2eec Mon Sep 17 00:00:00 2001 From: Jody Klymak Date: Fri, 4 Jan 2019 10:40:55 -0800 Subject: [PATCH 05/13] ahem... spelling of _warn_external --- lib/matplotlib/axes/_axes.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/matplotlib/axes/_axes.py b/lib/matplotlib/axes/_axes.py index b5d7ffc6aa49..ea94919c470e 100644 --- a/lib/matplotlib/axes/_axes.py +++ b/lib/matplotlib/axes/_axes.py @@ -2638,7 +2638,7 @@ def stem(self, *args, linefmt=None, markerfmt=None, basefmt=None, bottom=0, self.add_collection(stemlines) # Old behaviour is to plot each of the lines individually else: - cbook._warn_extrnal( + cbook._warn_external( 'In Matplotlib 3.3 individual lines on a stem plot will be ' 'added as a LineCollection instead of individual lines.\n' 'This significantly improves the performance of a stem plot.\n' From da04fa3294ca6955172f0beab0b0b3334867d10f Mon Sep 17 00:00:00 2001 From: Tim Hoffmann <2836374+timhoffm@users.noreply.github.com> Date: Sat, 5 Jan 2019 21:07:46 +0000 Subject: [PATCH 06/13] Fix docstring quotes Co-Authored-By: dstansby --- lib/matplotlib/container.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/matplotlib/container.py b/lib/matplotlib/container.py index 0f71c606fe5c..194ae401bcef 100644 --- a/lib/matplotlib/container.py +++ b/lib/matplotlib/container.py @@ -176,7 +176,7 @@ class StemContainer(Container): The artist of the horizontal baseline. """ def __init__(self, markerline_stemlines_baseline, **kwargs): - ''' + """ Parameters ---------- markerline_stemlines_baseline : tuple @@ -184,7 +184,7 @@ def __init__(self, markerline_stemlines_baseline, **kwargs): ``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 From 0bef71457a236fe17d5c5ef76695bfc69dc60d85 Mon Sep 17 00:00:00 2001 From: David Stansby Date: Sat, 19 Jan 2019 20:19:50 +0000 Subject: [PATCH 07/13] Docstring double quotes --- lib/matplotlib/legend_handler.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/matplotlib/legend_handler.py b/lib/matplotlib/legend_handler.py index cb5ed2a0edd3..b27331bc00f2 100644 --- a/lib/matplotlib/legend_handler.py +++ b/lib/matplotlib/legend_handler.py @@ -649,10 +649,10 @@ def create_artists(self, legend, orig_handle, 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.set_color(orig_handle.get_color()[0]) legend_handle.set_linestyle(orig_handle.get_linestyle()[0]) From 6b19ba68a7f4b7f6e5697fe949d3122496226655 Mon Sep 17 00:00:00 2001 From: David Stansby Date: Sat, 19 Jan 2019 20:21:18 +0000 Subject: [PATCH 08/13] Small doc change + use zip --- 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 ea94919c470e..1ecad523477b 100644 --- a/lib/matplotlib/axes/_axes.py +++ b/lib/matplotlib/axes/_axes.py @@ -2543,7 +2543,8 @@ def stem(self, *args, linefmt=None, markerfmt=None, basefmt=None, bottom=0, If ``True``, store and plot the stem lines as a `~.collections.LineCollection` instead of individual lines. This significantly increases performance, and will become the default - option in Matplotlib 3.3. If ``False``, defaults to old behaviour. + option in Matplotlib 3.3. If ``False``, defaults to the old + behavior of using a list of `.Line2D` objects. Returns @@ -2630,8 +2631,7 @@ def stem(self, *args, linefmt=None, markerfmt=None, basefmt=None, bottom=0, # New behaviour in 3.1 is to use a LineCollection for the stemlines if use_line_collection: stemlines = [] - for thisx, thisy in zip(x, y): - stemlines.append(((thisx, bottom), (thisx, thisy))) + stemlines = [((xi, bottom), (xi, yi)) for xi, yi in zip(x, y)] stemlines = mcoll.LineCollection(stemlines, linestyles=linestyle, colors=linecolor, label='_nolegend_') From 1f7228d63bfeb80a204f5d3875fd6a9ab759efc9 Mon Sep 17 00:00:00 2001 From: David Stansby Date: Sat, 19 Jan 2019 20:33:10 +0000 Subject: [PATCH 09/13] Remove code duplication --- lib/matplotlib/legend_handler.py | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/lib/matplotlib/legend_handler.py b/lib/matplotlib/legend_handler.py index b27331bc00f2..a9fafcc3686a 100644 --- a/lib/matplotlib/legend_handler.py +++ b/lib/matplotlib/legend_handler.py @@ -618,27 +618,20 @@ def create_artists(self, legend, orig_handle, 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) + for line in leg_stemlines: + self.update_prop(line, stemlines, legend) - self._update_prop_func = orig_update_func else: - for thisx, thisy in zip(xdata_marker, ydata): - thisline = Line2D([thisx, thisx], [bottom, thisy]) - leg_stemlines.append(thisline) for lm, m in zip(leg_stemlines, stemlines): self.update_prop(lm, m, legend) + if using_linecoll: + 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) - 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) From 6d6c78686a15ded8ef25a50c22878d2c7fad8383 Mon Sep 17 00:00:00 2001 From: David Stansby Date: Sat, 19 Jan 2019 20:34:57 +0000 Subject: [PATCH 10/13] Fix missing indentation --- 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 1ecad523477b..645c45272aac 100644 --- a/lib/matplotlib/axes/_axes.py +++ b/lib/matplotlib/axes/_axes.py @@ -2645,11 +2645,11 @@ def stem(self, *args, linefmt=None, markerfmt=None, basefmt=None, bottom=0, 'To remove this warning and switch to the new behaviour, ' 'set the "use_line_collection" keyword argument to True.') stemlines = [] - for thisx, thisy in zip(x, y): - l, = self.plot([thisx, thisx], [bottom, thisy], + for xi, yi in zip(x, y): + l, = self.plot([xi, xi], [bottom, yi], color=linecolor, linestyle=linestyle, marker=linemarker, label="_nolegend_") - stemlines.append(l) + stemlines.append(l) markerline, = self.plot(x, y, color=markercolor, linestyle=markerstyle, marker=markermarker, label="_nolegend_") From 9aa02ec100c630c51633afae30709758b6f6a8ee Mon Sep 17 00:00:00 2001 From: Jody Klymak Date: Sat, 9 Feb 2019 13:44:32 -0800 Subject: [PATCH 11/13] Update _axes.py Remove carriage returns.... --- lib/matplotlib/axes/_axes.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/matplotlib/axes/_axes.py b/lib/matplotlib/axes/_axes.py index 645c45272aac..6a1c104c1741 100644 --- a/lib/matplotlib/axes/_axes.py +++ b/lib/matplotlib/axes/_axes.py @@ -2640,8 +2640,8 @@ def stem(self, *args, linefmt=None, markerfmt=None, basefmt=None, bottom=0, else: cbook._warn_external( 'In Matplotlib 3.3 individual lines on a stem plot will be ' - 'added as a LineCollection instead of individual lines.\n' - 'This significantly improves the performance of a stem plot.\n' + 'added as a LineCollection instead of individual lines. ' + 'This significantly improves the performance of a stem plot. ' 'To remove this warning and switch to the new behaviour, ' 'set the "use_line_collection" keyword argument to True.') stemlines = [] From 7828b9c5e313a3ea51a5c7a8e4b3b9766bfaf8c3 Mon Sep 17 00:00:00 2001 From: Jody Klymak Date: Sat, 9 Feb 2019 13:45:51 -0800 Subject: [PATCH 12/13] clarified comment --- lib/matplotlib/legend_handler.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/matplotlib/legend_handler.py b/lib/matplotlib/legend_handler.py index a9fafcc3686a..b354f4792f39 100644 --- a/lib/matplotlib/legend_handler.py +++ b/lib/matplotlib/legend_handler.py @@ -613,8 +613,8 @@ def create_artists(self, legend, orig_handle, for x, y in zip(xdata_marker, ydata)] if using_linecoll: - # update_prop() usually takes two Line2D collections; - # override temporarily to copy properties from a LineCollection + # change the function used by update_prop() from the default + # to one that handles LineCollection orig_update_func = self._update_prop_func self._update_prop_func = self._copy_collection_props From 2e986335a81c7b7e0f7c6d936fab3a833958e21b Mon Sep 17 00:00:00 2001 From: Jody Klymak Date: Sun, 10 Feb 2019 09:55:59 -0800 Subject: [PATCH 13/13] Trailing whitespace --- lib/matplotlib/legend_handler.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/matplotlib/legend_handler.py b/lib/matplotlib/legend_handler.py index b354f4792f39..cea1b0a5b2a2 100644 --- a/lib/matplotlib/legend_handler.py +++ b/lib/matplotlib/legend_handler.py @@ -613,7 +613,7 @@ def create_artists(self, legend, orig_handle, for x, y in zip(xdata_marker, ydata)] if using_linecoll: - # change the function used by update_prop() from the default + # change the function used by update_prop() from the default # to one that handles LineCollection orig_update_func = self._update_prop_func self._update_prop_func = self._copy_collection_props