I can produce sorted bar plots by seaborn
and pandas
but I am having a hard time trying to do the same with matplotlib.pyplot
, using matplotlib 3.3.4. Here is reproducible code to my problem, with the current output:
x = [5, 1, 3, 4, 2, 7, 6]
heights = [156, 151, 135, 107, 100, 86, 72]
x_string = [str(t) for t in x]
data = {
'x': x.copy(),
'heights': heights.copy()
}
df = pd.DataFrame(data).sort_values('heights')
fig, (ax1, ax2, ax3) = plt.subplots(1, 3, figsize=(15,4))
ax1.bar(x='x', height='heights', data=df)
ax1.set_title('1) Using a DataFrame')
ax2.bar(x=x, height=heights)
ax2.set_title('2) Using Lists')
ax3.bar(x=x_string, height=heights)
ax3.set_title("3) With Strings")
fig.savefig('bar_order.png')
plt.show()
A possible workaround is to use something like
ax.bar(x=range(1, len(heights)+1), height=heights, tick_label=x)
Edit
The desired output is subplot 3. The behaviour I see, and I do not like, is that when I provide x as a list of integers, matplotlib takes it as the position on a normal mathematical x-axis but when I pass x as a list of string, matplotlib takes it as tick labels. Since bar charts are made for categorical variables, I expect the x
argument to always be treated as labels, or maybe there should be a key to tell matplotlib
if I want the x
argument to be treated as labels or positions on the x-axis.