如何以pi(Python)的倍数设置轴刻度(matplotlib)
我想用Python绘制一个图,并用pi的倍数显示x范围的刻度 有没有一个好方法可以做到这一点,而不是手动 我正在考虑使用matplotlib,但其他选项也可以 编辑3:EL_DON的解决方案对我来说是这样的:如何以pi(Python)的倍数设置轴刻度(matplotlib),python,matplotlib,plot,axis-labels,Python,Matplotlib,Plot,Axis Labels,我想用Python绘制一个图,并用pi的倍数显示x范围的刻度 有没有一个好方法可以做到这一点,而不是手动 我正在考虑使用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, 1
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()
给予:
编辑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()
给我
看起来真的不对
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))
我使用了以下答案中的信息:
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))
这可以非常简单地使用,无需任何参数:
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()
或者它可以以更复杂的方式使用:
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()
如果要避免在plot命令中用x除以pi,可以使用而不是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()
给出以下图像:
将numpy作为np导入
将matplotlib.pyplot作为plt导入
x=np.linspace(0,3*np.pi,1001)
plt.ylim(-3,3)
plt.xlim(0,4*np.pi)
平面图(x,np.sin(x))
勾选位置=[0,np.pi,2*np.pi]
标签=['0'、'$\pi$'、'$2\pi$']
plt.xticks(勾选位置、标签)
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)
"""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)
@Zubo如果这回答了你的问题,你应该接受它作为答案answer@scicalculator是的,现在它实际上显示了一些错误,所以我正在研究itOk,所以我尝试了一些轻微的修改,出现了一些奇怪的行为-我不知道这是从哪里来的。在编辑中发布了它。有人有办法不必先将x除以π吗?@EL_don我找到了一种不必先将x除以的方法,并将其作为另一个答案写了出来。由于邻域空间中没有足够的点数,所以没有解决这个问题。请尝试
x=np.linspace(-10*np.pi,10*np.pi,1001)
1001应该足够大,看起来很平滑。@EL_DON,是的,谢谢,就是这样!现在有一个更好的答案。我建议将被接受的答案改为@ScottCentoni的答案。我认为在@Zubo中有一个解决方案。虽然,我不知道他们把它作为一个单独的文件,而不是将函数合并到包中。奇怪的另外,被迫使用他们的cos
实现而不是numpy的实现也不太好。如果用户意外地绘制出大量数据,while循环是否会造成麻烦?它可能不止一次地调用tick格式化程序,如果tick是1e16、2e16等,或者是因为它被意外地用在了错误的绘图上,这会阻塞一分钟吗?不,没关系。必须禁用主定位器和次定位器才能转到大x(否则,在到达格式化程序之前,会出现异常,因此可以返回并修复试图在大x范围内使用此定位器的代码)。然后在我的笔记本电脑上执行时间不到100毫秒,甚至到3e16。最后一个刻度为95492965855137200 pi/3.:)如果您尝试在主刻度中进行小增量,则有一个限制。也就是说,将4改为18或其他值,而不是ax.xaxis.set\u major\u locator(plt.multiplelotator(np.pi/4))
。由于den=12
,它的格式不好。也许可以将den
更改为60,以支持更多的刻度增量选择。(我之所以要这样做,是因为我制作了一个函数,它将主刻度增量和次刻度增量作为参数,而不是仅设置为pi/4和pi/12)是的,这也让我感到困扰,所以我将它变得更一般。现在,您可以选择所需的分母,或者选择pi以外的其他值。
ax.set_xticks(np.arange(0, 2*np.pi+0.01, np.pi/4))
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)
"""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)