Search code examples
pythonlegend-properties

Why will my legend not move in Python


I had to create a simple graph to learn the properties of graphing making in python. One of those properties is legend placement. The code for such is ax.legend(loc="some number"). The different numbers you put in that piece of code I mention determine where the legend is placed. However, no matter what number I put, my legend never changes position. Is there a deeper issue that I am missing or could there just be something wrong with my program?

def line_plot():
    x=np.linspace(-np.pi,np.pi,30)
    cosx=np.cos(x)
    sinx=np.sin(x)
    fig1, ax1 = plt.subplots()
    ax1.plot(x,np.sin(x), c='r', lw=3)
    ax1.plot(x,np.cos(x), c='b', lw=3)
    ax1.set_xlabel('x')
    ax1.set_ylabel('y')
    ax1.legend(["cos","sin"])
    ax1.legend(loc=0);
    ax1.set_xlim([-3.14, 3.14])
    ax1.set_xticks([-np.pi, -np.pi/2, 0, np.pi/2, np.pi])
    ax1.grid(True)
    ax1.set_xticklabels(['-'+r'$\pi$', '-'+r'$\pi$'+'/2',0, r'$\pi$'+'/2', r'$\pi$'])
    plt.show()

    return

if __name__ == "__main__":
    line_plot()

Solution

  • When you plot your data you need to give them a label in order for the legend to appear. If you do not do this then you get UserWarning: No labelled objects found. Use label='...' kwarg on individual plots. and you wont be able to move your legend. So you can easily change this by doing the following:

    def line_plot():
        x=np.linspace(-np.pi,np.pi,30)
        cosx=np.cos(x)
        sinx=np.sin(x)
        fig1, ax1 = plt.subplots()
        ax1.plot(x,np.sin(x), c='r', lw=3,label='cos') #added label here
        ax1.plot(x,np.cos(x), c='b', lw=3,label='sin') #added label here
        ax1.set_xlabel('x')
        ax1.set_ylabel('y')
        #ax1.legend(["cos","sin"]) #don't need this as the plots are already labelled now
        ax1.legend(loc=0);
        ax1.set_xlim([-3.14, 3.14])
        ax1.set_xticks([-np.pi, -np.pi/2, 0, np.pi/2, np.pi])
        ax1.grid(True)
        ax1.set_xticklabels(['-'+r'$\pi$', '-'+r'$\pi$'+'/2',0, r'$\pi$'+'/2', r'$\pi$'])
        plt.show()
    
        return
    
    if __name__ == "__main__":
        line_plot()
    

    This gives the plot below. Now changing the value of loc changes the position of the legend.

    enter image description here

    EDIT:

    1) I gave each set of data you plotted their own label. Then when you get to the line ax1.legend(loc=0) matplotlib then sets the legend to include these labels on the legend. This is the most 'pythonic' way of plotting the legend.