0

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..

1
  • 1
    Note the answer in this question stackoverflow.com/questions/3843017/… , which produces a list of the zero-crossings in your data. Wouldn't that be enough? Commented Oct 27, 2022 at 17:43

1 Answer 1

0

@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()
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.