From 728cca32af37ef6e9236e587c759198c89ab9299 Mon Sep 17 00:00:00 2001 From: Oscar Gustafsson Date: Sun, 3 Apr 2022 15:04:28 +0200 Subject: [PATCH] Refactor hist for less numerical errors --- lib/matplotlib/axes/_axes.py | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/lib/matplotlib/axes/_axes.py b/lib/matplotlib/axes/_axes.py index f1ec9406ea6b..c3c61c122bc7 100644 --- a/lib/matplotlib/axes/_axes.py +++ b/lib/matplotlib/axes/_axes.py @@ -6633,7 +6633,11 @@ def hist(self, x, bins=None, range=None, density=False, weights=None, if histtype.startswith('bar'): - totwidth = np.diff(bins) + def _get_boffset(boffset): + if np.any(boffset): + return np.diff(boffset) + else: + return 0.0 if rwidth is not None: dr = np.clip(rwidth, 0, 1) @@ -6644,17 +6648,17 @@ def hist(self, x, bins=None, range=None, density=False, weights=None, dr = 1.0 if histtype == 'bar' and not stacked: - width = dr * totwidth / nx - dw = width - boffset = -0.5 * dr * totwidth * (1 - 1 / nx) + starts = dr * bins / nx + dw = starts + boffset = -0.5 * dr * bins * (1 - 1 / nx) elif histtype == 'barstacked' or stacked: - width = dr * totwidth + starts = dr * bins boffset, dw = 0.0, 0.0 if align == 'mid': - boffset += 0.5 * totwidth + boffset += 0.5 * bins elif align == 'right': - boffset += totwidth + boffset += bins if orientation == 'horizontal': _barfunc = self.barh @@ -6663,6 +6667,8 @@ def hist(self, x, bins=None, range=None, density=False, weights=None, _barfunc = self.bar bottom_kwarg = 'bottom' + width = np.diff(starts) + for m, c in zip(tops, color): if bottom is None: bottom = np.zeros(len(m)) @@ -6670,8 +6676,8 @@ def hist(self, x, bins=None, range=None, density=False, weights=None, height = m - bottom else: height = m - bars = _barfunc(bins[:-1]+boffset, height, width, - align='center', log=log, + bars = _barfunc(bins[:-1] + _get_boffset(boffset), height, + width, align='center', log=log, color=c, **{bottom_kwarg: bottom}) patches.append(bars) if stacked: