How to plot sine wave in Python with sudden amplitude change?

后端 未结 3 1219
余生分开走
余生分开走 2021-01-27 20:32

Posted: 7/4/2020

I was wondering if anyone knows how to plot a sine wave with let\'s say amplitude of 0.1 as a start and then continuing on as usual. Until at one point,

相关标签:
3条回答
  • 2021-01-27 20:49

    You could plot a piece-wise sin function where the second part defines the surge happening and you can change the amplitude there.

    For instance:

    import numpy as np
    import matplotlib.pyplot as plt
    import math
    
    surge_point = 50
    amplitudeAfterSurge = 4
    T = 50
    x_normal = np.linspace(0, surge_point, 1000)
    x_surge = np.linspace(surge_point, 150, 1000)
    
    y_normal = [math.sin(2*math.pi*i/T) for i in x_normal] # first part of the function
    
    # second part ,note `amplitudeAfterSurge` multiplying the function
    y_surge = [amplitudeAfterSurge * math.sin(2*math.pi*i/T) for i in x_surge] 
    
    plt.plot(x_normal, y_normal , 'r')
    plt.plot(x_surge, y_surge , 'r')
    
    plt.show()
    

    And you will get:

    0 讨论(0)
  • 2021-01-27 20:52

    I have converted the code to period time:

    import matplotlib.pyplot as plt
    import math
    
    
    # ------------------------------------------------------------------------
    # uses the list amplitude_changes to get the amplitude for time t
    def get_amplitude(t):
        for amplitude_change in amplitude_changes:
            if t >= amplitude_change['t']:
                amplitude = amplitude_change['amplitude']
    
        return amplitude
    
    
    # --------------------------------------------------------------------------
    def y_func(time, period_time, amplitude):
        return amplitude * math.sin((time / period_time) * 2 * math.pi)
    
    # --------------------------------------------------------------------------
    
    
    t_values = []
    amplitude_values = []
    
    signal1Frequency = 50
    period_time = 1 / signal1Frequency
    sampling_frequency = 1500
    
    delta_t = 1 / sampling_frequency
    
    
    amplitude_changes = [
                            {'t': 0, 'amplitude': 1},
                            {'t': period_time * 0.9, 'amplitude': 1.5},
                            {'t': period_time * 0.95, 'amplitude': 1},
                            {'t': period_time * 1.2, 'amplitude': 0.8},
                            {'t': period_time * 1.25, 'amplitude': 1},
                        ]
    
    max_t = period_time * 3                     # plot 3 periods
    t = 0
    while t <= max_t:
        t_values.append(t)
        amplitude = get_amplitude(t)
        amplitude_values.append(y_func(t, period_time, amplitude))
        t += delta_t
    
    
    plt.plot(t_values, amplitude_values)
    plt.title(f'f = {signal1Frequency} Hz (T = {period_time}) - Sampling frequency = {sampling_frequency} Hz')
    plt.show()
    

    Result

    0 讨论(0)
  • 2021-01-27 20:59

    Just like a sine wave in reality if the amplitude changes. You connect the dots of the amplitude just before and just after the change. It's not different from plotting the sine wave itself. How it looks, sharps edges for example, depends only of the moment the change happens.

    This is a very basic way of calculating the points and plotting the lines between them.

    At x=5 I double the amplitude.

    import matplotlib.pyplot as plt
    import math
    
    def y_func(x):
        return math.sin(x)
    
    x_values = []
    y_values = []
    
    x = 0
    
    amplitude = 1
    while x < 5:
        x_values.append(x)
        y_values.append(amplitude * y_func(x))
        x += 0.1
    
    amplitude = 2
    while x < 10:
        x_values.append(x)
        y_values.append(amplitude * y_func(x))
        x += 0.1
    
    plt.plot(x_values, y_values)
    
    plt.title('test')
    plt.show()
    

    After structuring it some more and putting the desired amplitude changes in a list, it's easy to produces nice spikes.

    import matplotlib.pyplot as plt
    import math
    
    
    # ------------------------------------------------------------------------
    def get_amplitude(x):
        for amplitude_change in amplitude_changes:
            if x >= amplitude_change['x']:
                amplitude = amplitude_change['amplitude']
    
        return amplitude
    
    
    # --------------------------------------------------------------------------
    def y_func(x, amplitude):
        return amplitude * math.sin(x)
    
    # --------------------------------------------------------------------------
    
    amplitude_changes = [
                            {'x': -1, 'amplitude': 1},
                            {'x': 6.5, 'amplitude': 2.2},
                            {'x': 6.7, 'amplitude': 1},
                            {'x': 9.1, 'amplitude': 0.5},
                            {'x': 9.2, 'amplitude': 1.2},
                            {'x': 9.4, 'amplitude': 1},
                        ]
    
    x_values = []
    y_values = []
    
    x = 0
    max_x = 10
    step = 0.1
    
    while x <= max_x:
        x_values.append(x)
        amplitude = get_amplitude(x)
        y_values.append(y_func(x, amplitude))
        x += step
    
    plt.plot(x_values, y_values)
    plt.title('test')
    plt.show()
    

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