From e078f918c9625d29e1e65964315aa23602de5ecd Mon Sep 17 00:00:00 2001 From: Thomas A Caswell Date: Sun, 27 Aug 2017 18:58:19 -0400 Subject: [PATCH 1/7] API: change signature of bar and barh Change the documented first position argument to x and y for bar and barh respectively but still support passing in left and bottom as keyword arguments. closes #7954 closes #8327 closes #8527 closes #8882 --- doc/api/api_changes/2017-08-27-TAC.rst | 22 ++ doc/users/dflt_style_changes.rst | 2 + examples/pie_and_polar_charts/nested_pie.py | 6 +- lib/matplotlib/axes/_axes.py | 247 ++++++++++++++------ lib/matplotlib/pyplot.py | 13 +- lib/matplotlib/tests/test_axes.py | 32 +++ lib/matplotlib/tests/test_pickle.py | 2 +- 7 files changed, 241 insertions(+), 83 deletions(-) create mode 100644 doc/api/api_changes/2017-08-27-TAC.rst diff --git a/doc/api/api_changes/2017-08-27-TAC.rst b/doc/api/api_changes/2017-08-27-TAC.rst new file mode 100644 index 000000000000..82f709169eb8 --- /dev/null +++ b/doc/api/api_changes/2017-08-27-TAC.rst @@ -0,0 +1,22 @@ +Change to signatures of :meth:`~matplotlib.axes.Axes.bar` & :meth:`~matplotlib.axes.Axes.barh` +---------------------------------------------------------------------------------------------- + +For 2.0 the :ref:`default value of *align* ` changed to +``'center'``. However this caused the signature of +:meth:`~matplotlib.axes.Axes.bar` and +:meth:`~matplotlib.axes.Axes.barh` to be misleading as the first parameters were +still *left* and *bottom* respectively:: + + bar(left, height, *, align='center', **kwargs) + barh(bottom, width, *, align='center', **kwargs) + +despite behaving as the center in both cases. The methods now take ``*args, **kwargs`` +is input and are documented to have the primary signatures of:: + + bar(x, height, *, align='center', **kwargs) + barh(y, width, *, align='center', **kwargs) + +Passing *left* and *bottom* as keyword arguments to +:meth:`~matplotlib.axes.Axes.bar` and +:meth:`~matplotlib.axes.Axes.barh` respectively will warn. +Support will be removed in Matplotlib 3.0. diff --git a/doc/users/dflt_style_changes.rst b/doc/users/dflt_style_changes.rst index 2035b71773a5..06984253e72b 100644 --- a/doc/users/dflt_style_changes.rst +++ b/doc/users/dflt_style_changes.rst @@ -599,6 +599,8 @@ The default value of the ``linecolor`` kwarg for `~matplotlib.Axes.hexbin` has changed from ``'none'`` to ``'face'``. If 'none' is now supplied, no line edges are drawn around the hexagons. +.. _barbarh_align: + ``bar`` and ``barh`` -------------------- diff --git a/examples/pie_and_polar_charts/nested_pie.py b/examples/pie_and_polar_charts/nested_pie.py index 5355bd615611..7dd77a1f531d 100644 --- a/examples/pie_and_polar_charts/nested_pie.py +++ b/examples/pie_and_polar_charts/nested_pie.py @@ -44,17 +44,17 @@ left_middle = np.arange(0.0, 2 * np.pi, 2 * np.pi / 12) left_outer = np.arange(0.0, 2 * np.pi, 2 * np.pi / 9) -ax.bar(left=left_inner, +ax.bar(x=left_inner, width=2 * np.pi / 6, bottom=0, color='C0', linewidth=2, edgecolor='w', height=np.zeros_like(left_inner) + 5) -ax.bar(left=left_middle, +ax.bar(x=left_middle, width=2 * np.pi / 12, bottom=5, color='C1', linewidth=2, edgecolor='w', height=np.zeros_like(left_middle) + 2) -ax.bar(left=left_outer, +ax.bar(x=left_outer, width=2 * np.pi / 9, bottom=7, color='C2', linewidth=2, edgecolor='w', height=np.zeros_like(left_outer) + 3) diff --git a/lib/matplotlib/axes/_axes.py b/lib/matplotlib/axes/_axes.py index 15ba96030a89..bcbfae8837ab 100644 --- a/lib/matplotlib/axes/_axes.py +++ b/lib/matplotlib/axes/_axes.py @@ -1868,25 +1868,49 @@ def step(self, x, y, *args, **kwargs): return self.plot(x, y, *args, **kwargs) - @_preprocess_data(replace_names=["left", "height", "width", "bottom", + @_preprocess_data(replace_names=["x", "left", + "height", "width", + "y", "bottom", "color", "edgecolor", "linewidth", "tick_label", "xerr", "yerr", "ecolor"], - label_namer=None) + label_namer=None, + replace_all_args=True + ) @docstring.dedent_interpd - def bar(self, left, height, width=0.8, bottom=None, **kwargs): + def bar(self, *args, **kwargs): """ Make a bar plot. - Make a bar plot with rectangles bounded by: + Call signatures:: + + bar(x, height, *, align='center', **kwargs) + bar(x, height, width, *, align='center', **kwargs) + bar(x, height, width, bottom, *, align='center', **kwargs) + + Make a bar plot with rectangles bounded by + + .. math:: + + (x - width/2, x + width/2, bottom, bottom + height) + + (left, right, bottom and top edges) by default. *x*, + *height*, *width*, and *bottom* can be either scalars or + sequences. - `left`, `left` + `width`, `bottom`, `bottom` + `height` - (left, right, bottom and top edges) + The *align* and *orientation* kwargs control the interpretation of *x* + and *bottom* + + The *align* keyword-only argument controls if *x* is interpreted + as the center or the left edge of the rectangle. Parameters ---------- - left : sequence of scalars - the x coordinates of the left sides of the bars + x : sequence of scalars + the x coordinates of the bars. + + *align* controls if *x* is the bar center (default) or + left edge. height : scalar or sequence of scalars the height(s) of the bars @@ -1899,6 +1923,21 @@ def bar(self, left, height, width=0.8, bottom=None, **kwargs): the y coordinate(s) of the bars default: None + align : {'center', 'edge'}, optional, default: 'center' + If 'center', interpret the *x* argument as the coordinates + of the centers of the bars. If 'edge', aligns bars by + their left edges + + To align the bars on the right edge pass a negative + *width* and ``align='edge'`` + + Returns + ------- + bars : matplotlib.container.BarContainer + Container with all of the bars + errorbars + + Other Parameters + ---------------- color : scalar or array-like, optional the colors of the bar faces @@ -1935,24 +1974,20 @@ def bar(self, left, height, width=0.8, bottom=None, **kwargs): dictionary of kwargs to be passed to errorbar method. *ecolor* and *capsize* may be specified here rather than as independent kwargs. - align : {'center', 'edge'}, optional, default: 'center' - If 'edge', aligns bars by their left edges (for vertical bars) and - by their bottom edges (for horizontal bars). If 'center', interpret - the `left` argument as the coordinates of the centers of the bars. - To align on the align bars on the right edge pass a negative - `width`. - - orientation : {'vertical', 'horizontal'}, optional - The orientation of the bars. - log : boolean, optional If true, sets the axis to be log scale. default: False - Returns - ------- - bars : matplotlib.container.BarContainer - Container with all of the bars + errorbars + orientation : {'vertical', 'horizontal'}, optional + + This is for internal use, please do not directly use this, + call `barh` instead. + + The orientation of the bars. + + See also + -------- + barh: Plot a horizontal bar plot. Notes ----- @@ -1968,11 +2003,34 @@ def bar(self, left, height, width=0.8, bottom=None, **kwargs): %(Rectangle)s - See also - -------- - barh: Plot a horizontal bar plot. """ kwargs = cbook.normalize_kwargs(kwargs, mpatches._patch_alias_map) + + matchers = [ + (lambda x, height, width=0.8, bottom=None, **kwargs: + (False, x, height, width, bottom, kwargs)), + (lambda left, height, width=0.8, bottom=None, **kwargs: + (True, left, height, width, bottom, kwargs)), + ] + exps = [] + for matcher in matchers: + try: + dp, x, height, width, y, kwargs = matcher(*args, **kwargs) + except TypeError as e: + # This can only come from a no-match as there is + # no other logic in the matchers. + exps.append(e) + else: + break + else: + raise exps[0] + # if we matched the second-case, then the user passed in + # left=val as a kwarg which we want to deprecate + if dp: + warnings.warn( + "The *left* kwarg to `bar` is deprecated use *x* instead. " + "Support for *left* will be removed in Matplotlib 3.0", + mplDeprecation, stacklevel=2) if not self._hold: self.cla() color = kwargs.pop('color', None) @@ -2002,38 +2060,38 @@ def bar(self, left, height, width=0.8, bottom=None, **kwargs): label = kwargs.pop('label', '') tick_labels = kwargs.pop('tick_label', None) - _left = left - _bottom = bottom - left, height, width, bottom = np.broadcast_arrays( + _x = x + _y = y + x, height, width, y, linewidth = np.broadcast_arrays( # Make args iterable too. - np.atleast_1d(left), height, width, bottom) + np.atleast_1d(x), height, width, y, linewidth) adjust_ylim = False adjust_xlim = False if orientation == 'vertical': - self._process_unit_info(xdata=left, ydata=height, kwargs=kwargs) + self._process_unit_info(xdata=x, ydata=height, kwargs=kwargs) if log: self.set_yscale('log', nonposy='clip') - # size width and bottom according to length of left - if _bottom is None: + # size width and y according to length of x + if _y is None: if self.get_yscale() == 'log': adjust_ylim = True - bottom = np.zeros_like(bottom) + y = np.zeros_like(y) tick_label_axis = self.xaxis - tick_label_position = left + tick_label_position = x elif orientation == 'horizontal': - self._process_unit_info(xdata=width, ydata=bottom, kwargs=kwargs) + self._process_unit_info(xdata=width, ydata=y, kwargs=kwargs) if log: self.set_xscale('log', nonposx='clip') - # size left and height according to length of bottom - if _left is None: + # size x and height according to length of y + if _x is None: if self.get_xscale() == 'log': adjust_xlim = True - left = np.zeros_like(left) + x = np.zeros_like(x) tick_label_axis = self.yaxis - tick_label_position = bottom + tick_label_position = y else: raise ValueError('invalid orientation: %s' % orientation) @@ -2051,24 +2109,30 @@ def bar(self, left, height, width=0.8, bottom=None, **kwargs): # lets do some conversions now since some types cannot be # subtracted uniformly if self.xaxis is not None: - left = self.convert_xunits(left) + x = self.convert_xunits(x) width = self.convert_xunits(width) if xerr is not None: xerr = self.convert_xunits(xerr) if self.yaxis is not None: - bottom = self.convert_yunits(bottom) + y = self.convert_yunits(y) height = self.convert_yunits(height) if yerr is not None: yerr = self.convert_yunits(yerr) + # We will now resolve the alignment and really have + # left, bottom, width, height vectors if align == 'center': if orientation == 'vertical': - left = left - width / 2 + left = x - width / 2 + bottom = y elif orientation == 'horizontal': - bottom = bottom - height / 2 - - elif align != 'edge': + bottom = y - height / 2 + left = x + elif align == 'edge': + left = x + bottom = y + else: raise ValueError('invalid alignment: %s' % align) patches = [] @@ -2096,18 +2160,17 @@ def bar(self, left, height, width=0.8, bottom=None, **kwargs): if xerr is not None or yerr is not None: if orientation == 'vertical': # using list comps rather than arrays to preserve unit info - x = [l + 0.5 * w for l, w in zip(left, width)] - y = [b + h for b, h in zip(bottom, height)] + ex = [l + 0.5 * w for l, w in zip(left, width)] + ey = [b + h for b, h in zip(bottom, height)] elif orientation == 'horizontal': # using list comps rather than arrays to preserve unit info - x = [l + w for l, w in zip(left, width)] - y = [b + 0.5 * h for b, h in zip(bottom, height)] + ex = [l + w for l, w in zip(left, width)] + ey = [b + 0.5 * h for b, h in zip(bottom, height)] - if "label" not in error_kw: - error_kw["label"] = '_nolegend_' + error_kw.setdefault("label", '_nolegend_') - errorbar = self.errorbar(x, y, + errorbar = self.errorbar(ex, ey, yerr=yerr, xerr=xerr, fmt='none', **error_kw) else: @@ -2143,23 +2206,37 @@ def bar(self, left, height, width=0.8, bottom=None, **kwargs): return bar_container @docstring.dedent_interpd - def barh(self, bottom, width, height=0.8, left=None, **kwargs): + def barh(self, *args, **kwargs): """ Make a horizontal bar plot. - Make a horizontal bar plot with rectangles bounded by: + Call signatures:: + + bar(y, width, *, align='center', **kwargs) + bar(y, width, height, *, align='center', **kwargs) + bar(y, width, height, left, *, align='center', **kwargs) + + Make a horizontal bar plot with rectangles by default bounded by + + .. math:: + + (left, left + width, y - height/2, y + height/2) + + (left, right, bottom and top edges) by default. *y*, *width*, + *height*, and *left* can be either scalars or sequences. - `left`, `left` + `width`, `bottom`, `bottom` + `height` - (left, right, bottom and top edges) + The *align* keyword-only argument controls if *y* is interpreted + as the center or the bottom edge of the rectangle. - `bottom`, `width`, `height`, and `left` can be either scalars - or sequences Parameters ---------- - bottom : scalar or array-like + y : scalar or array-like the y coordinate(s) of the bars + *align* controls if *y* is the bar center (default) + or bottom edge. + width : scalar or array-like the width(s) of the bars @@ -2169,6 +2246,14 @@ def barh(self, bottom, width, height=0.8, left=None, **kwargs): left : sequence of scalars the x coordinates of the left sides of the bars + align : {'center', 'edge'}, optional, default: 'center' + If 'center', interpret the *y* argument as the coordinates + of the centers of the bars. If 'edge', aligns bars by + their bottom edges + + To align the bars on the top edge pass a negative + *height* and ``align='edge'`` + Returns ------- `matplotlib.patches.Rectangle` instances. @@ -2206,16 +2291,13 @@ def barh(self, bottom, width, height=0.8, left=None, **kwargs): dictionary of kwargs to be passed to errorbar method. `ecolor` and `capsize` may be specified here rather than as independent kwargs. - align : {'center', 'edge'}, optional, default: 'center' - If 'edge', aligns bars by their left edges (for vertical - bars) and by their bottom edges (for horizontal bars). If - 'center', interpret the `bottom` argument as the - coordinates of the centers of the bars. To align on the - align bars on the top edge pass a negative 'height'. - log : boolean, optional, default: False If true, sets the axis to be log scale + See also + -------- + bar: Plot a vertical bar plot. + Notes ----- The optional arguments `color`, `edgecolor`, `linewidth`, @@ -2230,13 +2312,34 @@ def barh(self, bottom, width, height=0.8, left=None, **kwargs): %(Rectangle)s - See also - -------- - bar: Plot a vertical bar plot. """ - - patches = self.bar(left=left, height=height, width=width, - bottom=bottom, orientation='horizontal', **kwargs) + matchers = [ + (lambda y, width, height=0.8, left=None, **kwargs: + (False, y, width, height, left, kwargs)), + (lambda bottom, width, height=0.8, left=None, **kwargs: + (True, bottom, width, height, left, kwargs)), + ] + excs = [] + for matcher in matchers: + try: + dp, y, width, height, left, kwargs = matcher(*args, **kwargs) + except TypeError as e: + # This can only come from a no-match as there is + # no other logic in the matchers. + excs.append(e) + else: + break + else: + raise excs[0] + + if dp: + warnings.warn( + "The *bottom* kwarg to `barh` is deprecated use *y* instead. " + "Support for *bottom* will be removed in Matplotlib 3.0", + mplDeprecation, stacklevel=2) + kwargs.setdefault('orientation', 'horizontal') + patches = self.bar(x=left, height=height, width=width, + bottom=y, **kwargs) return patches @_preprocess_data(label_namer=None) diff --git a/lib/matplotlib/pyplot.py b/lib/matplotlib/pyplot.py index 85b5ea47b657..6a8151889a49 100644 --- a/lib/matplotlib/pyplot.py +++ b/lib/matplotlib/pyplot.py @@ -2622,20 +2622,19 @@ def axvspan(xmin, xmax, ymin=0, ymax=1, hold=None, **kwargs): # This function was autogenerated by boilerplate.py. Do not edit as # changes will be lost @_autogen_docstring(Axes.bar) -def bar(left, height, width=0.8, bottom=None, hold=None, data=None, **kwargs): +def bar(*args, **kwargs): ax = gca() # Deprecated: allow callers to override the hold state # by passing hold=True|False washold = ax._hold - + hold = kwargs.pop('hold', None) if hold is not None: ax._hold = hold from matplotlib.cbook import mplDeprecation warnings.warn("The 'hold' keyword argument is deprecated since 2.0.", mplDeprecation) try: - ret = ax.bar(left, height, width=width, bottom=bottom, data=data, - **kwargs) + ret = ax.bar(*args, **kwargs) finally: ax._hold = washold @@ -2644,19 +2643,19 @@ def bar(left, height, width=0.8, bottom=None, hold=None, data=None, **kwargs): # This function was autogenerated by boilerplate.py. Do not edit as # changes will be lost @_autogen_docstring(Axes.barh) -def barh(bottom, width, height=0.8, left=None, hold=None, **kwargs): +def barh(*args, **kwargs): ax = gca() # Deprecated: allow callers to override the hold state # by passing hold=True|False washold = ax._hold - + hold = kwargs.pop('hold', None) if hold is not None: ax._hold = hold from matplotlib.cbook import mplDeprecation warnings.warn("The 'hold' keyword argument is deprecated since 2.0.", mplDeprecation) try: - ret = ax.barh(bottom, width, height=height, left=left, **kwargs) + ret = ax.barh(*args, **kwargs) finally: ax._hold = washold diff --git a/lib/matplotlib/tests/test_axes.py b/lib/matplotlib/tests/test_axes.py index 7a0e8f326fc2..1d0aeee0a8e5 100644 --- a/lib/matplotlib/tests/test_axes.py +++ b/lib/matplotlib/tests/test_axes.py @@ -5266,6 +5266,38 @@ def test_twinx_knows_limits(): assert((xtwin.viewLim.intervalx == ax2.viewLim.intervalx).all()) +@pytest.mark.style('mpl20') +@pytest.mark.parametrize('args, kwargs, warning_count', + [((1, 1), {'width': 1, 'bottom': 1}, 0), + ((1, ), {'height': 1, 'bottom': 1}, 0), + ((), {'x': 1, 'height': 1}, 0), + ((), {'left': 1, 'height': 1}, 1)]) +def test_bar_signature(args, kwargs, warning_count): + fig, ax = plt.subplots() + with warnings.catch_warnings(record=True) as w: + r, = ax.bar(*args, **kwargs) + + assert r.get_width() == kwargs.get('width', 0.8) + assert r.get_y() == kwargs.get('bottom', 0) + assert len(w) == warning_count + + +@pytest.mark.style('mpl20') +@pytest.mark.parametrize('args, kwargs, warning_count', + [((1, 1), {'height': 1, 'left': 1}, 0), + ((1, ), {'width': 1, 'left': 1}, 0), + ((), {'y': 1, 'width': 1}, 0), + ((), {'bottom': 1, 'width': 1}, 1)]) +def test_barh_signature(args, kwargs, warning_count): + fig, ax = plt.subplots() + with warnings.catch_warnings(record=True) as w: + r, = ax.barh(*args, **kwargs) + + assert r.get_height() == kwargs.get('height', 0.8) + assert r.get_x() == kwargs.get('left', 0) + assert len(w) == warning_count + + def test_zero_linewidth(): # Check that setting a zero linewidth doesn't error plt.plot([0, 1], [0, 1], ls='--', lw=0) diff --git a/lib/matplotlib/tests/test_pickle.py b/lib/matplotlib/tests/test_pickle.py index de3b30cb5966..6d8d8f0f73ee 100644 --- a/lib/matplotlib/tests/test_pickle.py +++ b/lib/matplotlib/tests/test_pickle.py @@ -31,7 +31,7 @@ def test_simple(): # pickle.dump(ax, BytesIO(), pickle.HIGHEST_PROTOCOL) plt.figure() - plt.bar(left=np.arange(10), height=np.arange(10)) + plt.bar(x=np.arange(10), height=np.arange(10)) pickle.dump(plt.gca(), BytesIO(), pickle.HIGHEST_PROTOCOL) fig = plt.figure() From 5546eeefa8bcf8463646ad43f01d01ecd110e217 Mon Sep 17 00:00:00 2001 From: Thomas A Caswell Date: Sun, 27 Aug 2017 19:02:16 -0400 Subject: [PATCH 2/7] MNT: update pyplot.hist for changes to Axes.hist This change is from #8993 --- lib/matplotlib/pyplot.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/matplotlib/pyplot.py b/lib/matplotlib/pyplot.py index 6a8151889a49..7b46dc3179d4 100644 --- a/lib/matplotlib/pyplot.py +++ b/lib/matplotlib/pyplot.py @@ -2992,10 +2992,10 @@ def hexbin(x, y, C=None, gridsize=100, bins=None, xscale='linear', # This function was autogenerated by boilerplate.py. Do not edit as # changes will be lost @_autogen_docstring(Axes.hist) -def hist(x, bins=None, range=None, normed=False, weights=None, cumulative=False, +def hist(x, bins=None, range=None, density=None, weights=None, cumulative=False, bottom=None, histtype='bar', align='mid', orientation='vertical', rwidth=None, log=False, color=None, label=None, stacked=False, - hold=None, data=None, **kwargs): + normed=None, hold=None, data=None, **kwargs): ax = gca() # Deprecated: allow callers to override the hold state # by passing hold=True|False @@ -3007,11 +3007,11 @@ def hist(x, bins=None, range=None, normed=False, weights=None, cumulative=False, warnings.warn("The 'hold' keyword argument is deprecated since 2.0.", mplDeprecation) try: - ret = ax.hist(x, bins=bins, range=range, normed=normed, + ret = ax.hist(x, bins=bins, range=range, density=density, weights=weights, cumulative=cumulative, bottom=bottom, histtype=histtype, align=align, orientation=orientation, rwidth=rwidth, log=log, color=color, label=label, - stacked=stacked, data=data, **kwargs) + stacked=stacked, normed=normed, data=data, **kwargs) finally: ax._hold = washold From 5bb1c8a94401c196215252b17cdaaef7015988fa Mon Sep 17 00:00:00 2001 From: Thomas A Caswell Date: Sun, 27 Aug 2017 19:03:35 -0400 Subject: [PATCH 3/7] STY: whitespace fixes --- lib/matplotlib/__init__.py | 2 +- lib/matplotlib/testing/determinism.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/matplotlib/__init__.py b/lib/matplotlib/__init__.py index 1b8870f3a573..c025444e8780 100644 --- a/lib/matplotlib/__init__.py +++ b/lib/matplotlib/__init__.py @@ -1463,7 +1463,7 @@ def _replacer(data, key): def _preprocess_data(replace_names=None, replace_all_args=False, - label_namer=None, positional_parameter_names=None): + label_namer=None, positional_parameter_names=None): """ A decorator to add a 'data' kwarg to any a function. The signature of the input function must include the ax argument at the first position :: diff --git a/lib/matplotlib/testing/determinism.py b/lib/matplotlib/testing/determinism.py index 972df062075e..aca4572b2e5b 100644 --- a/lib/matplotlib/testing/determinism.py +++ b/lib/matplotlib/testing/determinism.py @@ -43,8 +43,8 @@ def _determinism_save(objects='mhi', format="pdf", usetex=False): if 'h' in objects: # also use different hatch patterns ax2 = fig.add_subplot(1, 6, 2) - bars = ax2.bar(range(1, 5), range(1, 5)) + \ - ax2.bar(range(1, 5), [6] * 4, bottom=range(1, 5)) + bars = (ax2.bar(range(1, 5), range(1, 5)) + + ax2.bar(range(1, 5), [6] * 4, bottom=range(1, 5))) ax2.set_xticks([1.5, 2.5, 3.5, 4.5]) patterns = ('-', '+', 'x', '\\', '*', 'o', 'O', '.') From 89c6a77a982493529cddd6ab90846c11636a662e Mon Sep 17 00:00:00 2001 From: Thomas A Caswell Date: Sun, 27 Aug 2017 23:17:32 -0400 Subject: [PATCH 4/7] DOC: tweak markup a bit --- lib/matplotlib/axes/_axes.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/matplotlib/axes/_axes.py b/lib/matplotlib/axes/_axes.py index bcbfae8837ab..5806a353a82e 100644 --- a/lib/matplotlib/axes/_axes.py +++ b/lib/matplotlib/axes/_axes.py @@ -1991,11 +1991,11 @@ def bar(self, *args, **kwargs): Notes ----- - The optional arguments `color`, `edgecolor`, `linewidth`, - `xerr`, and `yerr` can be either scalars or sequences of + The optional arguments *color*, *edgecolor*, *linewidth*, + *xerr*, and *yerr* can be either scalars or sequences of length equal to the number of bars. This enables you to use bar as the basis for stacked bar charts, or candlestick plots. - Detail: `xerr` and `yerr` are passed directly to + Detail: *xerr* and *yerr* are passed directly to :meth:`errorbar`, so they can also have shape 2xN for independent specification of lower and upper errors. @@ -2300,11 +2300,11 @@ def barh(self, *args, **kwargs): Notes ----- - The optional arguments `color`, `edgecolor`, `linewidth`, - `xerr`, and `yerr` can be either scalars or sequences of + The optional arguments *color*, *edgecolor*, *linewidth*, + *xerr*, and *yerr* can be either scalars or sequences of length equal to the number of bars. This enables you to use bar as the basis for stacked bar charts, or candlestick plots. - Detail: `xerr` and `yerr` are passed directly to + Detail: *xerr* and *yerr* are passed directly to :meth:`errorbar`, so they can also have shape 2xN for independent specification of lower and upper errors. From dd9c7b178e88ad862d24375bbaa5a15a56b02721 Mon Sep 17 00:00:00 2001 From: Thomas A Caswell Date: Sun, 27 Aug 2017 23:17:39 -0400 Subject: [PATCH 5/7] FIX: bug in docs inserted by _preprocess_data --- lib/matplotlib/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/matplotlib/__init__.py b/lib/matplotlib/__init__.py index c025444e8780..00488a134097 100644 --- a/lib/matplotlib/__init__.py +++ b/lib/matplotlib/__init__.py @@ -1720,7 +1720,7 @@ def inner(ax, *args, **kwargs): if len(replace_names) != 0: _repl = "* All arguments with the following names: '{names}'." if replace_all_args: - _repl += "\n* All positional arguments." + _repl += "\n * All positional arguments." _repl = _repl.format(names="', '".join(sorted(replace_names))) inner.__doc__ = (pre_doc + _DATA_DOC_APPENDIX.format(replaced=_repl)) From 80355e03d64e82b0d57fddd3c1e1e1756336092b Mon Sep 17 00:00:00 2001 From: Thomas A Caswell Date: Mon, 28 Aug 2017 15:20:27 -0400 Subject: [PATCH 6/7] DOC: add comment about use of lambdas to unpack args/kwrags credit goes to @anntzer --- lib/matplotlib/axes/_axes.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/matplotlib/axes/_axes.py b/lib/matplotlib/axes/_axes.py index 5806a353a82e..cfe861ca7299 100644 --- a/lib/matplotlib/axes/_axes.py +++ b/lib/matplotlib/axes/_axes.py @@ -2005,7 +2005,8 @@ def bar(self, *args, **kwargs): """ kwargs = cbook.normalize_kwargs(kwargs, mpatches._patch_alias_map) - + # this is using the lambdas to do the arg/kwarg unpacking rather + # than trying to re-implement all of that logic our selves. matchers = [ (lambda x, height, width=0.8, bottom=None, **kwargs: (False, x, height, width, bottom, kwargs)), @@ -2313,6 +2314,8 @@ def barh(self, *args, **kwargs): %(Rectangle)s """ + # this is using the lambdas to do the arg/kwarg unpacking rather + # than trying to re-implement all of that logic our selves. matchers = [ (lambda y, width, height=0.8, left=None, **kwargs: (False, y, width, height, left, kwargs)), From 7e1a65d2adb5e41e6f449560803916eff9260082 Mon Sep 17 00:00:00 2001 From: Thomas A Caswell Date: Mon, 28 Aug 2017 15:21:04 -0400 Subject: [PATCH 7/7] MNT: re-organize to simplify handling `None` as input --- lib/matplotlib/axes/_axes.py | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/lib/matplotlib/axes/_axes.py b/lib/matplotlib/axes/_axes.py index cfe861ca7299..402382587ccf 100644 --- a/lib/matplotlib/axes/_axes.py +++ b/lib/matplotlib/axes/_axes.py @@ -2061,23 +2061,29 @@ def bar(self, *args, **kwargs): label = kwargs.pop('label', '') tick_labels = kwargs.pop('tick_label', None) - _x = x - _y = y + adjust_ylim = False + adjust_xlim = False + + if orientation == 'vertical': + if y is None: + if self.get_yscale() == 'log': + adjust_ylim = True + y = 0 + + elif orientation == 'horizontal': + if x is None: + if self.get_xscale() == 'log': + adjust_xlim = True + x = 0 + x, height, width, y, linewidth = np.broadcast_arrays( # Make args iterable too. np.atleast_1d(x), height, width, y, linewidth) - adjust_ylim = False - adjust_xlim = False if orientation == 'vertical': self._process_unit_info(xdata=x, ydata=height, kwargs=kwargs) if log: self.set_yscale('log', nonposy='clip') - # size width and y according to length of x - if _y is None: - if self.get_yscale() == 'log': - adjust_ylim = True - y = np.zeros_like(y) tick_label_axis = self.xaxis tick_label_position = x @@ -2085,11 +2091,6 @@ def bar(self, *args, **kwargs): self._process_unit_info(xdata=width, ydata=y, kwargs=kwargs) if log: self.set_xscale('log', nonposx='clip') - # size x and height according to length of y - if _x is None: - if self.get_xscale() == 'log': - adjust_xlim = True - x = np.zeros_like(x) tick_label_axis = self.yaxis tick_label_position = y 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