Set colors in stacked bar plot per label

2019-07-25 00:22发布

I want to set the same colors pop up each time I run this barplot. For example: B1 = green, B2, red, B3 = blue etc.

I have so far tried .setcolor but it does not provide me to set the colors for individual box numbers (B1, B2 etc) -- I could not figure it out.

import pandas as pd
import seaborn as sns


d = {'DAY': [55,56,58,65], 'B1': [2,6,6,1],  'B2': [1,0,21,0], 'B3': [0,1,0,1]}
data1= pd.DataFrame(data = d)

sns.set()
data1.set_index('DAY').plot(kind='bar', stacked=True)

enter image description here

This works, but it assigns different colors for B1, B2, B3 etc. once I have new data..

For example, let us give it some toy data:

t = {'DAY': [55,56,58,65], 'B1': [2,6,6,1],  'B3': [0,1,0,1]}
toy1= pd.DataFrame(data = t)
sns.set()
toy1.set_index('DAY').plot(kind='bar', stacked=True)

enter image description here

B3 is orange here, whereas it was green in the first one.

1条回答
ゆ 、 Hurt°
2楼-- · 2019-07-25 00:59

Create a dictionary and map the columns to those colors. Because we iterate over the columns, the colors will be in the same order the columns are plotted. You will need to define colors for all of your different columns.

def gen_colors(df):
    col_d = {'B1': 'red', 'B2': 'black', 'B3': 'green'}
    return [col_d[col] for col in df.columns if 'B' in col]

sns.set()

d = {'DAY': [55,56,58,65], 'B1': [2,6,6,1],  'B2': [1,0,21,0], 'B3': [0,1,0,1]}
data1 = pd.DataFrame(data = d)
data1.set_index('DAY').plot(kind='bar', stacked=True, color=gen_colors(data1))

enter image description here

t = {'DAY': [55,56,58,65], 'B1': [2,6,6,1],  'B3': [0,1,0,1]}
toy1 = pd.DataFrame(data = t)
toy1.set_index('DAY').plot(kind='bar', stacked=True, color=gen_colors(toy1))

enter image description here


This, however, does not ensure that the ordering is consistent. That is, if your DataFrame is ordered differently, though B3 will always be the same color, it may wind up being above or below B1 when stacked. A more consistent solution is to reindex. You must include all Bi that are found across all of your DataFrames that need to be plotted consistently. Here I chose an arbitrarily large number of 1-9:

t = {'DAY': [55,56,58,65], 'B3': [0,1,0,1], 'B1': [2,6,6,1]}
toy1 = pd.DataFrame(data = t)

toy1 = toy1.reindex(['DAY'] + [f'B{i}' for i in range(1,10)], axis=1)
toy1.set_index('DAY').plot(kind='bar', stacked=True)

enter image description here

Though B3 appears first in the DataFrame, it was still plotted above B1, and with the third color in the cycle.

查看更多
登录 后发表回答