2
\$\begingroup\$

I have written an error analyzer in Python for the product of our company. I want to read the log from our device and parse it, On Y axis there are different components of the device, and on X axis there is time scale, there is a condition that two errors cannot appear at the same time. As the device doesn't support logging for now, I had to simulate it in Python. Error state is "1", non-error is "0", if error appears I write the error's number on the top between edges. I have added the slider, and when I change it's position I redraw everything, it slows the program, any hints how to implement it in a better way? EVENT_SIZE can be thousands. I am newbie in Python, so i will be glad to hear any programming pracises.

import numpy as np
import random
import matplotlib.pyplot as plt
from matplotlib.widgets import Slider

Y_AXIS_NAMES = ["NAME #1", "NAME #2", "NAME #3", "NAME #4", "NAME#5"]
Y_AXIS_VALUES = [i for i in range(1, len(Y_AXIS_NAMES)*2, 2)]

EVENT_SIZE = 50

Y_AXIS_MIN_VALUE = 0
Y_AXIS_MAX_VALUE = Y_AXIS_VALUES[-1] + 2

def DrawGrid(ax, pos, *args, **kwargs):
    if ax == 'x':
        for p in pos[::10]:
            plt.axvline(p, *args, **kwargs)
    else:
        for p in pos[::10]:
            plt.axhline(p, *args, **kwargs)

def ShowErrorPoints(ax, ay, offset):
    for i in zip(ax[1::2], ay[1::2]):
        if(i[0][0] == 1):
             plt.plot(i[1], offset+1, marker='o', color='r', markersize = 5)
             plt.annotate( i[0][1],
                           xy=(i[1]+0.1, offset+1+0.3),
                           #xytext=(i[1], offset),     
                           textcoords='data',
                           horizontalalignment='right',
                           verticalalignment='top',
                           )
             #plt.plot(i[1], offset+1, marker='o', color='r', markersize = 5, label='$ID: {}$'.format(i[0][1]))
             #datacursor(formatter='{label}'.format)

def update(val):
    new_pos = axslider.val
    ax.set_xbound(new_pos-viewwindow, new_pos+viewwindow)
    fig.canvas.draw_idle()

randBinList = lambda n: [random.randint(0,1) for b in range(1,n+1)]

######################
#Simulate input values
######################
first   = np.array(randBinList(EVENT_SIZE))
second_ = np.array(randBinList(EVENT_SIZE))
third_  = np.array(randBinList(EVENT_SIZE))
forth_  = np.array(randBinList(EVENT_SIZE))
fifth_  = np.array(randBinList(EVENT_SIZE))
mask    = np.zeros(EVENT_SIZE)

mask = np.logical_or   (mask,  first ).astype(int)
second = np.logical_and(1-mask, second_).astype(int)
mask = np.logical_or   (mask,  second_).astype(int)
third = np.logical_and (1-mask, third_).astype(int)
mask = np.logical_or   (mask,  third_).astype(int)
forth = np.logical_and (1-mask, forth_).astype(int)
mask = np.logical_or   (mask,  forth_)
fifth = np.logical_and (1-mask, fifth_).astype(int)
mask = np.logical_or   (mask,  fifth_)

first  = [[i, random.randint(1, 100)] for i in first]
second = [[i, random.randint(1, 100)] for i in second]
third  = [[i, random.randint(1, 100)] for i in third]
forth  = [[i, random.randint(1, 100)] for i in forth]
fifth  = [[i, random.randint(1, 100)] for i in fifth]

first  = np.repeat(first, [2], axis = 0)
second = np.repeat(second,[2], axis = 0)
third  = np.repeat(third, [2], axis = 0)
forth  = np.repeat(forth, [2], axis = 0)
fifth  = np.repeat(fifth, [2], axis = 0)

t = 0.5 * np.arange(EVENT_SIZE*2)

###############
#Building plots
###############
fig, ax = plt.subplots()
plt.hold(True)
plt.subplots_adjust(left=0.15, bottom=0.25)
plt.yticks(Y_AXIS_VALUES, Y_AXIS_NAMES)

DrawGrid('x', range(EVENT_SIZE+1), color='.5', linewidth=0.5)
DrawGrid('y', Y_AXIS_VALUES, color='.5', linewidth=0.5)

plt.title("Error decoder")
fig = plt.gcf()
fig.canvas.set_window_title('Decoder')

plt.step(t, [i[0] + 1 for i in first] , 'b', linewidth = 1, where='post')
plt.step(t, [i[0] + 3 for i in second], 'b', linewidth = 1, where='post')
plt.step(t, [i[0] + 5 for i in third] , 'b', linewidth = 1, where='post')
plt.step(t, [i[0] + 7 for i in forth] , 'b', linewidth = 1, where='post')
plt.step(t, [i[0] + 9 for i in fifth] , 'b', linewidth = 1, where='post')

ShowErrorPoints(first,  t, Y_AXIS_VALUES[0])
ShowErrorPoints(second, t, Y_AXIS_VALUES[1])
ShowErrorPoints(third,  t, Y_AXIS_VALUES[2])
ShowErrorPoints(forth,  t, Y_AXIS_VALUES[3])
ShowErrorPoints(fifth,  t, Y_AXIS_VALUES[4])

plt.ylim([0, Y_AXIS_MAX_VALUE])
plt.xlim([0, EVENT_SIZE])

viewwindow = 20

axcolor = 'lightgoldenrodyellow'
axpos = plt.axes([0.15, 0.1, 0.65, 0.03], axisbg=axcolor)
axslider = Slider(axpos, '', t[0]+viewwindow, t[-1]-viewwindow, valinit=(t[-1]+t[0])/2.0)

update(axslider.val)
axslider.on_changed(update)

plt.show()
\$\endgroup\$
  • \$\begingroup\$ It seems to work relatively smoothly for me... \$\endgroup\$ – Graipher Aug 8 '17 at 12:32
  • \$\begingroup\$ @Graipher if I increase EVENT_SIZE to 1000 the performance falls, and I would like to ask how to prevent it \$\endgroup\$ – Andrey Mazur Aug 9 '17 at 8:34

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.