Realtime Data Plotting in Python


WARNING: this project is largely outdated, and some of the modules are no longer supported by modern distributions of Python.

For a more modern, cleaner, and more complete GUI-based viewer of realtime audio data (and the FFT frequency data), check out my Python Real-time Audio Frequency Monitor project.

I love using python for handing data. Displaying it isn’t always as easy. Python fast to write, and numpy, scipy, and matplotlib are an incredible combination. I love matplotlib for displaying data and use it all the time, but when it comes to realtime data visualization, matplotlib (admittedly) falls behind. Imagine trying to plot sound waves in real time. Matplotlib simply can’t handle it. I’ve recently been making progress toward this end with PyQwt with the Python X,Y distribution. It is a cross-platform solution which should perform identically on Windows, Linux, and MacOS. Here’s an example of what it looks like plotting some dummy data (a sine wave) being transformed with numpy.roll().

How did I do it? Easy. First, I made the GUI with QtDesigner (which comes with Python x,y). I saved the GUI as a .ui file. I then used the pyuic4 command to generate a python script from the .ui file. In reality, I use a little helper script I wrote designed to build .py files from .ui files and start a little “” file which imports all of the ui classes. It’s overkill for this, but I’ll put it in the ZIP anyway.  Here’s what the GUI looks like in QtDesigner:


After that, I tie everything together in a little script which updates the plot in real time. It takes inputs from button click events and tells a clock (QTimer) how often to update/replot the data. Replotting it involves just rolling it with numpy.roll().  Check it out:

import ui_plot #this was generated by pyuic4 command
import sys
import numpy
from PyQt4 import QtCore, QtGui
import PyQt4.Qwt5 as Qwt

ys=numpy.sin(3.14159*xs*10/numPoints) #this is our data

def plotSomething():
    global ys
    c.setData(xs, ys)

if __name__ == "__main__":
    app = QtGui.QApplication(sys.argv)
    win_plot = ui_plot.QtGui.QMainWindow()
    uiplot = ui_plot.Ui_win_plot()

    # tell buttons what to do when clicked
    uiplot.btnB.clicked.connect(lambda: uiplot.timer.setInterval(100.0))
    uiplot.btnC.clicked.connect(lambda: uiplot.timer.setInterval(10.0))
    uiplot.btnD.clicked.connect(lambda: uiplot.timer.setInterval(1.0))

    # set up the QwtPlot (pay attention!)
    c=Qwt.QwtPlotCurve()  #make a curve
    c.attach(uiplot.qwtPlot) #attach it to the qwtPlot object
    uiplot.timer = QtCore.QTimer() #start a timer (to call replot events)
    uiplot.timer.start(100.0) #set the interval (in ms)
    win_plot.connect(uiplot.timer, QtCore.SIGNAL('timeout()'), plotSomething)

    # show the main window

I’ll put all the files in a ZIP to help out anyone interested in giving this a shot. Clicking different buttons updates the graph at different speeds. If you make something cool with this concept, let me know! I’d love to see it.



14 thoughts on “Realtime Data Plotting in Python

  1. Hi Scott, I live in Gainesville too (although I’m not a student), and I’m currently learning python. Are there any good resources / meetup groups for programmers that I should look into? Thanks.

  2. Hi Scott, very cool post, very useful. Many packages I have seen (Pyopencv, pyODE) seem to recommand pygame for fast plotting, but it is a pain to display mathematical stuff in a pygame window (everything must be converted into pixels). On my computer, I manage to display with Matplotlib in quasi-real time the stream of my webcam using imshow(), but certainly on less powerfull machines your solution will be preferable.

  3. Qwt is not your only option and in fact probably not the best one. The fact it is quite fast is more-or-less its only advantage. For more flexible real-time data display, I recommend Traits + Chaco + Enaml (all by enthought, at I have recently built a waveform analysis application with these (w/ real-time display) and can really recommend them. Note, Enaml (the new GUI design declarative language and library) can also embed matplotlib figures but matplotlib seems to throttle its update rate so it’s difficult to get very responsive plots. Enaml uses either wxPython or PyQt as it’s GUI backend so it can easily integrate with existing PyQt stuff.

    I wrote a chaco example to mirror your Qwt example. It will happily process events at ~ 50/second while the rest of the GUI remains fully responsive. I’m trying to find somewhere to post it…

    • I also use Traits and highly recommend it for its ease-of-use and flexibility. I’ve written a fully interactive tool for spectral analysis that has sped up work which used to take weeks into minutes. There are definitely a few GUI modules available now for Python, and they’re getting better and better!

    • Also @bc: Are you sure it was matplotlib throttling the updates? Creating the figure/axes is what takes the longest amount of time, but if you just update an existing plot with: scat = ax.scatter(…);scat.set_offsets(x, y), or similarly use set_data for plots, then you cut out a lot of the refresh lag than if you were re-building the figure and axes canvas every time.

      • Some time back, I benchmarked the drawing speed of matplotlib and found it surprisingly fast (esp for large datasets where it uses decimation to speed up rendering). However, when I tried a quick test with MPL + Enaml today, I found a rather slow update rate compared with Chaco. I didn’t investigate this further but assumed there is something in MPL which is limiting the redrawing rate (to avoid saturating CPU etc.). I.e. I think the slow update is by design, knowing that the core drawing calls can be much faster. In my test, I was not re-creating the figure or axes; just calling set_data(…) on the line artist.

  4. Hello !!

    I would like to know how can i open a python script to plot the data in the realtime. the data as follows:


    0 0.217413641411 0

    0.001 0.202640969807 0

    0.002 0.13284039654 0

    0.003 0.111942324101 0

    0.004 0.0806826346525 0

    This data is being sent from a C file as an output.

    In python, i would like read each line and update it in the graph realtime. can you help me as how do i go about this

  5. Dear Scott,

    I’m part of a research group trying to make a python program for us research. We are from Rio de Janeiro (Brazil) and we are trying to run your code but this is a common problem when we try:

    Traceback (most recent call last):
    File “”, line 1, in
    import ui_plot
    File “/home/moreiras/Documentos/ProjetoIC/qwtplot-example-python/”, line 10, in
    from PyQt4 import QtCore, QtGui
    RuntimeError: the sip module implements API v10.0 to v10.1 but the PyQt4.QtCore module requires API v9.2

    If possible, please help us.


    Felipe Moreira.

  6. Scott;
    I’m an old HAM radio hardware guy, but I Think I can make a 0-30 MHz Spectrum analyzer with this if I can get it to work.
    I installed Python 3.4 but the PyQwt apparently wont work with it.
    I keep getting this:
    Traceback (most recent call last):
    File “”, line 1, in
    import ui_plot
    File “”, line 56, in
    from PyQt4 import Qwt5
    ImportError: cannot import name ‘Qwt5’
    I assume I have a too new version of python ??
    What version should I use ??
    As you can tell programming is not my thing.