Home > Back-end >  Optimum way to plot sine wave from oscilloscope .csv with matplotlib in python
Optimum way to plot sine wave from oscilloscope .csv with matplotlib in python

Time:11-03

I wish to plot 1 or 2 periods of a sine wave from csv data obtained from an oscilloscope.

the DF columns are

df columns

I have managed to produce something workable but it requires manual work for each new set of csv data. I am sure there is a better way.

The code I have finds the start and end times of one period by obtaining the row indexes where the amplitude is greater than zero but less than some manually inputted value obtained by trial and error. The thinking is that a sine wave willcross the x axis at the start and end of a period.

import pandas as pd
import matplotlib.pyplot as plot
import numpy as np

df = pd.read_csv("tek0000.csv", skiprows=20)
Sin_wave_vals = np.where((df['CH1'] >0)&(df['CH1'] <0.021))
// gives output (array([ 355,  604,  730, 1230, 1480, 1604, 1730, 2980, 3604, 3854, 4979,
    5230, 5980, 7730, 9355, 9980]),)

time_df = df['TIME']
# select the rows from the df for a single period
time_df =time_df.iloc[Sin_wave_vals[0][0]:Sin_wave_vals[0][1]]
amplitude_ch1 =  df.iloc[355:604,1]
plot.plot(time, amplitude_ch1)
plot.title('Sine wave')

plot.xlabel('Time')
plot.ylabel('Amplitude = sin(time)')
plot.grid(True, which='both')
plot.axhline(y=0, color='k')
plot.show()

This works ok and plots what I require, but will work out too manual as I have about 20 of these to plot. I tried to obtain the upper limit by using the following

upper_lim=min(filter(lambda x: x > 0, df['CH1']))
# returns 0.02
Sin_wave_vals = np.where((df['CH1'] >0)&(df['CH1'] <upper_lim))

However, this did not work out how I intended..

CodePudding user response:

@Tim Roberts that works well, thank you.

This function works for a clear wave, with noise and a low amplitude there is an issue as the wave can pass the x axis multiple times in a period.

def Plot_wave(df,title, periods, time_col_iloc, amp_col_iloc):
  ## the time and columns location in DF are final 2 arguments and ahould be int
  zero_crossings = np.where(np.diff(np.sign(df.iloc[:,1])))[0]
  if periods == 1:
    time = df.iloc[zero_crossings[0]:zero_crossings[2],[time_col_iloc]]
    amplitude =  df.iloc[zero_crossings[0]:zero_crossings[2],amp_col_iloc]
  if periods == 2:
    time = df.iloc[zero_crossings[0]:zero_crossings[4],[0]]
    amplitude =  df.iloc[zero_crossings[0]:zero_crossings[4],1]
  if periods > 2:
     return("please enter period of 1 OR 2")

  plot.plot(time, amplitude)
  plot.title(title)
  plot.xlabel('Time')
  plot.ylabel('Amplitude = sin(time)')
  plot.grid(True, which='both')
  plot.axhline(y=0, color='k')
  plot.show()
  • Related