I'm plotting some categorical data using a bar chart. Matplotlib keeps sorting my x-axis alphabetically even when I sort my dataframe values. Here's my code :
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)
Output :

And yet here's what summary looks like and that's the order I want to see on my chart :
famas            2214.0
aut_typebruit     759.0
grena             200.0
flg                78.0
douze              72.0
sept               53.0
dtype: float64
Here's a link to a sample of my data : https://files.fm/u/wumscb4q import it with this line :
tsa.source = pd.read_csv('sample.csv', sep=';', index_col=0)
And here my functions :
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')
                This is a bug in matplotlib < 2.2.0 where the X axis is always sorted even if the values are strings. That is why the order of the bars is reversed in the following plot.
x = ['foo', 'bar']
y = [1, 2]
plt.bar(x, y, color=['b', 'g'])

Upgrade matplotlib to 2.2.0 or higher. The same code produces the expected result with these versions.

If you cannot or do not want to upgrade matplotlib you can use numbers instead of strings, then set the ticks and labels to the correct values:
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

You can use Series.plot which might be convenient for you since your data is already in the form of a Series, but be aware that pandas plots things differently. Use the keyword argument rot to control the rotation of the labels.
s = pd.Series(y, index=x)
s.plot(kind='bar',rot=0, color=['b', 'g'])

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With