1

I have two lists and I am plotting a graph using matplotlib. Currently, the bars are organized in the way the lists are written. I want to set them in an ascending/descending order automatically. How can I do so?

industries = ['Manufacturing', 'Food', 'Eco']
counts = [12,78,1]

plt.figure(figsize=(16,6))
bars = plt.bar(industries, counts, width=0.2, bottom=None, align='center', data=None)
plt.xlim(-0.9, len(industries) - 1 + 0.9)
for i in range(len(counts)):
    percentage = ((counts[i]/(total))*100)
    plt.annotate(percentage, xy=(industries[i], counts[i] + 10), ha='center')
plt.show()

Edit:

I realized that the bars are built on the basis of alphabetical order. Even if the data is sorted. How can this be fixed?

2 Answers2

0

First sort the lists as you need them by ziping them, sort, and then "unzip" them:

industries = ['Manufacturing', 'Food', 'Eco']
counts = [12,78,1]

sorted_counts, sorted_industries = zip(*sorted(zip(counts, industries), reverse=True))

Or set reversed=False for ascending.

Then plot like this

x_locations = range(len(industries))
plt.bar(x_locations, sorted_counts, , tick_label=sorted_industries, ...)

If you look at the docs you'll see the first parameter is not the bar labels but there x-coordinates. The simplest way to get them evenly spaced is to use range. Then you can change the tick lables using the tick_labels argument.

Just to note, when I try it using plt.bar(sorted_industries, sorted_counts), it is plotting them in the expected order, not alphabetical. What version of matplotlib are you trying this with?

Dan
  • 45,079
  • 17
  • 88
  • 157
  • Ah yes that makes sense too but sorting the list isn't the problem. Matplotlib automatically arranges everything in an alphabetical order even when the lists are sorted –  Aug 02 '20 at 22:43
  • oh I see - yeah you should use `range(len(industries))` as the x-values, I'll update – Dan Aug 02 '20 at 22:45
  • @a125 see my edit on how to plot it in the correct order – Dan Aug 02 '20 at 22:52
0
  • The two lists need to be combined with zip and then sorted on the counts.
  • Iterate through the list of tuples to add the bars, in sorted order in reverse order, with the annotation.
industries = ['Manufacturing', 'Food', 'Eco']
counts = [12, 78, 1]
tot = sum(counts)

# combine the two lists with zip and then reverse sort them
data = sorted(zip(industries, counts), key=lambda v: v[1], reverse=True)

plt.figure(figsize=(16, 6))
for (i, c) in data:  # unpack and plot each tuple in sorted order
    bars = plt.bar(i, c, width=0.2, bottom=None, align='center', data=None, color='g')
    plt.annotate(f'{(c/tot)*100:0.02f}%\n', xy=(i, c), va='center', ha='center')
plt.xlim(-0.9, len(industries) - 1 + 0.9)

plt.show()

enter image description here

Trenton McKinney
  • 56,955
  • 33
  • 144
  • 158