2

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.

Jorenko
  • 2,594
  • 2
  • 21
  • 26
  • Ok, edited my answer to try and use you data, hope it works now! – Rodrigo Feb 17 '09 at 16:33
  • So, you need to have precision on nanoseconds and want to plot seconds of data? That surely is a problem, as for 1s you'll have 1e9 points... I guess I'm having trouble to understand what is it you're trying to show on this graphic... – Rodrigo Feb 18 '09 at 00:10
  • It's not that I care about having perfectly accurate, visually discernible nanosecond resolution, but rather that the graphing algorithm needs to check for new edges at that resolution so it doesn't miss short pulses, like this: [(10.0, 0), (10.00000001, 1), (10.00000002, 0), (11.0, 1), (12.0, 0)] – Jorenko Feb 18 '09 at 13:25
  • For the data in my last comment, I'd expect to see a pulse so short that it's really just a 1-pixel vertical line at 10. – Jorenko Feb 18 '09 at 13:30

7 Answers7

2

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

ubiyubix
  • 1,036
  • 9
  • 13
2

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

alif
  • 619
  • 1
  • 6
  • 10
1
#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
Daniel Woodard
  • 103
  • 1
  • 2
1

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_

Rodrigo
  • 5,938
  • 6
  • 31
  • 39
  • By the way, I noticed that the docstring for function_plot claims you can pass a dict of {"label":fn()} into it to get multiple labelled plots. But, when I do this, it punks out complaining that I didn't give it a callable. – Jorenko Feb 17 '09 at 21:54
  • Also, looks like you're the maintainer for CairoPlot? You may be interested to know that it breaks in python 2.4 because max only added kwargs support in 2.5. – Jorenko Feb 17 '09 at 21:55
  • @Jorenko man, are you using the trunk version or the 1.1 version? If it's the trunk, dictionaries of functions should be working (and I'll have to take a look). If it's v1.1, the docstring must be wrong. – Rodrigo Feb 18 '09 at 00:03
  • @Jorenko Oh, and yes, i'm the maintainer. And I was aware of that 2.4 bug. Must find a way to fix it yet... – Rodrigo Feb 18 '09 at 00:06
0

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

joeforker
  • 40,459
  • 37
  • 151
  • 246
0

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.

Parand
  • 102,950
  • 48
  • 151
  • 186
0

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.

Community
  • 1
  • 1
Dave
  • 3,834
  • 2
  • 29
  • 44