Skip to content

Commit 9a999fe

Browse files
LeostaynerMarco Gorelli
authored and
Marco Gorelli
committed
Fixes issue pandas-dev#8193
1 parent b529857 commit 9a999fe

File tree

4 files changed

+33
-3
lines changed

4 files changed

+33
-3
lines changed

doc/source/whatsnew/v1.0.0.rst

+1
Original file line numberDiff line numberDiff line change
@@ -1110,6 +1110,7 @@ Plotting
11101110
- Bug in color validation incorrectly raising for non-color styles (:issue:`29122`).
11111111
- Allow :meth:`DataFrame.plot.scatter` to plot ``objects`` and ``datetime`` type data (:issue:`18755`, :issue:`30391`)
11121112
- Bug in :meth:`DataFrame.hist`, ``xrot=0`` does not work with ``by`` and subplots (:issue:`30288`).
1113+
- :func:`.plot` for line/bar now accepts color by dictonary (:issue:`8193`).
11131114

11141115
Groupby/resample/rolling
11151116
^^^^^^^^^^^^^^^^^^^^^^^^

pandas/plotting/_matplotlib/core.py

+6-2
Original file line numberDiff line numberDiff line change
@@ -726,7 +726,10 @@ def _apply_style_colors(self, colors, kwds, col_num, label):
726726
has_color = "color" in kwds or self.colormap is not None
727727
nocolor_style = style is None or re.match("[a-z]+", style) is None
728728
if (has_color or self.subplots) and nocolor_style:
729-
kwds["color"] = colors[col_num % len(colors)]
729+
if isinstance(colors, dict):
730+
kwds["color"] = colors[label]
731+
else:
732+
kwds["color"] = colors[col_num % len(colors)]
730733
return style, kwds
731734

732735
def _get_colors(self, num_colors=None, color_kwds="color"):
@@ -1341,12 +1344,13 @@ def _make_plot(self):
13411344

13421345
pos_prior = neg_prior = np.zeros(len(self.data))
13431346
K = self.nseries
1344-
13451347
for i, (label, y) in enumerate(self._iter_data(fillna=0)):
13461348
ax = self._get_ax(i)
13471349
kwds = self.kwds.copy()
13481350
if self._is_series:
13491351
kwds["color"] = colors
1352+
elif isinstance(colors, dict):
1353+
kwds["color"] = colors[label]
13501354
else:
13511355
kwds["color"] = colors[i % ncolors]
13521356

pandas/plotting/_matplotlib/style.py

+5-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,11 @@ def _get_standard_colors(
2727
warnings.warn(
2828
"'color' and 'colormap' cannot be used simultaneously. Using 'color'"
2929
)
30-
colors = list(color) if is_list_like(color) else color
30+
colors = (
31+
list(color)
32+
if is_list_like(color) and not isinstance(color, dict)
33+
else color
34+
)
3135
else:
3236
if color_type == "default":
3337
# need to call list() on the result to copy so we don't

pandas/tests/plotting/test_misc.py

+21
Original file line numberDiff line numberDiff line change
@@ -406,3 +406,24 @@ def test_get_standard_colors_no_appending(self):
406406
color_list = cm.gnuplot(np.linspace(0, 1, 16))
407407
p = df.A.plot.bar(figsize=(16, 7), color=color_list)
408408
assert p.patches[1].get_facecolor() == p.patches[17].get_facecolor()
409+
410+
@pytest.mark.slow
411+
def test_dictionary_color(self):
412+
# issue-8193
413+
# Test plot color dictionary format
414+
data_files = ["a", "b"]
415+
416+
expected = [(0.5, 0.24, 0.6), (0.3, 0.7, 0.7)]
417+
418+
df1 = DataFrame(np.random.rand(2, 2), columns=data_files)
419+
dic_color = {"b": (0.3, 0.7, 0.7), "a": (0.5, 0.24, 0.6)}
420+
421+
# Bar color test
422+
ax = df1.plot(kind="bar", color=dic_color)
423+
colors = [rect.get_facecolor()[0:-1] for rect in ax.get_children()[0:3:2]]
424+
assert all(color == expected[index] for index, color in enumerate(colors))
425+
426+
# Line color test
427+
ax = df1.plot(kind="line", color=dic_color)
428+
colors = [rect.get_color() for rect in ax.get_lines()[0:2]]
429+
assert all(color == expected[index] for index, color in enumerate(colors))

0 commit comments

Comments
 (0)