Quick and dirty stripchart in python?

12.8k Views Asked by At

I have some python code that receives a message every so often containing a timestamp and an edge transition, either low-to-high, or high-to-low. I'd like to graph each transition on a stripchart for a quick and dirty visualization of the digital waveform with the minimal amount of effort.

Can you recommend any methods or packages that would make this easy?

I'm also not opposed to exporting the data in, for instance, csv format and loading it into another program if that would be easier.

Edit:

Tried CairoPlot:

>>> data = [(10, 0), (11, 1), (12.5, 0), (15, 1)]
>>> def fn(t):
...     for d in data:
...             if t > d[0]:
...                     return d[1]
...     return data[-1][1]
...
>>> CairoPlot.function_plot( 'tester.png', data, 500, 300, discrete = True, h_bounds=( data[0][0],data[-1][0]), step = 1 )

This pinned my CPU at 100% for more than 10 minutes and was steadily eating memory. I killed it before it used up all of swap. Am I doing something wrong or is CairoPlot just broken?

Further edit:

I now have something more workable using CairoPlot, based loosely on the above code. However, it's not perfect because of the resolution: I may need up to tens of nanoseconds (1e-8) resolution in order to catch some of the shorter pulses. For a multi-second graph, this takes a very long time with this method.

7

There are 7 best solutions below

0
On

I haven't use it myself, but perhaps Cairo Plot is worth taking a look at.

4
On

you may try using CairoPlot:

import CairoPlot

#the data list stands for your low-to-high (1) and high-to-low (0) data
data = lambda x : [0,0,1,1,0,0,1][x]
CairoPlot.function_plot( 'Up_and_Down', data, 500, 300, discrete = True, x_bounds=( 0,len(data) - 1 ), step = 1 )

For more information, check CairoPlot

Edit:

I didn't understand your function fn(t) here. The idea of the function_plot is to plot a function not a vector.

To plot those points, you could use function_plot on this way:

#notice I have split your data into two different vectors,
#one for x axis and the other one for y axis
x_data = [10, 11, 12.5, 15]
y_data = [0, 1, 0, 1]

def get_data( i ):
    if i in x_data :
        return y_data[x_data.index(i)]
    else :
        return 0

CairoPlot.function_plot( 'Up_and_Down', get_data, 500, 300, discrete = True, x_bounds=( 0,20 ), step = 0.5 )

I guess that will work

For the 100% pinning CPU, that shouldn't happen... I'll take a look at it later today. Thanks for pointing it \o_

0
On

http://bitworking.org/projects/sparklines/ provides a tiny graph for you.

0
On

GnuPlot is a the old reliable answer here, easy graphing with lots of options. I believe there are python bindings but it's probably easier to export your data and run it through regular gnuplot. Here's an ancient quick start doc for it.

I'm also using matplotlib with great success for larger data sizes.

0
On

Matplotlib might work. Take a look at this strip chart demo.

0
On
#simple stripchart using pygame
import pygame, math, random                   
white=(255,255,255)                             #define colors                      
red=(255,0,0)
pygame.init()                                   #initialize pygame
width=1000
height=200
size=[width,height]                             #select window size
screen=pygame.display.set_mode(size)            #create screen
pygame.display.set_caption("Python Strip Chart")
clock=pygame.time.Clock()
data=[]
for x in range (0,width+1):
        data.append([x,100])

# -------- Event Loop -----------
while (not pygame.event.peek(pygame.QUIT)):     #user closed window
        for x in range (0,width):
                data[x][1]=data[x+1][1]       #move points to the left
        t=pygame.time.get_ticks()            #run time in milliseconds
        noise=random.randint(-10,10)         #create random noise
        data[width][1]=100.-50.*math.sin(t/200.) +noise #new value
        screen.fill(white)                         #erase the old line
        pygame.draw.lines(screen, red, 0,data,3)   #draw a new line
        clock.tick(150)                            #regulate speed
        pygame.display.flip()                  #display the new screen
pygame.quit ()                                #exit if event loop ends
0
On

For a realtime stripchart application using only tkinter (no external packages required), see What is the best real time plotting widget for wxPython?.

If I understand your question, you are receiving messages in realtime with nanosecond resolution timestamps, but you don't expect to see 10^9 messages per second. If the average message rate is low (100 messages per second or fewer), I'd just ignore the timestamp and plot the transitions one message at a time. If the graph timescale is 10ms per pixel, 4 transitions would be drawn over 40ms, but at least you wouldn't miss seeing that something happened.