Add termplotter module for plotting to the stdout
authorDan White <dan@whiteaudio.com>
Sun, 26 Aug 2012 02:45:02 +0000 (21:45 -0500)
committerDan White <dan@whiteaudio.com>
Sun, 26 Aug 2012 02:45:02 +0000 (21:45 -0500)
python-lib/termplotter.py [new file with mode: 0644]

diff --git a/python-lib/termplotter.py b/python-lib/termplotter.py
new file mode 100644 (file)
index 0000000..b1a1d28
--- /dev/null
@@ -0,0 +1,85 @@
+
+import curses
+from math import log10, floor
+
+DEBUG = False
+
+
+def ndigits(n):
+    return int(floor(log10(float(n))))
+
+class TermPlotter(object):
+    def __init__(self, limits=[-1.0, 1.0], width=None, leader=None):
+        if width is None:
+            curses.setupterm()
+            self.width = curses.tigetnum('cols')
+        else:
+            self.width = width
+        
+        self.pmin = limits[0]
+        self.pmax = limits[1]
+        if leader is None:
+            span = self.pmax - self.pmin
+            m = ndigits(max(map(lambda x: abs(x), limits))) + 1
+            mantissa_len = m #max(m, 1)
+            resolution_len = ndigits(self.width) + 2
+            fraction_len = resolution_len - mantissa_len
+            fwidth = resolution_len + 2
+            if mantissa_len == 0:
+                fwidth += 1
+            s = '%%%i.0%if' % (fwidth, fraction_len)
+            self.leader = s + ' '
+        else:
+            self.leader = leader
+
+        self.leadlen = len(self.leader % 0.0)
+        self.w = self.width - self.leadlen
+
+    def __call__(self, num):
+        return self.line(num)
+
+    def limitvalue(self, num):
+        return min(max(num, self.pmin), self.pmax)
+
+    def f2index(self, num):
+        n = self.limitvalue(num)
+        idx = int(round((n - self.pmin) * (self.w-1) / (self.pmax - self.pmin)))
+        return idx
+
+    def line(self, num):
+        #blank axis
+        s = self.leader % num
+        s += '|' + ' '*(self.w - 2) + '|'
+        sl = list(s)
+
+        #center
+        sl[self.f2index(0.0)+self.leadlen] = '.'
+
+        #number
+        sl[self.f2index(num)+self.leadlen] = 'X'
+        sn = ''.join(sl)
+        return sn
+
+
+
+
+if __name__ == '__main__' or DEBUG:
+    from time import sleep
+    from numpy.random import randn
+    from math import pi, sin
+
+    def getnum():
+        p = 0.0
+        while True:
+            #yield randn()/1.0
+            yield sin(p)
+            p += pi/100
+
+    while True:
+        #tp = TermPlotter(limits=[-1.0, 1.0], width=80)
+        tp = TermPlotter(limits=[-1.0, 1.0])
+        for n in getnum():
+            sn = tp.line(n)
+            print sn
+            sleep(0.02)
+