How to put value over bars when creating many barplots with a loop

Question:

How can I put the value over the bars when creating many plots with a loop.

The code I am using

years = [twenty,twentyone,twentytwo,twentythree]

for year in years:

   plt.ylim(0, 60)
   ax = sns.barplot(data=year, errorbar=None)
   ax.set_xticklabels(ax.get_xticklabels(), rotation=45, horizontalalignment='right')
   for i in ax.containers:
       ax.bar_label(i,)
   
   
   plt.xlabel('Type of error')
   
   
   # Set plot title and save image
   if year is twenty:
       plt.title('2020')
       plt.savefig(f'barplot_2020.png',bbox_inches="tight")


   
   elif year is twentyone:
       plt.title('2021')
       plt.savefig(f'barplot_2021.png',bbox_inches="tight")
       
   
   elif year is twentytwo:
       plt.title('2022')
       plt.savefig(f'barplot_2022.png',bbox_inches="tight")
   
   elif year is twentythree:
       plt.title('2023')
       plt.savefig(f'barplot_2023.png',bbox_inches="tight")
       #ax.bar_label(ax.containers[0],fmt="%.1f")

I have tried also to put some code in the ifs as shown in the last elif but the result is always the same as shown below.

enter image description here
enter image description here
enter image description here

Answers:

This is because you’re missing a plt.figure() command in the beginning of your loop.

plt.figure() instructs matplotlib to create a new empty figure.
Currently you’re constantly modifying the same figure, thus the bars overwrite each other.

We can fix this:

import seaborn as sns
import matplotlib.pyplot as plt

twenty = {'Type of error': ['A', 'B', 'C'], 'Count': [25, 35, 42]}
twentyone = {'Type of error': ['A', 'B', 'C'], 'Count': [30, 40, 38]}
twentytwo = {'Type of error': ['A', 'B', 'C'], 'Count': [28, 33, 45]}
twentythree = {'Type of error': ['A', 'B', 'C'], 'Count': [32, 38, 40]}

years = [twenty, twentyone, twentytwo, twentythree]

for year, data in zip(range(2020, 2024), years):
    plt.figure()  
    
    plt.ylim(0, 60)
    ax = sns.barplot(data=data, x='Type of error', y='Count', errorbar=None)
    ax.set_xticklabels(ax.get_xticklabels(), rotation=45, horizontalalignment='right')
    
    for p in ax.patches:
        ax.bar_label(ax.containers[0], fmt="%.1f")
    
    plt.xlabel('Type of error')
    plt.title(str(year))
    plt.show()

enter image description here
enter image description here

enter image description here
enter image description here

Answered By: Sebastian Wozny