adr
adr

Reputation: 2071

Pandas bar chart with unequal groups

I have data with a hierarchical structure and want to create a plot with groups of bars.

import pandas as pd

data = [
 ['alpha', 'x', 1],
 ['alpha', 'y', 2],
 ['alpha', 'z', 2],
 ['beta', 'x', 3],
 ['beta', 'z', 4]]

df = pd.DataFrame(data, columns=['P','Q','R'])
df.pivot('P','Q','R').plot.bar(rot=0)

This code produces:

code output

How could I:

  1. Eliminate the space for the missing bar, i.e. accommodate groups with different numbers of bars?
  2. Make all the alphas blue and the betas orange, i.e. cycle the colors by group rather than within groups?

Upvotes: 2

Views: 1290

Answers (3)

Rohit Chauhan
Rohit Chauhan

Reputation: 1169

I am not sure to get rid of empty cells but you can use a stacked parameter to get the output and also yes you can pass the color array to bar method which will display color accordingly.

import pandas as pd

data = [
 ['alpha', 'x', 1],
 ['alpha', 'y', 2],
 ['alpha', 'z', 2],
 ['beta', 'x', 3],
 ['beta', 'z', 4]]

df =  pd.DataFrame(data, columns=['P','Q','R'])
df.pivot(index='P',columns='Q',values='R').plot.bar(rot=0, stacked=True,color = ['blue', 'green', 'red'])

enter image description here

I hope it helps.

Upvotes: 3

adr
adr

Reputation: 2071

This is inspired by @MattR's answer, which showed me that plotting bars from scratch is not rocket science. Pandas groupby() seems to be a good tool for this.

In the end I prefer it without extra space between groups.

    labels = []
    for g, grp in df.groupby('P'):
        plt.bar(grp.index, grp.R, label=g)
        labels.extend(grp.Q)
    plt.xticks(df.index, labels)
    plt.legend()

enter image description here

Upvotes: 1

MattR
MattR

Reputation: 5146

What if you create the plot "manually"? You can use loc to filter. Then plot on the same figure.

the magic for the space happens by using the index values. notice in beta I add +1 to the index to create that extra space. I then combine both indexes in xticks and then simply use df['Q'] as the labels.

plt.bar(data=df.loc[df['P']=='alpha'], x=df.loc[df['P']=='alpha'].index, height='R', label='alpha')
plt.bar(data=df.loc[df['P']=='beta'], x=df.loc[df['P']=='beta'].index+1, height='R', label='beta')
plt.xticks(df.loc[df['P']=='alpha'].index.tolist() + list(df.loc[df['P']=='beta'].index+1),df['Q'].tolist())

plt.legend()

enter image description here

Upvotes: 2

Related Questions