简体   繁体   中英

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

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, the amplitude change to 1.0. Like a sudden surge of change in amplitude. It's like I was an oscillatory system that was stable, and becoming unstable at one point. The plot that I am expecting is as follow:

故障电流模型

Regards, Anis

Updated progress: 18/4/2020

import numpy as np
import matplotlib.pyplot as plotter
from scipy import signal
# How many time points are needed i,e., Sampling Frequency
samplingFrequency   = 1500
# At what intervals time points are sampled
samplingInterval       = 1 / samplingFrequency;
# Begin time period of the signals
beginTime           = 0;
# End time period of the signals
endTime             = 0.3;
# Frequency of the signals
signal1Frequency     = 50;
#Time points
time  = np.arange(beginTime, endTime, samplingInterval);
phase = 180
pi = np.pi
phi = phase*pi/180
# Create two waves- sine and square
amplitude1 = np.sin(2*np.pi*signal1Frequency*time)

amplitude2 = signal.square(2 * np.pi * 50 * time+ phi )
figure, axis = plotter.subplots(1, 1)
plotter.subplots_adjust(hspace=1)


if (time >0.2):
    amplitude = 3*amplitude1
    plotter.plot(time, amplitude)
    plotter.title('test')
    plotter.show()

Above is the code that I am currently working on. It keeps on popping an error to due to ambiguity. Requesting me to use a.all() and a.any() function to solve it. When I did do so, I am not getting the surge point that I am expecting. So any ideas on it? I am using time as x axis instead of indexing. And I am using numoy sine instead of math library. This is because when I tried FFT for code proposed below, I am not getting a 50 Hz, it was more of 30 or 10 Hz, and that is understandable given that the frequency was not set and it depends on the periodic cycle created by the sinusoid itself.

Regards, Anis

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()

在此处输入图像描述

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:

分段函数

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

在此处输入图像描述

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM