--- /dev/null
+
+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)
+