diff --git a/doc/source/whatsnew/v0.24.0.rst b/doc/source/whatsnew/v0.24.0.rst index ce629816a14c3..067f2e08ce72e 100644 --- a/doc/source/whatsnew/v0.24.0.rst +++ b/doc/source/whatsnew/v0.24.0.rst @@ -1595,6 +1595,7 @@ Plotting - Bug in :func:`DataFrame.plot.scatter` and :func:`DataFrame.plot.hexbin` caused x-axis label and ticklabels to disappear when colorbar was on in IPython inline backend (:issue:`10611`, :issue:`10678`, and :issue:`20455`) - Bug in plotting a Series with datetimes using :func:`matplotlib.axes.Axes.scatter` (:issue:`22039`) +- Bug in validating color parameter caused extra color to be appended to the given color array. This happened to multiple plotting functions using matplotlib. (:issue:`20726`) Groupby/Resample/Rolling ^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/pandas/plotting/_style.py b/pandas/plotting/_style.py index 930c3d1775ad8..d50fa48c92cf5 100644 --- a/pandas/plotting/_style.py +++ b/pandas/plotting/_style.py @@ -81,7 +81,10 @@ def _maybe_valid_colors(colors): # mpl will raise error any of them is invalid pass - if len(colors) != num_colors: + # Append more colors by cycling if there is not enough color. + # Extra colors will be ignored by matplotlib if there are more colors + # than needed and nothing needs to be done here. + if len(colors) < num_colors: try: multiple = num_colors // len(colors) - 1 except ZeroDivisionError: diff --git a/pandas/tests/plotting/test_misc.py b/pandas/tests/plotting/test_misc.py index 9ae3e7fc423f4..5d9ece09c9dcc 100644 --- a/pandas/tests/plotting/test_misc.py +++ b/pandas/tests/plotting/test_misc.py @@ -309,3 +309,21 @@ def test_get_standard_colors_random_seed(self): color1 = _get_standard_colors(1, color_type='random') color2 = _get_standard_colors(1, color_type='random') assert color1 == color2 + + def test_get_standard_colors_no_appending(self): + # GH20726 + + # Make sure not to add more colors so that matplotlib can cycle + # correctly. + from matplotlib import cm + color_before = cm.gnuplot(range(5)) + color_after = plotting._style._get_standard_colors( + 1, color=color_before) + assert len(color_after) == len(color_before) + + df = DataFrame(np.random.randn(48, 4), columns=list("ABCD")) + + color_list = cm.gnuplot(np.linspace(0, 1, 16)) + p = df.A.plot.bar(figsize=(16, 7), color=color_list) + assert (p.patches[1].get_facecolor() + == p.patches[17].get_facecolor())