From ac2bfb74aac251ae6ece69eb63fc30be8ce95d43 Mon Sep 17 00:00:00 2001 From: Atul Aggarwal Date: Tue, 21 Aug 2018 15:59:43 +0530 Subject: [PATCH 1/3] Fixing _get_standard_colors to honor num_colors arguments (#20585) --- pandas/plotting/_core.py | 10 ++++++++++ pandas/plotting/_style.py | 4 +++- pandas/tests/plotting/test_series.py | 29 ++++++++++++++++++++++++++++ 3 files changed, 42 insertions(+), 1 deletion(-) diff --git a/pandas/plotting/_core.py b/pandas/plotting/_core.py index 4fa3b51c60ee4..0f3108164c46f 100644 --- a/pandas/plotting/_core.py +++ b/pandas/plotting/_core.py @@ -1233,6 +1233,16 @@ def _plot(cls, ax, x, y, w, start=0, log=False, **kwds): def _start_base(self): return self.bottom + def _get_colors(self, num_colors=None, color_kwds='color'): + color = self.kwds.get(color_kwds) + if color is not None: + return color + else : + num_colors = self.nseries + return _get_standard_colors(num_colors=num_colors, + colormap=self.colormap, + color=self.kwds.get(color_kwds)) + def _make_plot(self): import matplotlib as mpl diff --git a/pandas/plotting/_style.py b/pandas/plotting/_style.py index c72e092c73aa2..de90d51aa933d 100644 --- a/pandas/plotting/_style.py +++ b/pandas/plotting/_style.py @@ -91,7 +91,9 @@ def _maybe_valid_colors(colors): # mpl will raise error any of them is invalid pass - if len(colors) != num_colors: + if len(colors) > num_colors: + colors = colors[:num_colors] + elif len(colors) < num_colors: try: multiple = num_colors // len(colors) - 1 except ZeroDivisionError: diff --git a/pandas/tests/plotting/test_series.py b/pandas/tests/plotting/test_series.py index 5dc7d52e05778..ad79daa242885 100644 --- a/pandas/tests/plotting/test_series.py +++ b/pandas/tests/plotting/test_series.py @@ -21,6 +21,7 @@ from pandas.tests.plotting.common import (TestPlotBase, _check_plot_works, _skip_if_no_scipy_gaussian_kde, _ok_for_gaussian_kde) +from pandas.plotting._style import _get_standard_colors @td.skip_if_no_mpl @@ -268,6 +269,34 @@ def test_bar_user_colors(self): (1., 0., 0., 1.)] assert result == expected + def test_bar_user_colors_limited(self): + s = Series([1, 2, 3, 4]) + ax = s.plot.bar(color=['red', 'blue']) + result = [p.get_facecolor() for p in ax.patches] + expected = [(1., 0., 0., 1.), + (0., 0., 1., 1.), + (1., 0., 0., 1.), + (0., 0., 1., 1.)] + assert result == expected + + def test_bar_user_colors_more_limited(self): + s = Series([1, 2, 3, 4, 5, 6]) + ax = s.plot.bar(color=['red', 'blue']) + result = [p.get_facecolor() for p in ax.patches] + expected = [(1., 0., 0., 1.), + (0., 0., 1., 1.), + (1., 0., 0., 1.), + (0., 0., 1., 1.), + (1., 0., 0., 1.), + (0., 0., 1., 1.)] + assert result == expected + + @pytest.mark.parametrize("num_colors", range(0,15)) + def test_standard_color(self, num_colors): + colors = _get_standard_colors(num_colors=num_colors) + + assert len(colors) == num_colors + def test_rotation(self): df = DataFrame(randn(5, 5)) # Default rot 0 From 8265f9404ff0e79ab79becdf51b438e7b2c2746b Mon Sep 17 00:00:00 2001 From: Atul Aggarwal Date: Tue, 21 Aug 2018 16:02:55 +0530 Subject: [PATCH 2/3] Fixng PEP issues reported (#20585) --- pandas/plotting/_core.py | 2 +- pandas/tests/plotting/test_series.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pandas/plotting/_core.py b/pandas/plotting/_core.py index 0f3108164c46f..0d4a485e52d68 100644 --- a/pandas/plotting/_core.py +++ b/pandas/plotting/_core.py @@ -1237,7 +1237,7 @@ def _get_colors(self, num_colors=None, color_kwds='color'): color = self.kwds.get(color_kwds) if color is not None: return color - else : + else: num_colors = self.nseries return _get_standard_colors(num_colors=num_colors, colormap=self.colormap, diff --git a/pandas/tests/plotting/test_series.py b/pandas/tests/plotting/test_series.py index ad79daa242885..f322421f2a157 100644 --- a/pandas/tests/plotting/test_series.py +++ b/pandas/tests/plotting/test_series.py @@ -291,7 +291,7 @@ def test_bar_user_colors_more_limited(self): (0., 0., 1., 1.)] assert result == expected - @pytest.mark.parametrize("num_colors", range(0,15)) + @pytest.mark.parametrize("num_colors",range(0,15)) def test_standard_color(self, num_colors): colors = _get_standard_colors(num_colors=num_colors) From a52582ab7c15eed012fbf874a4c527051e08ff37 Mon Sep 17 00:00:00 2001 From: Atul Aggarwal Date: Tue, 21 Aug 2018 16:27:39 +0530 Subject: [PATCH 3/3] Adding whatsnew and issue reference in test (#20585) --- doc/source/whatsnew/v0.24.0.txt | 1 + pandas/tests/plotting/test_series.py | 2 ++ 2 files changed, 3 insertions(+) diff --git a/doc/source/whatsnew/v0.24.0.txt b/doc/source/whatsnew/v0.24.0.txt index d7feb6e547b22..e363c77710d70 100644 --- a/doc/source/whatsnew/v0.24.0.txt +++ b/doc/source/whatsnew/v0.24.0.txt @@ -683,6 +683,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 colors selection in :func:`DataFrame.plot.bar` which causes different colors to be used when no color is specified (:issue:`20585`) Groupby/Resample/Rolling ^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/pandas/tests/plotting/test_series.py b/pandas/tests/plotting/test_series.py index f322421f2a157..6c15f2101c009 100644 --- a/pandas/tests/plotting/test_series.py +++ b/pandas/tests/plotting/test_series.py @@ -270,6 +270,7 @@ def test_bar_user_colors(self): assert result == expected def test_bar_user_colors_limited(self): + # GH 20585 s = Series([1, 2, 3, 4]) ax = s.plot.bar(color=['red', 'blue']) result = [p.get_facecolor() for p in ax.patches] @@ -293,6 +294,7 @@ def test_bar_user_colors_more_limited(self): @pytest.mark.parametrize("num_colors",range(0,15)) def test_standard_color(self, num_colors): + # GH 20585 colors = _get_standard_colors(num_colors=num_colors) assert len(colors) == num_colors