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