pythonmatplotlibseabornbar-chartplot-annotations

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


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


Solution

  • 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