From d2c80bc2dcbae1f72a836d26a88fab4d0a50854f Mon Sep 17 00:00:00 2001 From: Zachary Moon Date: Tue, 1 Nov 2022 12:38:00 -0600 Subject: [PATCH] Backport PR #49377: BUG: Fix passing `Colormap` instance to plot methods with mpl >= 3.6 --- doc/source/whatsnew/v1.5.2.rst | 2 ++ pandas/io/formats/style.py | 10 +++++++++- pandas/plotting/_matplotlib/core.py | 4 ++-- pandas/tests/io/formats/style/test_matplotlib.py | 14 ++++++++++++++ 4 files changed, 27 insertions(+), 3 deletions(-) diff --git a/doc/source/whatsnew/v1.5.2.rst b/doc/source/whatsnew/v1.5.2.rst index 4f6274b9084da..c95f563a77708 100644 --- a/doc/source/whatsnew/v1.5.2.rst +++ b/doc/source/whatsnew/v1.5.2.rst @@ -14,6 +14,8 @@ including other versions of pandas. Fixed regressions ~~~~~~~~~~~~~~~~~ - Fixed regression in :meth:`Series.replace` raising ``RecursionError`` with numeric dtype and when specifying ``value=None`` (:issue:`45725`) +- Fixed regression in :meth:`DataFrame.plot` preventing :class:`~matplotlib.colors.Colormap` instance + from being passed using the ``colormap`` argument if Matplotlib 3.6+ is used (:issue:`49374`) - .. --------------------------------------------------------------------------- diff --git a/pandas/io/formats/style.py b/pandas/io/formats/style.py index 9c3e4f0bb02fb..d1baaebf6c204 100644 --- a/pandas/io/formats/style.py +++ b/pandas/io/formats/style.py @@ -3927,7 +3927,15 @@ def _background_gradient( rng = smax - smin # extend lower / upper bounds, compresses color range norm = mpl.colors.Normalize(smin - (rng * low), smax + (rng * high)) - rgbas = plt.cm.get_cmap(cmap)(norm(gmap)) + from pandas.plotting._matplotlib.compat import mpl_ge_3_6_0 + + if mpl_ge_3_6_0(): + if cmap is None: + rgbas = mpl.colormaps[mpl.rcParams["image.cmap"]](norm(gmap)) + else: + rgbas = mpl.colormaps.get_cmap(cmap)(norm(gmap)) + else: + rgbas = plt.cm.get_cmap(cmap)(norm(gmap)) def relative_luminance(rgba) -> float: """ diff --git a/pandas/plotting/_matplotlib/core.py b/pandas/plotting/_matplotlib/core.py index 1302413916d58..af91a8ab83e12 100644 --- a/pandas/plotting/_matplotlib/core.py +++ b/pandas/plotting/_matplotlib/core.py @@ -1222,7 +1222,7 @@ def _make_plot(self): if self.colormap is not None: if mpl_ge_3_6_0(): - cmap = mpl.colormaps[self.colormap] + cmap = mpl.colormaps.get_cmap(self.colormap) else: cmap = self.plt.cm.get_cmap(self.colormap) else: @@ -1302,7 +1302,7 @@ def _make_plot(self): # pandas uses colormap, matplotlib uses cmap. cmap = self.colormap or "BuGn" if mpl_ge_3_6_0(): - cmap = mpl.colormaps[cmap] + cmap = mpl.colormaps.get_cmap(cmap) else: cmap = self.plt.cm.get_cmap(cmap) cb = self.kwds.pop("colorbar", True) diff --git a/pandas/tests/io/formats/style/test_matplotlib.py b/pandas/tests/io/formats/style/test_matplotlib.py index 8d9f075d8674d..52fd5355e3302 100644 --- a/pandas/tests/io/formats/style/test_matplotlib.py +++ b/pandas/tests/io/formats/style/test_matplotlib.py @@ -284,3 +284,17 @@ def test_bar_color_raises(df): msg = "`color` and `cmap` cannot both be given" with pytest.raises(ValueError, match=msg): df.style.bar(color="something", cmap="something else").to_html() + + +@pytest.mark.parametrize( + "plot_method", + ["scatter", "hexbin"], +) +def test_pass_colormap_instance(df, plot_method): + # https://github.com/pandas-dev/pandas/issues/49374 + cmap = mpl.colors.ListedColormap([[1, 1, 1], [0, 0, 0]]) + df["c"] = df.A + df.B + kwargs = dict(x="A", y="B", c="c", colormap=cmap) + if plot_method == "hexbin": + kwargs["C"] = kwargs.pop("c") + getattr(df.plot, plot_method)(**kwargs)