Skip to content

Commit c8a365a

Browse files
committed
MNT: start to use artists directly in errorbar
Instead of using calls to `plt.plot`
1 parent c94c282 commit c8a365a

File tree

1 file changed

+79
-48
lines changed

1 file changed

+79
-48
lines changed

lib/matplotlib/axes/_axes.py

+79-48
Original file line numberDiff line numberDiff line change
@@ -2806,15 +2806,32 @@ def errorbar(self, x, y, yerr=None, xerr=None,
28062806

28072807
if fmt is None:
28082808
fmt = 'none'
2809-
msg = ('Use of None object as fmt keyword argument to '
2810-
+ 'suppress plotting of data values is deprecated '
2811-
+ 'since 1.4; use the string "none" instead.')
2809+
msg = ('Use of None object as fmt keyword argument to ' +
2810+
'suppress plotting of data values is deprecated ' +
2811+
'since 1.4; use the string "none" instead.')
28122812
warnings.warn(msg, mplDeprecation, stacklevel=1)
28132813

28142814
plot_line = (fmt.lower() != 'none')
2815-
28162815
label = kwargs.pop("label", None)
28172816

2817+
fmt_style_kwargs = {k: v for k, v in
2818+
zip(('linestyle', 'marker', 'color'),
2819+
_process_plot_format(fmt)) if v is not None}
2820+
2821+
if ('color' in kwargs or 'color' in fmt_style_kwargs or
2822+
ecolor is not None):
2823+
base_style = {}
2824+
if 'color' in kwargs:
2825+
base_style['color'] = kwargs.pop('color')
2826+
else:
2827+
base_style = six.next(self._get_lines.prop_cycler)
2828+
2829+
base_style['label'] = '_nolegend_'
2830+
base_style.update(fmt_style_kwargs)
2831+
if 'color' not in base_style:
2832+
base_style['color'] = 'b'
2833+
if ecolor is None:
2834+
ecolor = base_style['color']
28182835
# make sure all the args are iterable; use lists not arrays to
28192836
# preserve units
28202837
if not iterable(x):
@@ -2836,12 +2853,18 @@ def errorbar(self, x, y, yerr=None, xerr=None,
28362853
# Instead of using zorder, the line plot is being added
28372854
# either here, or after all the errorbar plot elements.
28382855
if barsabove and plot_line:
2839-
l0, = self.plot(x, y, fmt, label="_nolegend_", **kwargs)
2856+
# in python3.5+ this can be simplified
2857+
eb_style = dict(base_style)
2858+
eb_style.update(**kwargs)
2859+
l0 = mlines.Line2D(x, y, **eb_style)
2860+
self.add_line(l0)
28402861

28412862
barcols = []
28422863
caplines = []
28432864

2844-
lines_kw = {'label': '_nolegend_'}
2865+
lines_kw = dict(base_style)
2866+
lines_kw.pop('marker', None)
2867+
lines_kw.pop('linestyle', None)
28452868
if elinewidth:
28462869
lines_kw['linewidth'] = elinewidth
28472870
else:
@@ -2853,25 +2876,16 @@ def errorbar(self, x, y, yerr=None, xerr=None,
28532876
lines_kw[key] = kwargs[key]
28542877

28552878
# arrays fine here, they are booleans and hence not units
2856-
if not iterable(lolims):
2857-
lolims = np.asarray([lolims] * len(x), bool)
2858-
else:
2859-
lolims = np.asarray(lolims, bool)
2860-
2861-
if not iterable(uplims):
2862-
uplims = np.array([uplims] * len(x), bool)
2863-
else:
2864-
uplims = np.asarray(uplims, bool)
2865-
2866-
if not iterable(xlolims):
2867-
xlolims = np.array([xlolims] * len(x), bool)
2868-
else:
2869-
xlolims = np.asarray(xlolims, bool)
2879+
def _bool_asarray_helper(d, expected):
2880+
if not iterable(d):
2881+
return np.asarray([d] * expected, bool)
2882+
else:
2883+
return np.asarray(d, bool)
28702884

2871-
if not iterable(xuplims):
2872-
xuplims = np.array([xuplims] * len(x), bool)
2873-
else:
2874-
xuplims = np.asarray(xuplims, bool)
2885+
lolims = _bool_asarray_helper(lolims, len(x))
2886+
uplims = _bool_asarray_helper(uplims, len(x))
2887+
xlolims = _bool_asarray_helper(xlolims, len(x))
2888+
xuplims = _bool_asarray_helper(xuplims, len(x))
28752889

28762890
everymask = np.arange(len(x)) % errorevery == 0
28772891

@@ -2886,7 +2900,11 @@ def xywhere(xs, ys, mask):
28862900
ys = [thisy for thisy, b in zip(ys, mask) if b]
28872901
return xs, ys
28882902

2889-
plot_kw = {'label': '_nolegend_'}
2903+
plot_kw = dict(base_style)
2904+
# eject any marker information from format string
2905+
plot_kw.pop('marker', None)
2906+
plot_kw.pop('ls', None)
2907+
plot_kw['linestyle'] = 'none'
28902908
if capsize is None:
28912909
capsize = rcParams["errorbar.capsize"]
28922910
if capsize > 0:
@@ -2904,6 +2922,7 @@ def xywhere(xs, ys, mask):
29042922
'zorder', 'rasterized'):
29052923
if key in kwargs:
29062924
plot_kw[key] = kwargs[key]
2925+
plot_kw['color'] = ecolor
29072926

29082927
def extract_err(err, data):
29092928
'''private function to compute error bars
@@ -2951,8 +2970,10 @@ def extract_err(err, data):
29512970
lo, ro = xywhere(left, right, noxlims & everymask)
29522971
barcols.append(self.hlines(yo, lo, ro, **lines_kw))
29532972
if capsize > 0:
2954-
caplines.extend(self.plot(lo, yo, 'k|', **plot_kw))
2955-
caplines.extend(self.plot(ro, yo, 'k|', **plot_kw))
2973+
caplines.append(mlines.Line2D(lo, yo, marker='|',
2974+
**plot_kw))
2975+
caplines.append(mlines.Line2D(ro, yo, marker='|',
2976+
**plot_kw))
29562977

29572978
if xlolims.any():
29582979
yo, _ = xywhere(y, right, xlolims & everymask)
@@ -2963,12 +2984,13 @@ def extract_err(err, data):
29632984
marker = mlines.CARETLEFTBASE
29642985
else:
29652986
marker = mlines.CARETRIGHTBASE
2966-
caplines.extend(
2967-
self.plot(rightup, yup, ls='None', marker=marker,
2968-
**plot_kw))
2987+
caplines.append(
2988+
mlines.Line2D(rightup, yup, ls='None', marker=marker,
2989+
**plot_kw))
29692990
if capsize > 0:
29702991
xlo, ylo = xywhere(x, y, xlolims & everymask)
2971-
caplines.extend(self.plot(xlo, ylo, 'k|', **plot_kw))
2992+
caplines.append(mlines.Line2D(xlo, ylo, marker='|',
2993+
**plot_kw))
29722994

29732995
if xuplims.any():
29742996
yo, _ = xywhere(y, right, xuplims & everymask)
@@ -2979,12 +3001,13 @@ def extract_err(err, data):
29793001
marker = mlines.CARETRIGHTBASE
29803002
else:
29813003
marker = mlines.CARETLEFTBASE
2982-
caplines.extend(
2983-
self.plot(leftlo, ylo, ls='None', marker=marker,
2984-
**plot_kw))
3004+
caplines.append(
3005+
mlines.Line2D(leftlo, ylo, ls='None', marker=marker,
3006+
**plot_kw))
29853007
if capsize > 0:
29863008
xup, yup = xywhere(x, y, xuplims & everymask)
2987-
caplines.extend(self.plot(xup, yup, 'k|', **plot_kw))
3009+
caplines.append(mlines.Line2D(xup, yup, marker='|',
3010+
**plot_kw))
29883011

29893012
if yerr is not None:
29903013
lower, upper = extract_err(yerr, y)
@@ -2996,8 +3019,10 @@ def extract_err(err, data):
29963019
lo, uo = xywhere(lower, upper, noylims & everymask)
29973020
barcols.append(self.vlines(xo, lo, uo, **lines_kw))
29983021
if capsize > 0:
2999-
caplines.extend(self.plot(xo, lo, 'k_', **plot_kw))
3000-
caplines.extend(self.plot(xo, uo, 'k_', **plot_kw))
3022+
caplines.append(mlines.Line2D(xo, lo, marker='_',
3023+
**plot_kw))
3024+
caplines.append(mlines.Line2D(xo, uo, marker='_',
3025+
**plot_kw))
30013026

30023027
if lolims.any():
30033028
xo, _ = xywhere(x, lower, lolims & everymask)
@@ -3008,12 +3033,13 @@ def extract_err(err, data):
30083033
marker = mlines.CARETDOWNBASE
30093034
else:
30103035
marker = mlines.CARETUPBASE
3011-
caplines.extend(
3012-
self.plot(xup, upperup, ls='None', marker=marker,
3013-
**plot_kw))
3036+
caplines.append(
3037+
mlines.Line2D(xup, upperup, ls='None', marker=marker,
3038+
**plot_kw))
30143039
if capsize > 0:
30153040
xlo, ylo = xywhere(x, y, lolims & everymask)
3016-
caplines.extend(self.plot(xlo, ylo, 'k_', **plot_kw))
3041+
caplines.append(mlines.Line2D(xlo, ylo, marker='_',
3042+
**plot_kw))
30173043

30183044
if uplims.any():
30193045
xo, _ = xywhere(x, lower, uplims & everymask)
@@ -3024,15 +3050,22 @@ def extract_err(err, data):
30243050
marker = mlines.CARETUPBASE
30253051
else:
30263052
marker = mlines.CARETDOWNBASE
3027-
caplines.extend(
3028-
self.plot(xlo, lowerlo, ls='None', marker=marker,
3029-
**plot_kw))
3053+
caplines.append(
3054+
mlines.Line2D(xlo, lowerlo, ls='None', marker=marker,
3055+
**plot_kw))
30303056
if capsize > 0:
30313057
xup, yup = xywhere(x, y, uplims & everymask)
3032-
caplines.extend(self.plot(xup, yup, 'k_', **plot_kw))
3058+
caplines.append(mlines.Line2D(xup, yup, marker='_',
3059+
**plot_kw))
3060+
for l in caplines:
3061+
self.add_line(l)
30333062

30343063
if not barsabove and plot_line:
3035-
l0, = self.plot(x, y, fmt, label='_nolegend_', **kwargs)
3064+
# in python3.5+ this can be simplified
3065+
eb_style = dict(base_style)
3066+
eb_style.update(**kwargs)
3067+
l0 = mlines.Line2D(x, y, **eb_style)
3068+
self.add_line(l0)
30363069

30373070
if ecolor is None:
30383071
if l0 is None:
@@ -3042,8 +3075,6 @@ def extract_err(err, data):
30423075

30433076
for l in barcols:
30443077
l.set_color(ecolor)
3045-
for l in caplines:
3046-
l.set_color(ecolor)
30473078

30483079
self.autoscale_view()
30493080
self._hold = holdstate

0 commit comments

Comments
 (0)