numpy 如何在较长时间内绘制正弦曲线

cwtwac6a  于 2023-10-19  发布在  其他
关注(0)|答案(2)|浏览(102)

我是Python新手,试图在x轴上绘制一条持续时间为300秒的正弦曲线,但我只能在短时间内绘制一条正确的正弦曲线。

MWE:

import numpy as np
import matplotlib.pyplot as plt

in_array = np.linspace(0, 2*np.pi, 300)
out_array = np.sin(in_array)

print("in_array : ", in_array)
print("\nout_array : ", out_array)

# red for numpy.sin()
plt.plot(in_array, out_array, color = 'red')
plt.title("numpy.sin()")
plt.xlabel("X")
plt.ylabel("Y")
plt.show()

上面的代码能够绘制所需的正弦曲线,如下所示:

如果我将上面代码中的np.linspace行改为

in_array = np.linspace(0, 6*np.pi, 300)

...然后我能够得到正弦曲线的3个周期,这也是可以的。

问题:如果我在上面的代码中使用in_array = np.linspace(0, 90*np.pi, 300)在x轴上绘制正弦曲线约300秒,那么曲线包含不同的幅度(如下所示),为什么以及如何纠正它?

jbose2ul

jbose2ul1#

在您提到的所有情况下,您生成的x轴点数量相同。
当间隔较短,为300个点时,您可以获得sin的更密集表示,即在每个局部极大值/极小值周围有足够的点来正确地绘制极值。在第一个示例中,每0.02弧度有1个x轴点。
在最后一个例子中,你仍然得到了300个点,但区间更宽。这意味着你大约有一个点每0.95弧度,有时点不会降落在极端附近,因此他们没有绘制,因此明显不同的振幅。
您可以向x轴添加更多点(使其更频繁)。
比如,900分看起来又不错:

in_array = np.linspace(0, 90*np.pi, 900)
out_array = np.sin(in_array)

plt.plot(in_array, out_array, color = 'red')
plt.title("numpy.sin()")
plt.xlabel("X")
plt.ylabel("Y")
plt.show()

输出:x1c 0d1x

azpvetkf

azpvetkf2#

假设你以固定的时间步长Δt 绘制sin ωttn是最接近正弦函数最大值的采样点,那么当 tmax - tn = Δt/2时,你会有最大误差,最大误差为(泰勒级数,忽略四阶项)
εmax =(ωΔt/2)2/2。
如果你想限制最大误差,例如,到0.005,你可以写 εmax =(ωΔt/2)2/2 ≤ 1/200,
求解Δt,最终得到 Δt ≤(5w)-1。
一般来说,如果 ε 是可接受的最大 * 相对 * 误差,则有
Δt ≤(8ε)1/2/ω
确定限制 * 绝对 * 误差所需的最大时间步长作为练习。
写一写可能会很有趣
ωΔt =(8ε)1/2
因为一个循环中的点数 N 由下式给出:
N = 2π / ωΔt = 2π /(8ε)1/2
因此,求解 ε,我们有
ε = π² / 2n²
最后我们可以画出下面的图表,它证实了经验法则“每个周期使用10个点,以将误差限制在最大5%”。

作为检查

import matplotlib.pyplot as plt
import numpy as np

ω = 1
t = np.linspace(0, 0.2, 1001)

plt.figure(layout='constrained')
plt.plot(t, np.cos(ω*t), lw=0.5, color='k')
for ε in (0, 0.001, 0.002, 0.005, 0.01, 0.02):
    Δt = np.sqrt(8*ε)/ω
    plt.scatter(
        Δt/2, np.cos(ω*Δt/2),
        label=r'$ε=%0.3f, ω\,Δt=%0.3f$'%(ε, Δt))
plt.xlabel('$ωt$')
plt.ylabel('$\\cos ωt$')
plt.legend()
plt.grid()

下面来自OP的评论让我怀疑我错过了什么,所以我写了并检查了(5 ')这段代码。

从代码生成的数字来看,采样不足没有问题,但当然我可能是错的。

import matplotlib.pyplot as plt
import numpy as np

f = 0.02
w = 2*355/113*f

max_err = 0.005
w_dt = pow(8*mx_err, 1/2)
dt = w_dt/w

t0, t1 = 0, 300
t = np.linspace(t0, t1, int((t1-t0)/dt))
plt.plot(t, np.sin(w*t))
plt.show()

相关问题