Home > Software design >  Show only one level of index as xticks in barplot
Show only one level of index as xticks in barplot

Time:11-06

I've got a 3 level index. I'm holding two levels in control at all times and plotting data over the third. The plots look nice, but all three levels show as x-axis labels.

gb_zone_month_mean = df.groupby(by=["hemisphere", "climate_zone", "month"]).mean()

zones = [0, 1, 2, 3]  # Climate zone (level 2 of index)
varis = variables[3:] # The 10 variables I care about. 
idx = pd.IndexSlice

fig, ax = plt.subplots(4, 10, figsize=(20, 10))

for z_i in zones:
    for i, v in zip(range(len(varis)), varis):
        gb_zone_month_mean.loc[idx[1, z_i, :], v].plot(kind="bar", ax=ax[z_i][i])
        
plt.tight_layout()
plt.show()

enter image description here

As you can see, there is only one level of the multi-index that is varying in any given plot. That's the month.

How can I choose which level of the multi-index is shown in the x-axis labels?

CodePudding user response:

You can reset_index with drop=True before plot. Also, use groupby would be much faster:

# sample data
df = pd.DataFrame(np.random.randint(0,10,(1000,4)), columns = ['a','b','c','d'])

# aggregation
groups = df.groupby(['a','b','c']).mean()

zones = [0,1,2,3]
varis = [3,4,5,6]

# create the axies, change to number you want
fig, axes = plt.subplots(4,10, figsize=(10,10))

# let say you want to plot on level `a`, `b`
# change to level name you want
# since `varis`, i.e. level `b` is selective, we query before groupby
for data,ax in zip(groups.query('b in @varis').groupby(['a','b']), axes.ravel()):
    (zone, var), d = data
        d.reset_index(level=['a','b'],drop=True)['d'].plot.bar(ax=ax)

Output:

enter image description here

Another option is seaborn's FacetGrid and barplot

import seaborn as sns

plot_data = groups.query('b in @varis').reset_index()
g = sns.FacetGrid(data=plot_data, row='b', col='a')
g.map(sns.barplot, 'c', 'd', order=plot_data['c'].unique())

You get:

enter image description here

  • Related