kressi / terminalplot

GNU General Public License v3.0
49 stars 5 forks source link

modified for multiple y series and ansi colors #2

Open evert-mouw opened 6 years ago

evert-mouw commented 6 years ago

Hi, Yes this is not the correct way to send in changes but I'm not forking the whole project. For my own use I modified your script so I could add up to four data series on the y axis and have colors. I also made a few other small changes. Maybe you like the changes so others could use them as well.

terminalplot2.zip

crbyxwpzfl commented 1 year ago

hi @kressi i really like your terminal plotter and very cool addition with color, debug and multiplot abilitys @evert-mouw!

I try to use it as a live serial plotter for sensor data right on a rp2040. therefore I reposition the cursor so the next plot overwrites the previous.

    for w in range(1,rows+4):  # plus 4 to scroll plot to the top or plus 3 to keep plot at position
        print('\033[1A', end='\x1b[2K')

furthermore I a.pop(0) for any value above a certain len(a) to keep the plot scrolling.

https://github.com/kressi/terminalplot/assets/60987359/183c27cd-d250-4f91-a315-169f6e5d25c2

full python ### full python ```py import time import numpy import random def plot(rows, columns, x, a, b=[], c=[], d=[]): # offset for caption rows -= 4 colors = [ '\u001b[32;1m', '\u001b[34;1m', '\u001b[35;1m', '\u001b[36;1m', '\u001b[31;1m' ] normalcolors = '\u001b[0m' # undo color pointsymbols = [ colors[0] + "●", colors[1] + "⏺", colors[2] + "▆", colors[3] + "█", colors[4] + "-" ] # the last symbol is used for overlapping series series = 0 overlap = 4 # "X" # Create empty canvas canvas = [[" " for _ in range(columns)] for _ in range(rows)] # Scale points such that they fit on canvas y = list( a + b + c + d ) x_max = max( len(a), len(b), len(c), len(d) ) + 1 if x_max > len(x): x_max = len(x) x_scale = scaleCalc(x[:x_max], columns) x_scaled = scale(x, x_scale) y_scale = scaleCalc(y, rows) y_smallest = min(y) for q in (a, b, c, d): series += 1 # Scale y-axis series points such that they fit on canvas q_scaled = scale(q, y_scale, y_smallest) # Add scaled points to canvas for ix, iq in zip(x_scaled, q_scaled): if canvas[rows - iq - 1][ix] == ' ': canvas[rows - iq - 1][ix] = pointsymbols[series-1] else: canvas[rows - iq - 1][ix] = pointsymbols[overlap] # multiple y values on the same point # Print rows of canvas for i in range(rows): line = ''.join(str(e) for e in canvas[i]).rstrip() print(line) print(normalcolors.rstrip(), end='') # Print scale print(f"\n{round(min(x),4)}min/{round(max(x),4)}max x; {round(min(a),4)}min/{round(max(y),4)}max y; {rows}/{columns}aspect") # reposition cursor for w in range(1,rows+4): # plus 4 to scroll plot to the top or plus 3 to keep plot at position print('\033[1A', end='\x1b[2K') def scaleCalc(x, length): s = float(length - 1) / \ (max(x) - min(x)) if x and max(x) - min(x) != 0 else length return s def scale(x, scale, smallest=None): if smallest==None: smallest = min(x) return [int((i - smallest) * scale) for i in x] x = []; a = []; b = []; c = []; d = [] i = 1 while True: time.sleep(0.1) x.append(i) a.append(numpy.sin(i*0.3)) b.append(numpy.cos(i*0.3)) c.append(numpy.sin(-i*0.3)) d.append(random.randint(-1,1)) i += 1 if len(x) >= 20: # space between points x.pop(0); a.pop(0); b.pop(0); c.pop(0); d.pop(0) plot(20, 100, x, a, b, c, d) # determine canvas sice with x, y ```
kressi commented 1 year ago

Thanks a lot for the feedback and the shared example! I will have a closer look at it within the next couple of days.