3

I am trying to simulate the display of a sine wave one would generate from an oscilloscope using Python. As I am trying to merely simulate it (and not pull the data from the oscilloscope), I was wondering how I would show a continuous sine wave. I have the sample rate of the device (200MHz - 1GS/s), the frequency of my wave (1MHz), and the amplitude (1V). The data would be viewed in microseconds. I have read through various answers here on StackOverflow and have had problems with the plot having irregular waves or something of the sort. Is there a way to have this data shown like below? Oscilloscope data output I wish to simulate, for 1MHz freq, 100MS/s sample rate, amplitude of 1V.

A secondary problem is the ability to plot this wave continuously. For example, when using Matplotlib, if I zoom out it doesn't show the wave continuing past my interval. Is there a way to have the wave continually represented? I don't want to be tied down to Matplotlib, so I am looking for other solutions that continually creating (appending?) data in both directions. If this is not possible, is it possible to establish some sort of number of wavelengths in each direction?

Thank you so much!

import numpy as np
from scipy import signal
import matplotlib.pyplot as plt

Fs = 20E3
f = 1E6
sample = Fs/f
print(sample)
x = np.arange(sample)

y = 100*np.sin(2 * np.pi * f * x / Fs)

plt.plot(x, y)
plt.show()
15
  • Can you show your code? Commented Apr 11, 2018 at 15:24
  • Are you in Windows or Linux ? Commented Apr 11, 2018 at 15:25
  • Do you want one image or do you want to have a dynamic display ? Commented Apr 11, 2018 at 15:27
  • 1
    @Imas That's alright, providing code (even if it doesn't do what you want it to do), allows other users to more easily develop code that fits in with what you're doing in a way that you can understand, it also shows that you've given the problem some thought and research before coming to SO Commented Apr 11, 2018 at 15:36
  • 1
    Your code above won't plot anything, given that np.arange(20e3/1e6) will return array([ 0. ]). It looks like you want f to be your wave frequency, and Fs to be your sampling frequency. Why is your sampling frequency lower than your wave frequency? Your waveform won't look very good if you do that. Commented Apr 11, 2018 at 17:35

1 Answer 1

1

You could use matplotlib.animation to achieve your goal.

I took an existing example which emulates an oscilloscope and adjusted it to your needs (e.g. sine wave & plotting continously).

Regarding the continous plotting: I set up a continous variable, where you can choose if you want to plot it continously (not able to zoom) or not (able to zoom). I wasn't able to combine both functionalities in one plot yet. So just run the code once with continous = True and once with continous = False to see if it suits your needs.

But I think this could be a good start for plotting continous sine waves.

import numpy as np
from matplotlib.lines import Line2D
import matplotlib.pyplot as plt
import matplotlib.animation as animation

# Your Parameters
amp = 1         # 1V        (Amplitude)
f = 1000        # 1kHz      (Frequency)
fs = 200000     # 200kHz    (Sample Rate)
T = 1/f
Ts = 1/fs

# Select if you want to display the sine as a continous wave
#  True = Continous (not able to zoom in x-direction)
#  False = Non-Continous  (able to zoom)
continous  = True

x = np.arange(fs)
y = [ amp*np.sin(2*np.pi*f * (i/fs)) for i in x]


class Scope(object):
    def __init__(self, ax, maxt=2*T, dt=Ts):
        self.ax = ax
        self.dt = dt
        self.maxt = maxt
        self.tdata = [0]
        self.ydata = [0]
        self.line = Line2D(self.tdata, self.ydata)
        self.ax.add_line(self.line)
        self.ax.set_ylim(-amp, amp)
        self.ax.set_xlim(0, self.maxt)

    def update(self, y):
        lastt = self.tdata[-1]
        if continous :
            if lastt > self.tdata[0] + self.maxt:
                self.ax.set_xlim(lastt-self.maxt, lastt)

        t = self.tdata[-1] + self.dt
        self.tdata.append(t)
        self.ydata.append(y)
        self.line.set_data(self.tdata, self.ydata)
        return self.line,


def sineEmitter():
    for i in x:
        yield y[i]


fig, ax = plt.subplots()
scope = Scope(ax)

# pass a generator in "sineEmitter" to produce data for the update func
ani = animation.FuncAnimation(fig, scope.update, sineEmitter, interval=10,
                              blit=True)

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