在 barplot 中仅显示一个级别的索引作为 xticks

Show only one level of index as xticks in barplot

我有一个 3 级索引。我始终控制着两个级别,并在第三个级别上绘制数据。这些图看起来不错,但所有三个级别都显示为 x 轴标签。

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()

如您所见,在任何给定图中,多指标中只有一个水平发生变化。就是那个月。

如何选择在 x 轴标签中显示多指标的哪个级别?

你可以 reset_indexdrop=True 在情节之前。另外,使用 groupby 会快得多:

# 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)

输出:

另一个选择是 seaborn 的 FacetGrid 和 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())

你得到: