如何设置pi的倍数(Python)(matplotlib)

Zub*_*ubo 12 python plot matplotlib axis-labels

我想在Python中制作一个情节,并且x范围显示为pi的倍数.

有没有一个很好的方法来做到这一点,而不是手动?

我正在考虑使用matplotlib,但其他选项都很好.

编辑3:EL_DON的解决方案对我有用:

import matplotlib.ticker as tck
import matplotlib.pyplot as plt
import numpy as np

f,ax=plt.subplots(figsize=(20,10))
x=np.linspace(-10*np.pi, 10*np.pi,1000)
y=np.sin(x)

ax.plot(x/np.pi,y)

ax.xaxis.set_major_formatter(tck.FormatStrFormatter('%g $\pi$'))
ax.xaxis.set_major_locator(tck.MultipleLocator(base=1.0))

plt.style.use("ggplot")


plt.show()
Run Code Online (Sandbox Code Playgroud)

赠送:

很好的正弦图

编辑2(在编辑3中解决!):EL_DON的答案似乎不适合我:

import matplotlib.ticker as tck
import matplotlib.pyplot as plt
import numpy as np

f,ax=plt.subplots(figsize=(20,10))
x=np.linspace(-10*np.pi, 10*np.pi)
y=np.sin(x)

ax.plot(x/np.pi,y)

ax.xaxis.set_major_formatter(tck.FormatStrFormatter('%g $\pi$'))
ax.xaxis.set_major_locator(tck.MultipleLocator(base=1.0))

plt.style.use("ggplot")

plt.show()
Run Code Online (Sandbox Code Playgroud)

给我

情节

哪个看起来不对劲

EL_*_*DON 12

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))
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

我使用了这些答案的信息:


Tho*_*ühn 12

如果您想避免在绘图命令中将 x 除以 pi,可以使用FuncFormatter而不是 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()
Run Code Online (Sandbox Code Playgroud)

给出以下图像:

上述代码的结果


Sco*_*oni 7

尽管Sage尝试在没有显式参数的情况下进行操作,但这还是受到Python数据科学手册的启发。

编辑:我已将其概括为允许您提供分母,单位值和单位的LaTeX标签作为可选参数。如果您认为有帮助,则包括一个类定义。

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))
Run Code Online (Sandbox Code Playgroud)

可以很简单地使用它,而无需任何参数:

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()
Run Code Online (Sandbox Code Playgroud)

cos(x)的图

或者可以更复杂的方式使用它:

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()
Run Code Online (Sandbox Code Playgroud)

exp(-x)* cos(60 * x)的图

  • 是的,这也困扰着我,所以我让它更笼统。现在你可以选择你想要的分母,或者选择 pi 以外的其他东西。 (2认同)

kab*_*hel 5

pi 分数的解:

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)
Run Code Online (Sandbox Code Playgroud)
  1. 绘制你的函数:
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)
Run Code Online (Sandbox Code Playgroud)
  1. 修改网格的范围,使其对应于 pi 值:
ax.set_xticks(np.arange(0, 2*np.pi+0.01, np.pi/4))
Run Code Online (Sandbox Code Playgroud)
  1. 更改轴标签:
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)
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述