Darshit Thakar
Darshit Thakar

Reputation: 45

Start the Y ticks at origin of graph and end tick where the axis ends in matplotlib pyplot

I want the axis ticks to start and end where the axis starts and ends enter image description here

enter image description here I have multiple columns which needs to be plotted at once. In the for loop I cannot define the y ticks for each and every column because they have different range of values. I want a code that does the axis setting as shown in the picture for every column's plot

This is the snippet of the code that I am using

import random
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import openpyxl
import os
from PIL import Image
import io

x = np.random.randint( 10, 100, size = (50, 4) )


y = np.random.randint( 1, 20, size = (50, 4) )


z = np.concatenate((x,y), axis = 1)

df = pd.DataFrame( z, columns=list('ABCDEFGH') )

columns=list('ABCDEFGH')
cat = ['Cat1','Cat2','Cat3']

cat_list = random.choices(cat,k = 50)

df["Cat"] = cat_list 

barWidth = 0.25

# loop over multiple colums to plot as bar graph
for i in columns[0:6]:
    print(i)
    # The bars classidied according to 
    bars0 = [ df[df['Cat'] == 'Cat1' ][i].mean(),
               
              df[df['Cat'] == 'Cat1' ][i].mean(),
              
              df[ df['Cat'] == 'Cat1' ][i].mean(),
              
              df[ df['Cat'] == 'Cat1' ][i].mean(),
              
              df[ df['Cat'] == 'Cat1' ][i].mean(),
              
              df[ df['Cat'] == 'Cat1' ][i].mean() ]
    # bars 0 represents all the Cat 1 participants 
             
    yerr0 =  [
             
              df[df['Cat'] == 'Cat1' ][i].std(),
               
              df[df['Cat'] == 'Cat1' ][i].std(),
              
              df[ df['Cat'] == 'Cat1' ][i].std(),
              
              df[ df['Cat'] == 'Cat1' ][i].std(),
              
              df[ df['Cat'] == 'Cat1' ][i].std(),
              
              df[ df['Cat'] == 'Cat1' ][i].std() ]          
              
            
    
    
    bars1 = [  df[df['Cat'] == 'Cat2' ][i].mean(),
               
              df[df['Cat'] == 'Cat2' ][i].mean(),
              
              df[ df['Cat'] == 'Cat2' ][i].mean(),
              
              df[ df['Cat'] == 'Cat2' ][i].mean(),
              
              df[ df['Cat'] == 'Cat2' ][i].mean(),
              
              df[ df['Cat'] == 'Cat2' ][i].mean() ]
    # bars 1 represents all the Cat 2 participants 
             
    yerr1 = [ 
             
               df[df['Cat'] == 'Cat2' ][i].std(),
               
              df[df['Cat'] == 'Cat2' ][i].std(),
              
              df[ df['Cat'] == 'Cat2' ][i].std(),
              
              df[ df['Cat'] == 'Cat2' ][i].std(),
              
              df[ df['Cat'] == 'Cat2' ][i].std(),
              df[ df['Cat'] == 'Cat2' ][i].std() ]         
                     
             
            
    
    
    bars8 = [ df[df['Cat'] == 'Cat3' ][i].mean(),
               
              df[df['Cat'] == 'Cat3' ][i].mean(),
              
              df[ df['Cat'] == 'Cat3' ][i].mean(),
              
              df[ df['Cat'] == 'Cat3' ][i].mean(),
              
              df[ df['Cat'] == 'Cat3' ][i].mean(),
              
              df[ df['Cat'] == 'Cat1' ][i].mean()]
    # bars 8 represents all the Cat 3 participants 
             
    yerr8 =  [
             
                df[df['Cat'] == 'Cat3' ][i].std(),
               
              df[df['Cat'] == 'Cat3' ][i].std(),
              
              df[ df['Cat'] == 'Cat3' ][i].std(),
              
              df[ df['Cat'] == 'Cat3' ][i].std(),
              
              df[ df['Cat'] == 'Cat3' ][i].std(),
              df[ df['Cat'] == 'Cat3' ][i].std() ]        
    # standard deciation for the y error bar           
    
    r1 = np.arange(len(bars1))
    r2 = [x + barWidth for x in r1]
    r3 = [x + barWidth for x in r2]
   
    
    fig, ax = plt.subplots()
    right_side = ax.spines["right"]

    right_side.set_visible(False)
    
    top_side = ax.spines["top"]

    top_side.set_visible(False)
    
    # Cat1
    plt.bar(r1 ,bars0,color='r', width=barWidth, edgecolor='white',
            label='Cat1',yerr=yerr0)
    
    # Cat2
    plt.bar(r2,bars1,color='g', width=barWidth, edgecolor='white',
            label='Cat2', yerr=yerr1)
    
    # Cat3
    plt.bar(r3,bars8, color='b', width=barWidth,
            edgecolor='white', label='Cat3', yerr=yerr8)
            
    
    
    plt.xlabel('columns', fontdict={'fontname': 'Arial', 'fontsize': 16,'fontweight':'bold'})
    
    plt.ylabel('AVG '+ columns[columns.index(i)] ,fontdict={'fontname': 'Arial', 'fontsize': 16})
    
    
    
    plt.title(columns[columns.index(i)] ,fontdict={'fontname': 'Arial', 'fontsize': 24})
    
    plt.xticks([r + barWidth for r in range(len(bars1))],
               [ 'A', 'B',
                'C', 'D', 'E', 'F'],fontsize=12)
    
    

When I individually define the plt.yticks() I am able to achieve the graph on the right. I am unable to figure out how to do it in a loop

Upvotes: 1

Views: 1093

Answers (1)

mcsoini
mcsoini

Reputation: 6642

Just add plt.ylim(top=plt.yticks()[0][-1]) at the end of your loop. This exploits the fact that the automatically generated yticks also contain the next-higher tick, even though it's not visible. For example,

    print(plt.ylim())
    print(plt.yticks()[0])

inside your loop gives

(0.0, 16.5362767162174)
[ 0.  2.  4.  6.  8. 10. 12. 14. 16. 18.]

So even though the y-axis goes to 16.53..., the maximum ytick (not visible, outside the axis) is already present. So all we have to do is to set the top of ylim to this maximum value to extend the y-axis just a little bit.

Of course this results in a slight extension of the axis, so it might be a bit to long for the data in the plot. But based on the example it looks ok. It also corresponds to what you show in your question. Also, to make this more optimal one would need to put in a lot more effort in terms of recreating the automatic yticks, which is probably not worth it.

Upvotes: 1

Related Questions