【问题标题】:How to prevent alphabetical sorting for python bars with matplotlib?如何防止使用 matplotlib 对 python 条进行字母排序?
【发布时间】:2018-09-13 19:56:10
【问题描述】:

我正在使用条形图绘制一些分类数据。即使我对数据框值进行排序,Matplotlib 也会按字母顺序对我的 x 轴进行排序。 这是我的代码:

fig3, new_ax = plt.subplots(1,1, figsize=(25/3,5))
summary = tsa.source.sum().sort_values(ascending=False)
new_ax.bar(summary.index, summary.values, color=my_colors)
new_ax.legend()
bar_heights(new_ax) # custom function to get the values on top of bars
simpleaxis(new_ax) # custom function to define an axis to please my boss...
new_ax.set_ylabel('Effectifs')
new_ax.set_xlabel("Type d'arme")
new_ax.grid(False)

输出:

但这是摘要的样子,这就是我想在图表上看到的顺序:

famas            2214.0
aut_typebruit     759.0
grena             200.0
flg                78.0
douze              72.0
sept               53.0
dtype: float64

这是我的数据示例的链接: https://files.fm/u/wumscb4q 用这一行导入它:

tsa.source = pd.read_csv('sample.csv', sep=';', index_col=0)

这里是我的功能:

def simpleaxis(ax):
    ax.spines['top'].set_visible(False)
    ax.spines['right'].set_visible(False)
    ax.get_xaxis().tick_bottom()
    ax.get_yaxis().tick_left()

def bar_heights(axes):
    for rect in axes.containers[0]:
        height = rect.get_height()
        rect.axes.text(rect.get_x() + rect.get_width()/2., height+3,
            '%d' % int(height),
            ha='center', va='bottom')

【问题讨论】:

  • 我无法复制您的问题。想发minimal reproducible example
  • 完成了,我想...
  • 不太最小plt.bar(['foo', 'bar'], [1, 2]) 呢?它是否按字母顺序对条形进行排序?
  • 是的...!
  • 不知道为什么这被否决了 - 完全合理的问题和我也遇到过的问题。我将其投票恢复为中立。

标签: python python-3.x matplotlib


【解决方案1】:

问题

这是 matplotlib a bug,即使值是字符串,X 轴也始终排序。这就是为什么下图中的条形顺序相反的原因。

x = ['foo', 'bar']
y = [1, 2]
plt.bar(x, y, color=['b', 'g'])

修复

将 matplotlib 升级到 2.2.0 或更高版本。对于这些版本,相同的代码会产生预期的结果。

解决方法

如果您不能或不想升级 matplotlib,您可以使用数字代替字符串,然后将刻度和标签设置为正确的值:

index = range(len(x))
plt.bar(x, y, color=['b', 'g'])  # use numbers in the X axis.
plt.xticks(index, x)  # set the X ticks and labels

熊猫之道

您可以使用Series.plot,这可能对您很方便,因为您的数据已经采用Series 的形式,但请注意,pandas 以不同的方式绘制事物。使用关键字参数rot 来控制标签的旋转。

s = pd.Series(y, index=x)
s.plot(kind='bar',rot=0, color=['b', 'g'])

【讨论】:

    【解决方案2】:

    我回答了我自己的问题,因为我找到了一种解决方法,但它需要多行代码才能获得相同的结果,我不喜欢这样:

    summary.plot(kind='bar', ax=new_ax, color=my_colors, width=0.8)
    fig3.autofmt_xdate(bottom=0.2, rotation=0, ha='center')
    

    需要第二行,因为summary.plot() 将 xticklabels 的方向更改为垂直...

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-05-27
      • 1970-01-01
      • 2018-05-04
      • 2018-09-03
      • 2023-03-06
      • 1970-01-01
      • 2015-05-22
      • 1970-01-01
      相关资源
      最近更新 更多