3

to describe my problem i am providing you with small dataset as an example: so imagine following dataset:

import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
df = pd.DataFrame({'name':['a', 'b', 'c', 'a', 'b', 'c'], 'val':[1,5,3,4,5,3]} )

I am creating simple histogam with following code:

def plot_bar_x():
    index = np.arange(len(df['name']))
    plt.bar(index, df['val'])
    plt.legend(list(df['name'].unique()))
    plt.xticks(index, df['name'], fontsize=10, rotation=30)
    plt.show()
plot_bar_x()

But it gives me following plot: enter image description here

Although I have 3 unique names but i see only 'a' label, however i used this line: plt.legend(list(df['name'].unique())) the other issue is that all the bars are in the same color, is there a way to get different colors for unique labels without defining colors beforehand manually?

desired output is:

enter image description here

Sascha
  • 687
  • 1
  • 8
  • 22

2 Answers2

1

You only plot once on one series, that's why plt only picks one label for legend. If you don't have a lot of names, try:

def plot_bar_x():
    index = np.arange(len(df['name']))
    plt.figure()
    for name in df.name.unique():
        tmp_df = df[df.name == name]
        plt.bar(tmp_df.index, tmp_df.val, label=name)
    plt.xticks(index, df['name'], fontsize=10, rotation=30)
    plt.legend()
    plt.show()

There must be some clever way to solve your problem, but it's over my head now.

Quang Hoang
  • 146,074
  • 10
  • 56
  • 74
1

You can directly plot the DataFrame using df.plot() and then pass the colors of each bar using some predefined dictionary. Then you can create legends using mpatches.Patch as shown here. You can use seaborn to have the grayish background with grids. The colors can be generated depending on the number of unique items in the DataFrame.

import matplotlib.pyplot as plt
import matplotlib.patches as mpatches
import pandas as pd
import numpy as np; np.random.seed(123)
import seaborn as sns
sns.set()

df = pd.DataFrame({'name':['a', 'b', 'c', 'a', 'b', 'c'], 'val':[1,5,3,4,5,3]} )
col_dict = {k:np.random.rand(3,) for k in df['name'].unique()}

ax = df.plot.bar(x='name', y='val', color=[col_dict[i] for i in df['name']])
labels = [mpatches.Patch(color=v, label=k) for k,v in col_dict.items()]
plt.legend(handles=labels, loc='best')    
plt.show()

enter image description here

Sheldore
  • 37,862
  • 7
  • 57
  • 71