diff --git a/pandas/plotting/_matplotlib/style.py b/pandas/plotting/_matplotlib/style.py index 3e0954ef3d74d..b919728971505 100644 --- a/pandas/plotting/_matplotlib/style.py +++ b/pandas/plotting/_matplotlib/style.py @@ -56,29 +56,9 @@ def random_color(column): else: raise ValueError("color_type must be either 'default' or 'random'") - if isinstance(colors, str): - conv = matplotlib.colors.ColorConverter() - - def _maybe_valid_colors(colors): - try: - [conv.to_rgba(c) for c in colors] - return True - except ValueError: - return False - - # check whether the string can be convertible to single color - maybe_single_color = _maybe_valid_colors([colors]) - # check whether each character can be convertible to colors - maybe_color_cycle = _maybe_valid_colors(list(colors)) - if maybe_single_color and maybe_color_cycle and len(colors) > 1: - hex_color = [c["color"] for c in list(plt.rcParams["axes.prop_cycle"])] - colors = [hex_color[int(colors[1])]] - elif maybe_single_color: - colors = [colors] - else: - # ``colors`` is regarded as color cycle. - # mpl will raise error any of them is invalid - pass + if isinstance(colors, str) and _is_single_color(colors): + # GH #36972 + colors = [colors] # Append more colors by cycling if there is not enough color. # Extra colors will be ignored by matplotlib if there are more colors @@ -94,3 +74,33 @@ def _maybe_valid_colors(colors): colors += colors[:mod] return colors + + +def _is_single_color(color: str) -> bool: + """Check if ``color`` is a single color. + + Examples of single colors: + - 'r' + - 'g' + - 'red' + - 'green' + - 'C3' + + Parameters + ---------- + color : string + Color string. + + Returns + ------- + bool + True if ``color`` looks like a valid color. + False otherwise. + """ + conv = matplotlib.colors.ColorConverter() + try: + conv.to_rgba(color) + except ValueError: + return False + else: + return True diff --git a/pandas/tests/plotting/test_frame.py b/pandas/tests/plotting/test_frame.py index bdb86d2dd846f..74fbbf13e9597 100644 --- a/pandas/tests/plotting/test_frame.py +++ b/pandas/tests/plotting/test_frame.py @@ -170,10 +170,21 @@ def test_integer_array_plot(self): def test_mpl2_color_cycle_str(self): # GH 15516 - colors = ["C" + str(x) for x in range(10)] df = DataFrame(randn(10, 3), columns=["a", "b", "c"]) - for c in colors: - _check_plot_works(df.plot, color=c) + colors = ["C0", "C1", "C2", "C3", "C4", "C5", "C6", "C7", "C8", "C9"] + with warnings.catch_warnings(record=True) as w: + warnings.simplefilter("always", "MatplotlibDeprecationWarning") + + for color in colors: + _check_plot_works(df.plot, color=color) + + # if warning is raised, check that it is the exact problematic one + # GH 36972 + if w: + match = "Support for uppercase single-letter colors is deprecated" + warning_message = str(w[0].message) + msg = "MatplotlibDeprecationWarning related to CN colors was raised" + assert match not in warning_message, msg def test_color_single_series_list(self): # GH 3486