ENH/BUG: color cannot be applied to line subplots
State: closed

Specifying `subplots=True` in line and kde plot draws all lines in black, and may not accept colors and styles keyword. Summarized a table to compare current / expected (fixed) behaviour.

Sample data:

```
df = pd.DataFrame(np.random.randn(10, 3))
```

| Command | Current Behavior | Expected Behavior |
| --- | --- | --- |
| `df.plot(subplots=True)` | All 3 lines are in black (OK) | 3 lines are in default color cycle. |
| `df.plot(style='r', subplots=True)` | All 3 lines are in red (OK) | No change |
| `df.plot(color='r', subplots=True)` | All 3 lines are in red (OK) | No change |
| `df.plot(color='red', subplots=True)` | All 3 lines are in red (OK) (thanks to #10387) | No change |
| `df.plot(color=['r', 'g', 'b'], subplots=True)` | ValueError: to_rgba: Invalid rgba arg "['r', 'g', 'b']" (NG) | 3 lines are drawn in red, green, blue |
| `df.plot(style=['r', 'g', 'b'], subplots=True)` | 3 lines are drawn in red, green, blue (OK) | No change |


Labels:
name: Visualization
description: plotting

Comments:
I think the first one `df.plot(subplots=True)` giving all black lines is not really logical. I know it is like now, but maybe we should change that to follow just the default rcParam settings as for other plots? I don't think there is a reason to make them black compared to a normal `df.plot()`

Yeah, +1 to change the default, but should wait for v0.17 as API change?

Updated to use default colors for subplots.

@jorisvandenbossche , @TomAugspurger Could you check this? Intend to use the fix in another PR.

@TomAugspurger Can you take a look?

Only had a chance for a quick look. Nothing looks wrong so I'd day merge it so you can get your other PR going.

> On Jun 16, 2015, at 17:00, Sinhrks notifications@github.com wrote:
> 
> @TomAugspurger Can you take a look?
> 
> —
> Reply to this email directly or view it on GitHub.

Looks good, just one question: how does a single color get handled when having multiple columns to plot? So eg `color='green'` instead of `color='rgcby'`. As on first sight, I don't see this case in the tests.

@jorisvandenbossche Thanks, good catch. How should we handle string represents a single color for multiple lines? Current master regard it as color cycle, and raises `ValueError`. I think options are:
- Make error message better
- Retry regarding the passed str as single color once we catch `ValueError`

```
df = pd.DataFrame(np.random.randn(3, 3))
df[0].plot(color='green')
# single green line

df.plot(color=['green'])
# triple green lines

df.plot(color='green')
# ValueError: to_rgba: Invalid rgba arg "e"
```

I'd say try to make the error message better. Really `color='cgy'` should be `color=['c', 'g', 'y']`, but I think that is too big a change.

Or have a try and fallback approach? And only if both fail, give an error? The only question then is what should be tried first.

Or how about we always try both, and we raise if they both _succeed_?

@TomAugspurger Yeah raise when both succeed / both fail sounds good. If no objections, I'll prepare a separate PR to fix this first using [`mpl.colors.ColorConverter`](http://matplotlib.org/api/colors_api.html#matplotlib.colors.ColorConverter).

```
import matplotlib.colors as colors 

colors.ColorConverter().to_rgba('g')
# (0.0, 0.5, 0.0, 1.0)

# should confirm whether it must be identical with 'g'
colors.ColorConverter().to_rgba('green')
# (0.0, 0.5019607843137255, 0.0, 1.0)

colors.ColorConverter().to_rgba('invalid')
# ValueError: to_rgba: Invalid rgba arg "invalid"
```

Yep, sounds good to me. Only remark: what can the user do if this raises, but it _is_ what he/she wants to use? Eg a color name that exists of only characters that also represent a color as single character (I don't know if such a name exists ..) and that is as long as the number of columns. You want to give this a single color, but it raises -> what to do to solve this? (apart from specifying the color as rgba values)

Oh... I didn't think about that :) I suppose we could _warn_, go with one, and tell the user to use `colors=['green']` or `colors=['g', 'r', 'e', 'e', 'n']` if that's what the want.

I really do wonder if there are any matplotlib colors that are valid in either form... Maybe we're worying about nothing ;)

Ah, no, I didn't think of `colors=['green']`. So it is always possible to unambiguously specify it. So then the error message can contain this message to specify one of the two alternatives.

How about raising _"xxx" can be parsed as both single color and color cycle. Specify each color using list'_

Also, there looks no str expression which can be parsed as both for now (thus can't test raise?).
- http://matplotlib.org/examples/color/named_colors.html

Or it can be even more specific, expanding a little bit: `"xxx" can be parsed as both single color and color cycle. Specify each color using a list like ["xxx"] or ["x", "x", "x"] "`

Revisit after #10387.

this can be revisited now since  #10387 is merged

Rebased and added single color string tests.

@sinhrks Can you update the table in the top post? As it is not fully clear anymore if this is the final behaviour we decided upon

From the tests, I understand that the behaviour of `df.plot(subplots=True)` (previously: "All 3 lines are in black") is now: 3 lines follow default cycle, which would be "blue, green, red" with default settings. 
But, I think it should be "all 3 lines are blue" ? (as it is each time the first line for each subplot)

Based on the current bar plot, the nth color is corresponding to the nth column. I think this spec is ok, otherwise we have no means to use separate colors for each lines / bars?

```
df = pd.DataFrame({'A': [1, 2, 3 ,4], 'B': [5, 6, 7, 8]})
df.plot(color=['r', 'g'], subplots=True, kind='bar')
```

![figure_1](https://cloud.githubusercontent.com/assets/1696302/8522326/cd6d8f4e-2427-11e5-85ee-5e94c678305c.png)

@jorisvandenbossche @TomAugspurger OK for this?

What I meant is that in the following:

```
df = pd.DataFrame({'A': [1, 2, 3 ,4], 'B': [5, 6, 7, 8]})
df.plot(subplots=True)
```

(which now gives all black lines) I would expect here blue lines in each subplot, as for each subplot it is the first line to plot. And that does not conflict with giving it a special color through `df.plot(subplots=True, color=['r', 'g'])`. 
But, if it is already the behaviour with barplots to use different colors for each subplot, then I am OK with that to do that for the line plots as well.

Yes, bar plot uses default color cycle (separate colors) if color is not specified and `subplots=True`.

Let me merge this once the test has been passed, assuming there is no further feedback.