diff --git a/pandas/plotting/_matplotlib/core.py b/pandas/plotting/_matplotlib/core.py index 57caa05048a60..ed2bec76f6ebd 100644 --- a/pandas/plotting/_matplotlib/core.py +++ b/pandas/plotting/_matplotlib/core.py @@ -1663,17 +1663,26 @@ def _kind(self) -> Literal["bar", "barh"]: def orientation(self) -> PlottingOrientation: return "vertical" - def __init__(self, data, **kwargs) -> None: + def __init__( + self, + data, + *, + align="center", + bottom=0, + left=0, + width=0.5, + position=0.5, + log=False, + **kwargs, + ) -> None: # we have to treat a series differently than a # 1-column DataFrame w.r.t. color handling self._is_series = isinstance(data, ABCSeries) - self.bar_width = kwargs.pop("width", 0.5) - pos = kwargs.pop("position", 0.5) - kwargs.setdefault("align", "center") + self.bar_width = width + self._align = align + self._position = position self.tick_pos = np.arange(len(data)) - bottom = kwargs.pop("bottom", 0) - left = kwargs.pop("left", 0) if is_list_like(bottom): bottom = np.array(bottom) if is_list_like(left): @@ -1681,24 +1690,36 @@ def __init__(self, data, **kwargs) -> None: self.bottom = bottom self.left = left - self.log = kwargs.pop("log", False) + self.log = log + MPLPlot.__init__(self, data, **kwargs) + @cache_readonly + def ax_pos(self) -> np.ndarray: + return self.tick_pos - self.tickoffset + + @cache_readonly + def tickoffset(self): if self.stacked or self.subplots: - self.tickoffset = self.bar_width * pos - if kwargs["align"] == "edge": - self.lim_offset = self.bar_width / 2 - else: - self.lim_offset = 0 - elif kwargs["align"] == "edge": + return self.bar_width * self._position + elif self._align == "edge": w = self.bar_width / self.nseries - self.tickoffset = self.bar_width * (pos - 0.5) + w * 0.5 - self.lim_offset = w * 0.5 + return self.bar_width * (self._position - 0.5) + w * 0.5 else: - self.tickoffset = self.bar_width * pos - self.lim_offset = 0 + return self.bar_width * self._position - self.ax_pos = self.tick_pos - self.tickoffset + @cache_readonly + def lim_offset(self): + if self.stacked or self.subplots: + if self._align == "edge": + return self.bar_width / 2 + else: + return 0 + elif self._align == "edge": + w = self.bar_width / self.nseries + return w * 0.5 + else: + return 0 # error: Signature of "_plot" incompatible with supertype "MPLPlot" @classmethod @@ -1749,6 +1770,7 @@ def _make_plot(self, fig: Figure) -> None: start = 1 start = start + self._start_base + kwds["align"] = self._align if self.subplots: w = self.bar_width / 2 rect = self._plot(