plot analog wave from 9 points of freq and power in python - python-3.x

Good day Everyone, I'm new there hope someone will guide me and help me with my query.
is there away to plot the wave of signal using python? i have 9 points of frequency an power and i want it plot it using python v3.6.
i found some recourse like here and here and here and here i have try the code in below , but i want the graph shows as wave not in same that way. any suggest ?
code is :
# importing the required module
import matplotlib.pyplot as plt
# x axis values
x = [54,58,61,62,64,65,66,69,72] # frequency
# corresponding y axis values
y = [2,2.5,4,3,2.5,3.5,4.5,3,2] # Power
# plotting the points
plt.plot(x, y)
# naming the x axis
plt.xlabel('x - axis')
# naming the y axis
plt.ylabel('y - axis')
# giving a title to my graph
plt.title('My first graph!')
# function to show the plot
plt.show()
code of sin-wave, how i modify the code in below to assign the value of frequency and power as : freq = [54,58,61,62,64,65,66,69,72] # frequency and Power = [2,2.5,4,3,2.5,3.5,4.5,3,2] # Power
import numpy as np
import matplotlib
matplotlib.use('TKAgg') #use matplotlib backend TkAgg (optional)
import matplotlib.pyplot as plt
sample_rate = 200 # sampling frequency in Hz (atleast 2 times f)
t = np.linspace(0,5,sample_rate) #time axis
f = 100 #Signal frequency in Hz
sig = np.sin(2*np.pi*f*(t/sample_rate))
plt.plot(t,sig)
plt.xlabel("Time")
plt.ylabel("Amplitude")
plt.tight_layout()
plt.show()

Related

draw signal spectrum using matplotlib

I have the following signal and I want to do the following:
s= 4*np.cos(4*np.pi*pow(10,6)*t+30)+2*np.sin(8*np.pi*pow(10,6)*t+15)+np.cos(12*np.pi*pow(10,6)*t)+0.5*np.cos(16*np.pi*pow(10,6)*t) # the signal
I want to draw signal spectrum using matplotlib and numpy,
the find its bandwidth and determine if it's periodic or not
I use this code available here(https://matplotlib.org/3.1.0/gallery/lines_bars_and_markers/spectrum_demo.html)
thanks for helping
I am not 100% sure if I now what you want to do but it seems plotting and returning all the turning points of your function should help you a lot with your problem.
Therefore you may try this:
import numpy as np
import matplotlib.pyplot as plt
from scipy.signal import argrelextrema
def func(t):
# messures the time in units of
# pow(10,6)*t
exp = 4*np.cos(4*np.pi*t+30)+\
2*np.sin(8*np.pi*t+15)+\
np.cos(12*np.pi*t)+\
0.5*np.cos(16*np.pi*t)
return exp
max_time = 2
time_steps = 400
# defining the signal
X = np.linspace(0,max_time,time_steps)
Y = func(X)
# getting all the max and min values
minimas = argrelextrema(Y, np.less)
maximas = argrelextrema(Y, np.greater)
# plot the singal
plt.plot(X,Y)
# plot minimas and maximas
plt.scatter(X[minimas],Y[minimas],color='r')
plt.scatter(X[maximas],Y[maximas],color='g')
plt.xlabel('t*10**6')
plt.ylabel('signal')
plt.show()

FFT freq wrong is there a problem in code

Want to convert raw accelerometer data to frequency however I have set the frequency on my motor to 120hz and check with another device I am unable to FFT the accelerometer data to get the right frequency produced by the motor
Using Python 3.7, the data use is most likely correct so wondering if there is a problem in the code
from scipy.fftpack import fft
import numpy as np
from scipy import pi
import matplotlib.pyplot as plt
%matplotlib inline
# Sampling rate and time vector
start_time = 0 # seconds
end_time = 2 # seconds
sampling_rate = 6660 # Hz
N =(end_time - start_time)*sampling_rate # array size
# Nyquist Sampling Criteria
T = 1/sampling_rate # inverse of the sampling rate
x = np.linspace(0.0, 1.0/(2.0*T), int(N/2))
# FFT algorithm
yr = fft(X) # "raw" FFT with both + and - frequencies
y = 2/N * np.abs(yr[0:np.int(N/2)]) # positive freqs only
# Plotting the results
plt.plot(x, y)
plt.xlabel('Frequency (Hz)')
plt.ylabel('Vibration (g)')

How to project certain values from the graph on the axis in Python?

I am trying to plot a normal distribution curve in Python using matplotlib. I followed the accepted answer in the post python pylab plot normal distribution in order to generate the graph.
I would like to know if there is a way of projecting the mu - 3*sigma, mu + 3*sigma and the mean values on both the x-axis and y-axis.
Thanks
EDIT 1
Image for explaining projection
example_image.
In the image, I am trying to project the mean value on x and y-axis. I would like to know if there is a way I can achieve this along with obtaining the values (the blue circles on x and y-axis) on x and y-axis.
The following script shows how to achieve what you want:
import matplotlib.pyplot as plt
import numpy as np
import scipy.stats as stats
mu = 2
variance = 9
sigma = np.sqrt(variance)
x = np.linspace(mu - 3*sigma, mu + 3*sigma, 500)
y = stats.norm.pdf(x, mu, sigma)
fig, ax = plt.subplots()
ax.plot(x, y)
ax.set_xlim([min(x), max(x)])
ax.set_ylim([min(y), max(y)+0.02])
ax.hlines(y=max(y), xmin=min(x), xmax=mu, color='r')
ax.vlines(x=mu, ymin=min(y), ymax=max(y), color='r')
plt.show()
The produced plot is
If you are familiar with the properties of normal distribution, it is easy to know intersection with x axis is just mu, i.e., the distribution mean. Intersection with y axis is just the maximum value of y, i.e, max(y) in the code.

Plotting data with variable frequency vs elapsed time

I have a dataset in pandas with measurements acquired with varying sample time.
I'm trying to plot the data vs. elapsed time, but time axis gets messed up.
I've found info that use of .autofmt_xdate() should solve the issue, but works only for data with fixed sampling frequency. In case of my data the x axis is entirely missing any labels.
a simple example of both cases
import pandas as pd
import matplotlib.pyplot as plt
idx1 = pd.to_timedelta(['00:00:00', '00:00:30', '00:01:00', '00:01:30', '00:02:00'])
idx2 = pd.to_timedelta(['00:00:01', '00:00:30', '00:01:00', '00:01:30', '00:02:00'])
vals = range(5)
s1= pd.Series(vals, idx1)
s2= pd.Series(vals, idx2)
# Labels on x are ok
plt.figure()
plt.gca().set_title('fixed frequency f=30s')
s1.plot()
plt.gcf().autofmt_xdate()
plt.show()
# Labels on x are messed up
plt.figure()
plt.gca().set_title('variable frequency')
s2.plot()
plt.gcf().autofmt_xdate()
plt.show()

'module' object has no attribute 'draw_all'

I am trying to use drawnow to plot a graph using python.
but there is always an error says that "drawnow has no attribute to draw-all"
I'm using python 3 and the latest version of drawnow
Thank you for your help!
import serial # import Serial Library
import numpy # Import numpy
import matplotlib.pyplot as plt #import matplotlib library
from drawnow import *
tempF= []
pressure=[]
arduinoData = serial.Serial('/dev/cu.usbmodem1451', 9600) #Creating our serial object named arduinoData
plt.ion() #Tell matplotlib you want interactive mode to plot live data
cnt=0
def makeFig(): #Create a function that makes our desired plot
plt.ylim(80,90) #Set y min and max values
plt.title('My Live Streaming Sensor Data') #Plot the title
plt.grid(True) #Turn the grid on
plt.ylabel('Temp F') #Set ylabels
plt.plot(tempF, 'ro-', label='Degrees F') #plot the temperature
plt.legend(loc='upper left') #plot the legend
plt2=plt.twinx() #Create a second y axis
plt.ylim(93450,93525) #Set limits of second y axis- adjust to readings you are getting
plt2.plot(pressure, 'b^-', label='Pressure (Pa)') #plot pressure data
plt2.set_ylabel('Pressrue (Pa)') #label second y axis
plt2.ticklabel_format(useOffset=False) #Force matplotlib to NOT autoscale y axis
plt2.legend(loc='upper right') #plot the legend
while True: # While loop that loops forever
while (arduinoData.inWaiting()==0): #Wait here until there is data
pass #do nothing
arduinoString = arduinoData.readline() #read the line of text from the serial port
dataArray = arduinoString.split(',') #Split it into an array called dataArray
temp = float( dataArray[0]) #Convert first element to floating number and put in temp
P = float( dataArray[1]) #Convert second element to floating number and put in P
tempF.append(temp) #Build our tempF array by appending temp readings
pressure.append(P) #Building our pressure array by appending P readings
drawnow(makeFig) #Call drawnow to update our live graph
plt.pause(.000001) #Pause Briefly. Important to keep drawnow from crashing
cnt=cnt+1
if(cnt>50): #If you have 50 or more points, delete the first one from the array
tempF.pop(0) #This allows us to just see the last 50 data points
pressure.pop(0)

Resources