How to set axis ticks in multiples of pi (Python) (matplotlib)

前端 未结 6 1744
长发绾君心
长发绾君心 2020-12-08 04:37

I\'d like to make a plot in Python and have x range display ticks in multiples of pi.

Is there a good way to do this, not manually?

I\'m thinking of using

相关标签:
6条回答
  • 2020-12-08 05:17
    import numpy as np
    import matplotlib.pyplot as plt
    x=np.linspace(0,3*np.pi,1001)
    plt.ylim(-3,3)
    plt.xlim(0, 4*np.pi)
    plt.plot(x, np.sin(x))
    tick_pos= [0, np.pi , 2*np.pi]
    labels = ['0', '$\pi$', '$2\pi$']
    plt.xticks(tick_pos, labels)
    

    0 讨论(0)
  • 2020-12-08 05:23

    If you want to avoid dividing x by pi in the plot command, this answer can be adjusted slightly using a FuncFormatter instead of a FormatStrFormatter:

    import numpy as np
    from matplotlib import pyplot as plt
    from matplotlib.ticker import FuncFormatter, MultipleLocator
    
    fig,ax = plt.subplots()
    
    x = np.linspace(-5*np.pi,5*np.pi,100)
    y = np.sin(x)/x
    ax.plot(x,y)
    #ax.xaxis.set_major_formatter(FormatStrFormatter('%g $\pi$'))
    ax.xaxis.set_major_formatter(FuncFormatter(
       lambda val,pos: '{:.0g}$\pi$'.format(val/np.pi) if val !=0 else '0'
    ))
    ax.xaxis.set_major_locator(MultipleLocator(base=np.pi))
    
    plt.show()
    

    gives the following image:

    0 讨论(0)
  • 2020-12-08 05:23

    I created a PyPi Package that creates formatter and locator instances like Scott Centoni's answer.

    """Show a simple example of using MultiplePi."""
    
    import matplotlib.pyplot as plt
    import numpy as np
    
    from matplot_fmt_pi import MultiplePi
    
    fig = plt.figure(figsize=(4*np.pi, 2.4))
    axes = fig.add_subplot(111)
    x = np.linspace(-2*np.pi, 2*np.pi, 512)
    axes.plot(x, np.sin(x))
    
    axes.grid(True)
    axes.axhline(0, color='black', lw=2)
    axes.axvline(0, color='black', lw=2)
    axes.set_title("MultiplePi formatting")
    
    pi_manager = MultiplePi(2)
    axes.xaxis.set_major_locator(pi_manager.locator())
    axes.xaxis.set_major_formatter(pi_manager.formatter())
    
    plt.tight_layout()
    plt.savefig("./pi_graph.png", dpi=120)
    
    0 讨论(0)
  • 2020-12-08 05:24

    This is inspired by Python Data Science Handbook, although Sage attempts to do without explicit parameters.

    EDIT: I've generalized this to allow you to supply as optional parameters the denominator, the value of the unit, and the LaTeX label for the unit. A class definition is included if you find that helpful.

    import numpy as np
    import matplotlib.pyplot as plt
    
    def multiple_formatter(denominator=2, number=np.pi, latex='\pi'):
        def gcd(a, b):
            while b:
                a, b = b, a%b
            return a
        def _multiple_formatter(x, pos):
            den = denominator
            num = np.int(np.rint(den*x/number))
            com = gcd(num,den)
            (num,den) = (int(num/com),int(den/com))
            if den==1:
                if num==0:
                    return r'$0$'
                if num==1:
                    return r'$%s$'%latex
                elif num==-1:
                    return r'$-%s$'%latex
                else:
                    return r'$%s%s$'%(num,latex)
            else:
                if num==1:
                    return r'$\frac{%s}{%s}$'%(latex,den)
                elif num==-1:
                    return r'$\frac{-%s}{%s}$'%(latex,den)
                else:
                    return r'$\frac{%s%s}{%s}$'%(num,latex,den)
        return _multiple_formatter
    ​
    class Multiple:
        def __init__(self, denominator=2, number=np.pi, latex='\pi'):
            self.denominator = denominator
            self.number = number
            self.latex = latex
    ​
        def locator(self):
            return plt.MultipleLocator(self.number / self.denominator)
    ​
        def formatter(self):
            return plt.FuncFormatter(multiple_formatter(self.denominator, self.number, self.latex))
    

    This can be used very simply, without any parameters:

    x = np.linspace(-np.pi, 3*np.pi,500)
    plt.plot(x, np.cos(x))
    plt.title(r'Multiples of $\pi$')
    ax = plt.gca()
    ax.grid(True)
    ax.set_aspect(1.0)
    ax.axhline(0, color='black', lw=2)
    ax.axvline(0, color='black', lw=2)
    ax.xaxis.set_major_locator(plt.MultipleLocator(np.pi / 2))
    ax.xaxis.set_minor_locator(plt.MultipleLocator(np.pi / 12))
    ax.xaxis.set_major_formatter(plt.FuncFormatter(multiple_formatter()))
    plt.show()
    

    Or it can be used in a more sophisticated way:

    tau = np.pi*2
    den = 60
    major = Multiple(den, tau, r'\tau')
    minor = Multiple(den*4, tau, r'\tau')
    x = np.linspace(-tau/60, tau*8/60,500)
    plt.plot(x, np.exp(-x)*np.cos(60*x))
    plt.title(r'Multiples of $\tau$')
    ax = plt.gca()
    ax.grid(True)
    ax.axhline(0, color='black', lw=2)
    ax.axvline(0, color='black', lw=2)
    ax.xaxis.set_major_locator(major.locator())
    ax.xaxis.set_minor_locator(minor.locator())
    ax.xaxis.set_major_formatter(major.formatter())
    plt.show()
    

    0 讨论(0)
  • 2020-12-08 05:27
    f,ax=plt.subplots(1)
    x=linspace(0,3*pi,1001)
    y=sin(x)
    ax.plot(x/pi,y)
    ax.xaxis.set_major_formatter(FormatStrFormatter('%g $\pi$'))
    ax.xaxis.set_major_locator(matplotlib.ticker.MultipleLocator(base=1.0))
    

    I used info from these answers:

    • https://stackoverflow.com/a/19972993/6605826
    • https://stackoverflow.com/a/29188910/6605826
    0 讨论(0)
  • 2020-12-08 05:37

    Solution for pi fractions:

    import numpy as np
    import matplotlib.pyplot as plt
    
    from matplotlib import rc
    rc('text', usetex=True) # Use LaTeX font
    
    import seaborn as sns
    sns.set(color_codes=True)
    
    1. Plot your function:
    fig, ax = plt.subplots(1)
    x = np.linspace(0, 2*np.pi, 1001)
    y = np.cos(x)
    ax.plot(x, y)
    plt.xlim(0, 2*np.pi)
    
    1. Modify the range of the grid so that it corresponds to the pi values:
    ax.set_xticks(np.arange(0, 2*np.pi+0.01, np.pi/4))
    
    1. Change axis labels:
    labels = ['$0$', r'$\pi/4$', r'$\pi/2$', r'$3\pi/4$', r'$\pi$',
              r'$5\pi/4$', r'$3\pi/2$', r'$7\pi/4$', r'$2\pi$']
    ax.set_xticklabels(labels)
    

    0 讨论(0)
提交回复
热议问题