Python中的梯形波

时间:2017-06-14 08:41:27

标签: python-3.x numpy matplotlib scipy

如何在Python中生成梯形波?

我查看了SciPy和NumPy等模块,但是徒劳无功。是否有一个模块,如scipy.signal.gaussian,它返回一个表示高斯函数波的值数组?

Enter image description here

我使用Astropy的梯形内核生成了这个, 的 Trapezoid1DKernel(30,斜率= 1.0) 。我想在不使用Astropy的情况下在Python中实现它。

4 个答案:

答案 0 :(得分:2)

SciPy website看起来它不包括在内(它们目前有sawtoothsquare,但不是梯形)。作为the C示例的通用版本,以下将执行您想要的操作,

import numpy as np
import matplotlib.pyplot as plt

def trapezoidalWave(xin, width=1., slope=1.):
    x = xin%(4*width)
    if (x <= width):
        # Ascending line
        return x*slope;
    elif (x <= 2.*width):
        # Top horizontal line
        return width*slope
    elif (x <= 3.*width):
        # Descending line
        return 3.*width*slope - x*slope
    elif (x <= 4*width):
        # Bottom horizontal line
        return 0.


x = np.linspace(0.,20,1000)
for i in x:
    plt.plot(i, trapezoidalWave(i), 'k.')
    plt.plot(i, trapezoidalWave(i, 1.5, 2.), 'r.')
plt.show()

看起来像,

Enter image description here

使用Heaviside函数可以更优雅地完成此操作,这些函数允许您使用NumPy数组,

import numpy as np
import matplotlib.pyplot as plt

def H(x):
    return 0.5 * (np.sign(x) + 1)

def trapWave(xin, width=1., slope=1.):
    x = xin%(4*width)
    y = ((H(x)-H(x-width))*x*slope +
         (H(x-width)-H(x-2.*width))*width*slope +
         (H(x-2.*width)-H(x-3.*width))*(3.*width*slope - x*slope))
    return y

x = np.linspace(0.,20,1000)
plt.plot(x, trapWave(x))
plt.plot(x, trapWave(x, 1.5, 2.))
plt.show()

对于这个例子,Heaviside版本大约快20倍!

答案 1 :(得分:2)

以下示例显示了如何获取点并显示范围。

基于回复的公式:Equation for trapezoidal wave equation

import math
import numpy as np
import matplotlib.pyplot as plt


def get_wave_point(x, a, m, l, c):
    # Equation from: https://stackoverflow.com/questions/11041498/equation-for-trapezoidal-wave-equation
    # a/pi(arcsin(sin((pi/m)x+l))+arccos(cos((pi/m)x+l)))-a/2+c
    # a is the amplitude
    # m is the period
    # l is the horizontal transition
    # c is the vertical transition

    point = a/math.pi*(math.asin(math.sin((math.pi/m)*x+l))+math.acos(math.cos((math.pi/m)*x+l)))-a/2+c
    return point

print('Testing wave')

x = np.linspace(0., 10, 1000)
listofpoints = []
for i in x:
    plt.plot(i, get_wave_point(i, 5, 2, 50, 20), 'k.')
    listofpoints.append(get_wave_point(i, 5, 2, 50, 20))
print('List of points : {} '.format(listofpoints))
plt.show()

答案 2 :(得分:1)

虽然宽度和斜率足以定义三角形信号,但您需要梯形信号的第三个参数:幅度。

使用这三个参数,您可以轻松调整scipy.signal.sawtooth功能,通过截断和偏移三角形函数来为您提供梯形形状。

from scipy import signal
import matplotlib.pyplot as plt
import numpy as np


def trapzoid_signal(t, width=2., slope=1., amp=1., offs=0):
    a = slope*width*signal.sawtooth(2*np.pi*t/width, width=0.5)/4.
    a[a>amp/2.] = amp/2.
    a[a<-amp/2.] = -amp/2.
    return a + amp/2. + offs

t = np.linspace(0, 6, 501)
plt.plot(t,trapzoid_signal(t, width=2, slope=2, amp=1.), label="width=2, slope=2, amp=1")
plt.plot(t,trapzoid_signal(t, width=4, slope=1, amp=0.6), label="width=4, slope=1, amp=0.6")

plt.legend( loc=(0.25,1.015))
plt.show()

enter image description here

请注意,您可能还希望定义一个阶段,具体取决于用例。

为了定义单个脉冲,您可能需要稍微修改一下该函数并提供一个范围超过[0,width]的数组。

from scipy import signal
import matplotlib.pyplot as plt
import numpy as np

def trapzoid_signal(t, width=2., slope=1., amp=1., offs=0):
    a = slope*width*signal.sawtooth(2*np.pi*t/width, width=0.5)/4.
    a += slope*width/4.
    a[a>amp] = amp
    return a + offs

for w,s,a in zip([2,5], [2,1], [1,0.6]):
    t = np.linspace(0, w, 501)
    l = "width={}, slope={}, amp={}".format(w,s,a)
    plt.plot(t,trapzoid_signal(t, width=w, slope=s, amp=a), label=l)

plt.legend( loc="upper right")
plt.show()

enter image description here

答案 3 :(得分:0)

归功于@ImportanceOfBeingErnest。我只是修改了他的代码的一些编辑,这些编辑刚刚结束了我的一天。

from scipy import signal
import matplotlib.pyplot as plt
from matplotlib import style
import numpy as np

def trapzoid_signal(t, width=2., slope=1., amp=1., offs=0):
    a = slope*width*signal.sawtooth(2*np.pi*t/width, width=0.5)/4.
    a += slope*width/4.
    a[a>amp] = amp
    return a + offs

for w,s,a in zip([32],[1],[0.0322]):
    t = np.linspace(0, w, 34)

    plt.plot(t,trapzoid_signal(t, width=w, slope=s, amp=a))


plt.show()

结果:enter image description here