1

For a class project I am plotting a barchart. I have a python list with a bunch of labels (even, odd, squares, powers of 3, etc) and a numpy array to hold probabilities associated with each label (in the same order as the labels list). When I plot my chart

labels = ["even", "odd", "squares", "powers of 3"]

fig, ax = plt.subplots()
ax.barh(labels, probability)

it puts the barchart values in reverse alphabetical order so instead of it being ordered even, odd, squares it is ordered squares, powers of 3, odd, even, etc. How can I keep my plot in the same order as my list?

greyer
  • 97
  • 1
  • 13
  • As of now, version 2.1.2 of matplotlib, categorical axes will be sorted alphabetically. This is an undesired behaviour, but still has not been fixed, see e.g. [this issue](https://github.com/matplotlib/matplotlib/pull/9318). Probably, [this PR](https://github.com/matplotlib/matplotlib/pull/10212) will fix it at some point in the future. The only option currently is to plot numbers, just as one had do to prior to matplotlib 2.1 anyways. The [duplicate](https://stackoverflow.com/questions/47373762/pyplot-sorting-y-values-automatically) shows how to do that. – ImportanceOfBeingErnest Jan 22 '18 at 21:10

1 Answers1

2

The first parameter in Axes.barh is the vertical coordinates of the bars, so you'll want something like

fig, ax = plt.subplots()
y = np.arange(len(labels))
ax.barh(y, probability)
ax.set_yticks(y)
ax.set_yticklabels(labels)

This way, the bars will be ordered following the order of your list from top to bottom. If you want it the other way around, you could simply do

fig, ax = plt.subplots()
y = np.arange(len(labels))
ax.barh(y, probability)
ax.set_yticks(y)
ax.set_yticklabels(labels)
ax.invert_yaxis()

instead.

enter image description here

Edit: Given @ImportanceOfBeingErnest's comment, I should note that the above was tested with matplotlib 2.1.1.

fuglede
  • 17,388
  • 2
  • 54
  • 99