3

My dataframe

df = pd.DataFrame({'date': ['2018-01-01', '2018-01-02', '2018-01-03', '2018-01-04', '2018-01-05'], 'b': ['a', 'a', 'b', 'b', 'c'], 'c': [1,2,3,4,5]})

         date  b  c
0  2018-01-01  a  1
1  2018-01-02  a  2
2  2018-01-03  b  3
3  2018-01-04  b  4
4  2018-01-05  c  5

I want to plot a line graph where X is date, y is c and the color of the line changes based on b. For this example there should be 3 different colors, the actual colors don't matter as long as their different.

I though this would work but it doesn't allow the change of color by column.

The output should be one line that changes color

Kenan
  • 13,156
  • 8
  • 43
  • 50

2 Answers2

6

You basically want to create a new series for each value in column b. One way to do that is to group on date and b and then unstack b, and the other method is to use pivot. Then just plot the result.

df.pivot(index='date', columns='b').droplevel(0, axis=1).plot(colors='rbc')  
# 'rbc' = ['red', 'blue', 'cyan'] 
# These colors are based on the column ordering, e.g. 'a', 'b', 'c'.

To be more explicit with the colors:

colors = {
    'a': 'red',
    'b': 'blue',
    'c': 'cyan'
}
(df
 .pivot(index='date', columns='b')
 .droplevel(0, axis=1)[colors.keys()]
 .plot(colors=colors.values())
)

enter image description here

Alexander
  • 105,104
  • 32
  • 201
  • 196
  • hmm....would there be a way to add a color mapping for the values of column `b`, like `{'a': 'red', 'b': 'blue', 'c': 'cyan'}` – Kenan Jan 21 '20 at 20:48
  • I don't think you can with a line chart. With a scatter plot, you can try something like `df.assign(days=df['date'].diff().dt.days.fillna(0).cumsum()).plot(kind='scatter', x='days', y='c', colors=df['b'].map({'a': 'red', 'b': 'blue', 'c': 'cyan'}))`. I am assuming here that the `date` column is timestamps rather than text. – Alexander Jan 21 '20 at 20:58
4

Let's try:

_, ax = plt.subplots()
df['date'] = pd.to_datetime(df['date'])
colors = {'a':'r', 'b':'b','c':'c'}
for n, g in df.groupby('b'):
     g.plot('date','c', marker='o', ax=ax, color=colors[n])

ax.legend()

Output:

enter image description here

Scott Boston
  • 147,308
  • 15
  • 139
  • 187