y轴倒置的条形图,条形图固定在底部

时间:2018-12-11 13:58:40

标签: python-3.x matplotlib

下面的代码创建一个Y轴倒置的条形图。我还无法管理的是,这些酒吧不是“从上方悬挂”,而是从底部开始。换句话说,我希望条形图从y轴的最大值(即x轴)开始,以df ['y']的值结束。我该怎么办?

import pandas as pd
import matplotlib.pyplot as plt

df = pd.DataFrame(data={'x_cat': ['aaaaa',
                              'bvvvvvv',
                              'deeeee',
                              'qqqqqqq',
                              'rr rrrrrrrr',
                              'rss sdasr',
                              'cccccccccccc',
                              'aarrrrrrrrrrra'
                              ],
                     'y': [11.91,
                           35.19,
                           43.61,
                           46.12,
                           75.03,
                           81.39,
                           83.28,
                           89.20]
                   })
df['rank'] = df['y'].rank(method='dense') - 1

fig = plt.figure()
ax = fig.add_subplot(111)
# increase space below subplot
fig.subplots_adjust(bottom=0.3)
ax.bar(df['rank'],
   df['y'],
   width=0.8,
   )
# invert y axis
ax.invert_yaxis()
# label x axis
ax.set_xticks(range(len(df)))
ax.set_xticklabels(df['x_cat'],
               fontdict={'fontsize': 14})
for tick in ax.get_xticklabels():
    tick.set_rotation(90)

output

1 个答案:

答案 0 :(得分:1)

您需要计算新的bottom。 (注意 因为轴是倒置的,所以“底部”成为条形图的可视顶部。)底部是值,高度是最大值减去值本身。

我更改了您情节的其他方面,例如如果您的值未排序,则计算等级并将其用于绘图会导致错误的标签。因此,最好事先对数据框进行排序(而不必考虑排名)。

最后,我们需要调整这些条的“粘性边缘”,因为它们应该紧贴图形的底部(即轴的顶部)。

import pandas as pd
import matplotlib.pyplot as plt

df = pd.DataFrame({'x_cat': ['aaaaa', 'bvvvvvv', 'deeeee', 'qqqqqqq', 'rr rrrrrrrr',
                             'rss sdasr', 'cccccccccccc', 'aarrrrrrrrrrra'],
                   'y': [11.91, 35.19, 43.61, 46.12, 75.03, 81.39, 83.28, 89.20]})
df.sort_values("y", inplace=True)

fig = plt.figure()
ax = fig.add_subplot(111)
# increase space below subplot
fig.subplots_adjust(bottom=0.3)
bars = ax.bar(df['x_cat'], df['y'].max()-df['y'], bottom=df['y'], width=0.8, )

# invert y axis
ax.invert_yaxis()

ax.tick_params(axis="x", rotation=90, labelsize=14)

for bar in bars:
    bar.sticky_edges.y[:] = [df['y'].values.max()]
ax.autoscale()
plt.show()

output