2

I want to create bars with this code and I've done it, but my percentages aren't visible correctly. They should be integer values, but they aren't

import matplotlib.pyplot as plt
import matplotlib.ticker as mticker
import numpy as np

numbers1 = dataset.loc[0:36, 'Today'].tolist()
numbers2 = dataset.loc[0:36, 'Tomorrow'].tolist()
names = dataset.loc[0:36, 'Cities'].tolist()

data = list(zip(names, numbers1, numbers2))
data.sort(key=lambda x: x[1], reverse=True)
sorted_names, sorted_numbers1, sorted_numbers2 = zip(*data)

fig, ax = plt.subplots(figsize=(12, 6))  # Set the desired graphics dimensions (width, height)

width = 0.4
spacing = 0.1

x = np.arange(len(sorted_names))

rects1 = ax.bar(x - spacing/2, sorted_numbers1, width, color='blue')

for i in range(len(sorted_names)):
    if sorted_numbers1[i] < sorted_numbers2[i]:
        rects1[i].set_color('green')
    elif sorted_numbers1[i] > sorted_numbers2[i]:
        rects1[i].set_color('red')

ax.set_xticks(x)
ax.set_xticklabels(sorted_names, rotation=45, ha='right')

# Converting the "y" axis to percentages
ax.yaxis.set_major_formatter(mticker.PercentFormatter())

# Adding percentage values above bars
for i, rect in enumerate(rects1):
    height = rect.get_height()
    ax.text(rect.get_x() + rect.get_width() / 2, height, f'{sorted_numbers1[i]}%', ha='center', va='bottom')

# Setting the distances between elements
plt.subplots_adjust(bottom=0.4, wspace=0.5, hspace=0.5)

plt.show()

My bars with non correct percentages

My table with correct percentages

I expect to see normal percentages upon my bars like 74%....66% and next... and side percentages the same...

Joris Schellekens
  • 8,483
  • 2
  • 23
  • 54
  • Hi @Алейна Дарк your code seems to work fine on dummy data. There is some issue with the data you are using. Please share a sample data to reproduce results. – Prashant Maurya Jun 23 '23 at 06:52

2 Answers2

0

Try using PercentFormatter(xmax=1.0), as suggested in this post: https://stackoverflow.com/a/36319915/10176124

If your percentage is formatted as 0-1 you can set xmax to 1, if it is formatted 0-100 you can use the default xmax or use xmax=100. You can also control the number of decimals with the 'decimals' argument, see the documentation for the function here:

https://matplotlib.org/stable/api/ticker_api.html#matplotlib.ticker.PercentFormatter

  • Thank you. @P Fernandez my code became much better. But percentages above bars are still 0,27%, 0,25%..... and the same things. But i want to make it like 27%, 25% and next.... maybe you know how to change it? How can i send you my new code? – Алейна Дарк Jun 23 '23 at 13:15
0

It is my new code

import matplotlib.ticker as mticker
import numpy as np

numbers1 = dataset.loc[0:36, 'Відсоток ЗСУ'].tolist()
numbers2 = dataset.loc[0:36, 'PercentTomorrow'].tolist()
names = dataset.loc[0:36, 'Місто'].tolist()

data = list(zip(names, numbers1, numbers2))
data.sort(key=lambda x: x[1], reverse=True)
sorted_names, sorted_numbers1, sorted_numbers2 = zip(*data)

fig, ax = plt.subplots(figsize=(12, 6))

width = 0.4
spacing = 0.1

x = np.arange(len(sorted_names))

rects1 = ax.bar(x - spacing/2, sorted_numbers1, width, color='blue')

for i in range(len(sorted_names)):
    if sorted_numbers1[i] < sorted_numbers2[i]:
        rects1[i].set_color('green')
    elif sorted_numbers1[i] > sorted_numbers2[i]:
        rects1[i].set_color('red')

ax.set_xticks(x)
ax.set_xticklabels(sorted_names, rotation=45, ha='right')

ax.yaxis.set_major_formatter(mticker.PercentFormatter(xmax=1.0))

for i, rect in enumerate(rects1):
    height = rect.get_height()
    percentage = sorted_numbers1[i] / 100.0  # Convert percentage to decimal
    ax.text(rect.get_x() + rect.get_width() / 2, height, f'{percentage:.2%}', ha='center', va='bottom')  # Format as percentage

plt.subplots_adjust(bottom=0.4, wspace=0.5, hspace=0.5)

plt.show()```