Example #1
1
class MonitorWindow(PanedWindow):
    def __init__(self, master, skeleton):
        PanedWindow.__init__(self, master=master, height=400)
        self.skeleton = skeleton

        self.figure = Figure(figsize=(5,4), dpi=100)

        self.subplots = {}

        nrows = len(self.skeleton.units)
        ncols = 3
        plot_counter = 1

        for u in self.skeleton.units.keys():
            subplots = [None, None, None]
            history = self.skeleton.units[u].history()
            t = range(0, len(history[0]))

            for a in range(0, 3):
                subplot = self.figure.add_subplot(nrows, ncols, plot_counter, xlim=[0,200], ylim=[-90,90])
                s = history[a]
                subplot.plot(t,s)
                plot_counter += 1
                subplots[a] = subplot

            self.subplots[u] = subplots

        self.canvas = FigureCanvasTkAgg(self.figure, master=self)
        self.canvas.show()
        self.canvas.get_tk_widget().pack(side="top", fill="both", expand=1)

        self.canvas.mpl_connect("key_press_event", self.pressed_key)

        self.pack(fill="both", expand="yes")

    def redraw_graph(self):
        plot_counter = 1

        for k, axes in self.subplots.iteritems():
            history = self.skeleton.units[k].history()
            t = range(0, len(history[0]))

            for a, subplot in enumerate(axes):
                s = history[a]
                subplot.plot(t,s)
                plot_counter += 1

                subplot.clear()
                subplot.plot(t,s)

                subplot.set_xlim([0, 200])
                subplot.set_ylim([-90, 90])

        self.canvas.draw()

    def pressed_key(self, event):
        if event.key == "r":
            self.redraw_graph()
        else:
            print("Key pressed: %s" % event.key)
Example #2
0
class Graph(tk.Frame,object):
	def __init__(self,master=None,onClick=None,xSize=40,ySize=30):
		self.onClick=(lambda x,y,z:None) if onClick is None else onClick
		tk.Frame.__init__(self,master)

		self.f = Figure(figsize=(4,4), dpi=100)		# return a matplotlib.figure.Figure instance, Höhe und Breite in Inches
		self.a = self.f.add_subplot(111)		# Add a subplot with static key "111" and return instance to it
		
		self.a.grid(True)				# Set the axes grids on

		self.a.set_xlim((0,ySize))
		self.a.set_ylim((0,xSize))
		
		self.canvas = FigureCanvasTkAgg(self.f, master=self)	# The Canvas widget provides structured graphics facilities for Tkinter.
		self.canvas.mpl_connect('button_press_event', self.rawOnClick)
		
		self.canvas.show()				# Aus matplotlib: display all figures and block until the figures have been closed
		self.canvas.get_tk_widget().pack(side=tk.TOP, fill=tk.BOTH, expand=1)

	def addline(self,x,y):
		self.curline=matplotlib.lines.Line2D([y],[x])
		self.a.add_line(self.curline)

	def append(self,x,y):
		y0,x0=self.curline.get_data()
		x0.append(x)
		y0.append(y)
		self.curline.set_data(y0,x0)
		self.canvas.draw()

	def rawOnClick(self,evt):
		print evt.key
		both=True if evt.key=='shift' else False
		self.onClick(evt.ydata, evt.xdata, both)
Example #3
0
class LiveGraphTk(Backend):
    """ LiveGraph backend for Tkinter.

    """

    def show(self, delay):

        if self.master is None:
            self.root = Tk.Toplevel()
            self.master = self.root
        else:
            self.root = Tk.Toplevel(self.master)

        self.canvas = FigureCanvasTkAgg(self.figure, master=self.root)
        #self.canvas.get_tk_widget().pack(side=Tk.TOP, fill=Tk.BOTH, expand=1)

        self.toolbar = NavigationToolbar2TkAgg(self.canvas, self.root)
        self.toolbar.update()
        self.canvas._tkcanvas.pack(side=Tk.TOP, fill=Tk.BOTH, expand=True)

        self.canvas.mpl_connect('key_press_event', self.on_key_event)

        self.root.protocol("WM_DELETE_WINDOW", self.close)

        super().show(delay)

    def run(self, delay):
        """Calls the update method periodically with the delay in milliseconds.

        Decrease the delay to make the plotting smoother and increase it to
        reduce the preformance. For live plotting the delay must fit the rate
        of the incoming data.

        Keyword arguments:
        delay -- the delay in millisconds after each call (default 50)

        """

        super().run()
        self.root.after(delay, self.run, delay)

    @property
    def visible(self):
        if self.root.state() in ['normal', 'zoomed']:
            return True
        else:
            return False

    @visible.setter
    def visible(self, boolean):
        if boolean:
            self.root.deiconify()
        else:
            self.root.withdraw()

        self.visible = False

    def close(self):
        super().close()
        self.master.destroy()
Example #4
0
    def __init__(self, root, controller):
        f = Figure()
        ax = f.add_subplot(111)
        ax.set_xticks([])
        ax.set_yticks([])
        ax.set_xlim((x_min, x_max))
        ax.set_ylim((y_min, y_max))
        canvas = FigureCanvasTkAgg(f, master=root)
        canvas.show()
        canvas.get_tk_widget().pack(side=Tk.TOP, fill=Tk.BOTH, expand=1)
        canvas._tkcanvas.pack(side=Tk.TOP, fill=Tk.BOTH, expand=1)
        canvas.mpl_connect('button_press_event', self.onclick)
        toolbar = NavigationToolbar2TkAgg(canvas, root)
        toolbar.update()
        self.controllbar = ControllBar(root, controller)
        self.menubar = MenuBar(root, controller)
        self.f = f
        self.ax = ax
        self.canvas = canvas
        self.controller = controller
        self.contours = []
        self.tube = []
        self.c_labels = None
        self.plot_kernels()

        self.class_colors = ('b', 'r', 'g', 'y')
Example #5
0
class PlotWindow(Frame):
    """

    """

    def __init__(self, parent, figure, plotType=None):
        """
        Constructor

        @param parent:
        @param figure:
        @param plotType:
        @return
        """
        Frame.__init__(self, parent)

        # a tk.DrawingAre
        self.plotType = plotType
        self.canvas = FigureCanvasTkAgg(figure, master=self)
        self.canvas.show()
        self.canvas.get_tk_widget().pack(side=TOP, fill=BOTH, expand=1)
        self.toolbar = NavigationToolbar2TkAgg(self.canvas, self)
        self.toolbar.update()
        self.canvas._tkcanvas.pack(side=TOP, fill=BOTH, expand=1)
        self.canvas.mpl_connect('key_press_event', self.on_key_event)

    def getPlotType(self):
        """

        @return
        """
        return self.plotType

    def updateFigure(self, figure):
        """

        @param figure:
        @return
        """

        self.canvas._tkcanvas.pack_forget()

        self.canvas = FigureCanvasTkAgg(figure, master=self)
        self.canvas.show()
        self.canvas.get_tk_widget().pack(side=TOP, fill=BOTH, expand=1)

        self.toolbar = NavigationToolbar2TkAgg(self.canvas, self)
        self.toolbar.update()
        self.canvas._tkcanvas.pack(side=TOP, fill=BOTH, expand=1)

        self.canvas.mpl_connect('key_press_event', self.on_key_event)

    def on_key_event(self, event):
        """

        @param event:
        @return
        """
        print('you pressed %s' % event.key)
        key_press_handler(event, self.canvas, self.toolbar)
 def __init__(self, root, f):
     Tk.Frame.__init__(self, root)
     
     # a tk.DrawingArea
     canvas = FigureCanvasTkAgg(f, root)
     canvas.show()
     canvas.get_tk_widget().pack(side=Tk.TOP, fill=Tk.BOTH, expand=1)
     
     toolbar = NavigationToolbar2TkAgg(canvas, root)
     toolbar.update()
     canvas._tkcanvas.pack(side=Tk.TOP, fill=Tk.BOTH, expand=1)
     
     
     def on_key_event(event):
         print('you pressed %s' % event.key)
         key_press_handler(event, canvas, toolbar)
     
     canvas.mpl_connect('key_press_event', on_key_event)
     
     
     def _quit():
         root.quit()     # stops mainloop
         root.destroy()  # this is necessary on Windows to prevent
                         # Fatal Python Error: PyEval_RestoreThread: NULL tstate
     
     button = Tk.Button(root, text='Quit', command=_quit)
     button.pack(side=Tk.BOTTOM)
    def __init__(self, master, controller):

        def onClick(event):
            global pause
            pause ^= True

        global ser, instrument

        Frame.__init__(self, master)

        self.graphframe = Frame(self)
        self.graphframe.pack(side = TOP, fill=BOTH, expand=True)
        self.filenameframe = Frame(self)
        self.filenameframe.pack(side = BOTTOM, fill=BOTH, pady = 10)
        self.browseframe = Frame(self)
        self.browseframe.pack(side = BOTTOM, fill=BOTH, pady = 10)

        self.title = ttk.Label(self.graphframe, text = "Pressure Reading from Pads", font = ("", "14", "bold"))
        self.title.pack(pady = 10, padx = 10)


        # figure window
        canvas = FigureCanvasTkAgg(f, self.graphframe)
        canvas.show()
        canvas.get_tk_widget().pack(side=BOTTOM, fill=BOTH, expand=True)
        canvas.mpl_connect('button_press_event', onClick)

        toolbar = NavigationToolbar2TkAgg(canvas, self.graphframe)
        toolbar.update()
        canvas._tkcanvas.pack(side=TOP, fill=BOTH, expand=True)

        self.filepath = StringVar()
        self.filename = StringVar()

        self.filename.set(str(strftime("%d-%m-%Y_%H%M", gmtime())) + '.mid')

        browse_label = ttk.Label(self.browseframe, text = "Save MIDI file in:")
        browse_label.pack(side = LEFT, fill=Y, padx = 5)
        self.browse_filepath = ttk.Entry(self.browseframe, textvariable = self.filepath)
        self.browse_filepath.pack(side = LEFT, fill=X, expand=True, padx = 5)
        browse_button = ttk.Button(self.browseframe, text = "Browse", command = self.askopenfile)
        browse_button.pack(side = LEFT, fill=BOTH, padx = 5)

        filename_label = ttk.Label(self.filenameframe, text = "MIDI filename:")
        filename_label.pack(side = LEFT, fill=Y, padx = 5)
        self.saveFileName = ttk.Entry(self.filenameframe, textvariable = self.filename)
        self.saveFileName.pack(side = LEFT, fill=X, expand=True, padx = 5)
        browse_button = ttk.Button(self.filenameframe, text = "Save", command = self.savefile)
        browse_button.pack(side = LEFT, fill=BOTH, padx = 5)
Example #8
0
 def __init__(self, master):
     super(ImageFrame, self).__init__(master)
     figure = Figure((5,4), dpi=100)
     self.figure = figure
     canvas = FigureCanvasTkAgg(figure, master=master)
     canvas.mpl_connect('button_press_event', self._on_click)
     canvas.mpl_connect('key_press_event',self._on_keypress)
     canvas.show()
     self.__canvas  = canvas
     toolbar    = NavigationToolbar2TkAgg(canvas, master)
     toolbar.update()
     canvas.get_tk_widget().pack(side=TOP, fill=BOTH, expand=YES)
     toolbar.pack()
     self.axes   = figure.add_subplot(111)
     self.peakFinder = PeakFinder(self.axes, canvas)
Example #9
0
 def __init__(self, master):
     super().__init__(master)
     figure = Figure((5,4), dpi=100)
     self.figure = figure
     canvas = FigureCanvasTkAgg(figure, master=master)
     canvas.mpl_connect('button_press_event', self._on_click)
     canvas.mpl_connect('key_press_event',self._on_keypress)
     canvas.draw()
     self.__canvas  = canvas
     toolbar    = NavigationToolbar2TkAgg(canvas, master)
     toolbar.update()
     canvas.get_tk_widget().pack(side='top', fill='both', expand='yes')
     toolbar.pack()
     self.axes   = figure.add_subplot(111)
     self.__rectselector = RectSelector(self.axes, canvas)
Example #10
0
def draw():
    def on_key_event(event):
        print('you pressed %s' % event.key)
        key_press_handler(event, canvas, toolbar)
    
    fig = Figure(figsize=(5, 4), dpi=100)
    ax = fig.add_subplot(111)
    x = arange(0.0, 3.0, 0.01)
    y=eval(entry.get()+"(x)")
    ax.set_title(entry.get())
    ax.plot(x, y)
    ax.set_xlabel('x')
    ax.set_ylabel('y')
    canvas = FigureCanvasTkAgg(fig, master=root)
    canvas.show()
    canvas.get_tk_widget().pack(side=Tk.TOP, fill=Tk.BOTH, expand=1)
    toolbar = NavigationToolbar2TkAgg(canvas, root)
    toolbar.update()
    canvas._tkcanvas.pack(side=Tk.TOP, fill=Tk.BOTH, expand=1)
    canvas.mpl_connect('key_press_event', on_key_event)
Example #11
0
    def __init__(self):
        self.root = tk.Tk()
        self.root.wm_title("AEViewer")
        self.make_menu()

        frame = tk.Frame(self.root)
        frame.pack(side=tk.TOP, fill=tk.BOTH, expand=1)

        self.fig = Figure(figsize=(8,6), dpi=100)
        canvas = FigureCanvasTkAgg(self.fig, frame)
        canvas.get_tk_widget().pack(side=tk.TOP, fill=tk.BOTH, expand=1)
        self.toolbar = NavigationToolbar2TkAgg(canvas, frame)

        canvas.mpl_connect('key_press_event', self.on_key_press)
        canvas.mpl_connect('scroll_event', self.on_scroll)
        
        self.progressbar = ttk.Progressbar(self.root, orient='horizontal', mode='determinate', )
        self.progressbar.pack(side=tk.BOTTOM, fill=tk.X)
        
        self.data = None
        self.root.update() # needed on windows for events to work
Example #12
0
 def __init__(self, abs_path_to_csv, var_names):
     self.check_vars(var_names)
     self._root = Tk.Tk()
     self._root.wm_title("pyDataGate")
     self._figure = Figure(figsize=(5,4), dpi=100)
     self._dataset = DataSet(abs_path)
     root = self._root
     f = self._figure
     canvas = FigureCanvasTkAgg(f, master=root)
     canvas.show()
     canvas.get_tk_widget().pack(side=Tk.TOP, fill=Tk.BOTH, expand=1)
     canvas.mpl_connect('button_press_event', self.on_click_event)
     arrays = []
     for a_var in var_names:            
         arrays.append(self._dataset.get_array_from_dicts(a_var))
     if len(var_names) == 2:
         ax = f.add_subplot(111)
         ax.scatter(arrays[0], arrays[1])
     if len(var_names) == 3:
         ax = f.add_subplot(111)
         ax.scatter(arrays[0], arrays[1], c=arrays[2])
     button = Tk.Button(master=root, text='Quit', command=self.quit)
     button.pack(side=Tk.BOTTOM)
Example #13
0
 def __init__(self, root, controller):
     f = Figure()
     nticks = 10
     ax = f.add_subplot(111, aspect='1')
 	ax.set_xticks([x*(x_max-x_min)/nticks+x_min for x in range(nticks+1)])
 	ax.set_yticks([y*(y_max-y_min)/nticks+y_min for y in range(1,nticks+1)])
     ax.set_xlim((x_min, x_max))
     ax.set_ylim((y_min, y_max))
     canvas = FigureCanvasTkAgg(f, master=root)
     canvas.show()
     canvas.get_tk_widget().pack(side=Tk.TOP, fill=Tk.BOTH, expand=1)
     canvas._tkcanvas.pack(side=Tk.TOP, fill=Tk.BOTH, expand=1)
     canvas.mpl_connect('button_press_event', self.onclick)
     toolbar = NavigationToolbar2TkAgg(canvas, root)
     toolbar.update()
     self.controllbar = ControllBar(root, controller)
     self.f = f
     self.ax = ax
     self.canvas = canvas
     self.controller = controller
     self.contours = []
     self.c_labels = None
     self.plot_kernels()
Example #14
0
def fig_plot(frame, tarr, parr, nshot, y_ticks=[], col='#c00000', ylbl=''):


    fig = Figure(figsize=(8.2, 8.2), dpi=100)
    can = FigureCanvasTkAgg(fig, master=frame)
    can._tkcanvas.pack(side=tk.TOP, fill=tk.BOTH, expand=1)
    fig.subplots_adjust(left=0.1, bottom=0.1, right=0.95, top=0.92, hspace=0)
    fig.text(.5, .95, '#%d' %nshot, ha='center')

    nsrc = parr.shape[1]
    for jx in range(nsrc):
        ax = fig.add_subplot(8, 1, jx+1)
        ax.plot(tarr, parr[:, jx], color=col)
        ax.set_ylabel('%s%d' %(ylbl, jx+1), fontsize=fsize)
        ax.set_yticks(y_ticks)
        ax.ticklabel_format(axis='y', style='sci', scilimits=(-4,-4))
        ax.yaxis.major.formatter._useMathText = True
        if jx < nsrc-1:
            ax.tick_params(axis='x', which='both', bottom='on', top='on', labelbottom='off')

    ax.set_xlabel('Time [s]', fontsize=fsize)
    can.mpl_connect('button_press_event', fconf.on_click)
    toolbar = NavigationToolbar2TkAgg(can, frame)
    toolbar.update()
Example #15
0
    def __init__(self,root,listener=None):
        self.root=root
        fig,ax=plt.subplots(figsize=(6,6))
        self.ax=ax
        self.ax.set_xlim([0,255])
        self.ax.set_ylim([0,255])
        browser=ToneCurve(fig,self.ax,listener)

        plot_frame=Frame(self.root)
        self.root.add(plot_frame)
        canvas=FigureCanvasTkAgg(fig,master=plot_frame)
                
        canvas.mpl_connect('pick_event',browser.onpick)
        canvas.mpl_connect('motion_notify_event',browser.on_motion)
        #both bind is very important for release event but I do not know why
        canvas._tkcanvas.bind('button_release_event',browser.on_release)
        canvas.mpl_connect('button_release_event', browser.on_release)

        toolbar = NavigationToolbar2TkAgg(canvas, plot_frame)
        toolbar.update()
        self.canvas=canvas  
        self.canvas._tkcanvas.pack(side=tk.TOP, fill=tk.BOTH, expand=1)
Example #16
0
class MainPlot():
    def __init__(self, parent, filenames, trials, timing, destroy_fun,
                 mainplot_axes_fun, queuein, offset_frames, loaded_variables):
        self.mainplot_axes_fun = mainplot_axes_fun
        self.queuein = queuein
        self.fig = Figure(figsize=(12, 4))
        self.destroy_fun = destroy_fun
        gs = gridspec.GridSpec(1, 1)
        gs.update(left=0.001, right=0.999, bottom=0.07, top=0.999)
        self.ax = self.fig.add_subplot(gs[0, 0])
        self.cont_y_pos = -1

        self.fig2 = Figure(figsize=(2, 4))
        self.axname = self.fig2.add_subplot(gs[0, 0])
        # self.axname = self.fig.add_subplot(gs[0, 1])
        self.axname.set_ylim(bottom=0, top=10.5)
        self.axname.set_xlim(left=0, right=1)
        self.axname.axis('off')

        self.ax.set_ylim(bottom=-1, top=0)
        self.ax.set_yticklabels([])
        self.ax.set_yticks([])

        # a tk.DrawingArea
        self.canvas = FigureCanvasTkAgg(self.fig, master=parent)
        self.canvas.get_tk_widget().config(highlightthickness=0)
        self.canvas.show()
        self.canvas.get_tk_widget().grid(row=1, column=0, sticky='NSEW')
        self.canvas.mpl_connect('button_press_event', self.onclick)

        canvas2 = FigureCanvasTkAgg(self.fig2, master=parent)
        canvas2.get_tk_widget().config(highlightthickness=0)
        canvas2.show()
        canvas2.get_tk_widget().grid(row=1, column=1, sticky='NSEW')
        canvas2.mpl_connect('button_press_event', self.onclick)

        camtime = self.get_camTime(timing)
        camrate = self.get_camRate(timing)
        self.offset = (offset_frames / camrate) - camtime
        # print(self.offset)
        # self.colors = ["#4542f4", "#41f465", "#f44141", "#f441e5"]
        self.label_colors = ["#E9CAF4", "#CAEDF4"]
        self.numstreams = 0
        self.loaded_variables = loaded_variables

        data = self.load_matfile(trials)
        # self.xmin = float('Inf')
        # self.xmax = -float('Inf')
        self.xmin = data[0, 0]
        self.xmax = data[-1, 1]
        # self.update_axes(0,1)
        self.boxes_and_labels = []
        self.loaddata(filenames)

    def get_camTime(self, timingfile):
        return scipy.io.loadmat(timingfile)['trialInfo']['camTime'][0][0][0][0]

    def get_camRate(self, timingfile):
        return scipy.io.loadmat(timingfile)['trialInfo']['camRate'][0][0][0][0]

    def cstream2cevent(self, cstream):
        cevent = np.array([[-1, -1, -1]], dtype=np.float64)
        numrows, numcols = np.shape(cstream)
        if numcols > 2:
            return cstream
        in_event = False
        prev_category = 0
        build_event = np.array([[-1, -1, -1]], dtype=np.float64)
        for c in range(0, numrows):
            cur_category = cstream[c, 1]
            if cur_category != prev_category:
                if build_event[0, 0] > 0:
                    build_event[0, 1] = cstream[c, 0]
                    build_event[0, 2] = prev_category
                    cevent = np.append(cevent, build_event, axis=0)
                    build_event = np.array([[-1, -1, -1]])
                elif cur_category > 0:
                    build_event[0, 0] = cstream[c, 0]
            prev_category = cur_category
        return cevent[1:, :]

    def draw_rects(self, data, bottom):
        ind = data[:, 0].argsort(axis=0)
        data = data[ind, :]
        ax = self.ax
        values = data[:, 2].astype(int)
        prev_off = -1
        prev_prev_off = -1
        prev_was_half = None
        lencolors = len(colors)
        for i in range(0, np.size(data[:, 0])):
            curr = data[i, :]
            dur = data[i, 1] - data[i, 0]
            if dur > 0:
                thisbottom = bottom
                # if rect overlaps, then draw at half height so that both show up
                if (data[i, 0] < prev_off):
                    height = 5
                    if prev_was_half == "bottom":
                        prev_was_half = "top"
                        thisbottom = bottom + 5
                    else:
                        prev_was_half = "bottom"
                else:
                    prev_was_half = None
                    height = 10
                if prev_off < data[i, 1]:
                    prev_prev_off = prev_off
                    prev_off = data[i, 1]
                if (values[i] - 1) > lencolors:
                    idx = (values[i] - 1) % lencolors
                else:
                    idx = values[i] - 1
                ax.add_patch(
                    pat.Rectangle((data[i, 0], thisbottom),
                                  dur,
                                  height,
                                  color=colors[idx]))

    def load_matfile(self, filename):
        if ".csv" in filename:
            data = self.csv2np(filename)
        elif ".mat" in filename:
            data = scipy.io.loadmat(filename)['sdata'][0][0][1]
        else:
            data = []
        return data

    def loaddata(self, filenames):
        for f in filenames:
            self.add_variable(f)
        self.ax.figure.canvas.draw()
        self.axname.figure.canvas.draw()

    def onclick(self, event):
        if event.inaxes == self.ax:
            # print('button=%d, x=%d, y=%d, xdata=%f, ydata=%f' %
            #       (event.button, event.x, event.y, event.xdata, event.ydata))
            command = "seekto " + str(event.xdata + self.offset)
            self.queuein.put(command)
        if event.inaxes == self.axname:
            for b in self.boxes_and_labels:
                box, label = b
                contains, attrd = box.contains(event)
                if contains:
                    self.destroy_fun(label)

    def event2cevent(self, data):
        numrows, numcols = np.shape(data)
        one_array = np.ones((numrows, 1), dtype=np.float64)
        arracat = np.concatenate((data, one_array), axis=1)
        return arracat

    def draw_cont(self, data, top):
        maxval = np.max(data[:, 1])
        vals_norm = np.divide(data[:, 1], maxval)
        vals_scaled = np.multiply(vals_norm, 10)
        # if self.cont_y_pos >= -1:
        #     top = self.cont_y_pos
        # else:
        #     self.cont_y_pos = top
        vals_scaled = vals_scaled + top
        self.ax.plot(data[:, 0], vals_scaled)

    def csv2np(self, filename):
        fid = open(filename, "r")
        lines = fid.readlines()
        fid.close()
        outarray = np.zeros(shape=(1, 3), dtype=np.float64)
        for line in lines:
            line = line.split("\n")[0]
            npline = np.fromstring(line, dtype=np.float64, sep=',')
            outarray = np.concatenate((outarray, [npline]), axis=0)
        return outarray[1:, :]

    def add_variable(self, filename):
        # print(filename)
        self.numstreams += 1
        ax = self.ax
        axname = self.axname
        # axc = self.axc
        bot, top = ax.get_ylim()
        data = None
        if len(self.loaded_variables) > 0:
            for f in self.loaded_variables:
                if filename == f[0]:
                    data = f[1]
                    break
        if data is None:
            data = self.load_matfile(filename)
            self.loaded_variables.append((filename, data))
        # else:
        #     print("%s already loaded" % filename)
        if len(data) > 0:
            if "/event" in filename:
                data = self.event2cevent(data)
            if "/cont_" in filename:
                self.draw_cont(data, top)
            else:
                data = self.cstream2cevent(data)
                rects = self.draw_rects(data, top)
            if bot < 0:
                ax.set_ylim(bottom=0, top=10.5)
                axname.set_ylim(bottom=0, top=10.5)
                top = 10.5
            else:
                ax.set_ylim(top=top + 10.5)
                axname.set_ylim(top=top + 10.5)
                top = top + 10.5

            box = axname.add_patch(
                pat.Rectangle((0, top - 10.5),
                              1,
                              10,
                              color=self.label_colors[self.numstreams % 2]))
            filenamesplit = filename.split('/')

            text = axname.text(0, top - 6.5, filenamesplit[-1])
            self.boxes_and_labels.append((box, filename))

    def update_axes(self, xlim1, xlim2):
        width = self.xmax - self.xmin
        newleft = xlim1 * width + self.xmin
        newright = xlim2 * width + self.xmin
        self.ax.set_xlim(left=newleft, right=newright)
        self.mainplot_axes_fun(newleft, newright)
        self.ax.figure.canvas.draw()

    def get_axes(self):
        return self.ax.get_xlim()
Example #17
0
    def __init__(self, master):
        Toplevel.__init__(self)
        self.sizex = 570
        self.sizey = 700
        # position window next to main window
        self.geometry('{0}x{1}+{2}+{3}'.format(self.sizex, self.sizey, master.sizex+20, 0))
        self.master = master

        # self.title("Filterer [{}]".format(master.filename))
        self.minsize(self.sizex, self.sizey)
        # self.resizable(0,0)

        f = self.matplt()
        canvas = FigureCanvasTkAgg(f, master=self)
        canvas.show()
        canvas.get_tk_widget().grid(row=0, columnspan=3, sticky="nsew")#(side=TOP, fill=BOTH, expand=1)

        canvas.mpl_connect('motion_notify_event', self.mouse_plotclick)

        group = LabelFrame(self, text='lambda/theta filtering')
        group.grid(row=1, column=0, sticky='nsew')

        w = Label(group, text='lambda')
        w.pack()
        self.lam_check = IntVar()
        w = Checkbutton(group, text='active', variable=self.lam_check)
        w.pack()
        self.scale_lam = Scale(group, from_=0, to=200, orient=HORIZONTAL, length=150)
        self.scale_lam.set(0)
        self.scale_lam.pack()

        w = Label(group, text='theta')
        w.pack()
        self.theta_check = IntVar()
        w = Checkbutton(group, text='active', variable=self.theta_check)
        w.pack()
        self.scale_theta = Scale(group, from_=0, to=180, resolution=1, orient=HORIZONTAL, length=150)
        self.scale_theta.set(0)
        self.scale_theta.pack()

        group = LabelFrame(self, text='normal map')
        group.grid(row=1, column=1, sticky='nsew')
        self.normalmap_var = StringVar()
        self.normalmap_var.set("none")
        w = OptionMenu(group, self.normalmap_var, "none", "lfs", "theta", "radius", "lambda")
        w.pack()
        w.bind("<ButtonRelease-1>", self.draw_normal_map)

        group = LabelFrame(self, text='thetacon noise')
        group.grid(row=1, column=2, sticky='nsew')
        self.thetacon_check = IntVar()
        w = Checkbutton(group, text='active', variable=self.thetacon_check)
        w.pack()
        self.scale_thetacon_absmin = Scale(group, from_=0, to=180, resolution=1, orient=VERTICAL, length=120)
        self.scale_thetacon_absmin.set(26)
        self.scale_thetacon_absmin.pack(side=LEFT)
        self.scale_thetacon_min = Scale(group, from_=0, to=180, resolution=1, orient=VERTICAL, length=120)
        self.scale_thetacon_min.set(37)
        self.scale_thetacon_min.pack(side=LEFT)
        self.scale_thetacon_delta = Scale(group, from_=0, to=180, resolution=1, orient=VERTICAL, length=120)
        self.scale_thetacon_delta.set(45)
        self.scale_thetacon_delta.pack(side=LEFT)

        group = LabelFrame(self, text='lfs decimation')
        group.grid(row=3, column=0, sticky='nsew')
        w = Button(group, text='Show', command=self.draw_decimate_lfs )
        w.pack()
        self.scale_epsilon = Scale(group, from_=0, to=1, resolution=.02, orient=HORIZONTAL, length=150)
        self.scale_epsilon.set(0.4)
        self.scale_epsilon.pack()

        group = LabelFrame(self, text='ballco decimation')
        group.grid(row=3, column=1, sticky='nsew')
        w = Button(group, text='Show', command=self.draw_decimate_ballco )
        w.pack()
        self.scale_ballco_xi = Scale(group, from_=0, to=1, resolution=.01, orient=HORIZONTAL, length=150)
        self.scale_ballco_xi.set(0.1)
        self.scale_ballco_xi.pack()
        self.ballco_k = Spinbox(group, from_=1, to=15)
        self.ballco_k.pack()

        group = LabelFrame(self, text='radiuscon noise')
        group.grid(row=3, column=2, sticky='nsew')
        self.radiuscon_check = IntVar()
        w = Checkbutton(group, text='active', variable=self.radiuscon_check)
        w.pack()
        self.scale_radiuscon_alpha = Scale(group, from_=0, to=1, resolution=.01, orient=HORIZONTAL, length=150)
        self.scale_radiuscon_alpha.set(0.7)
        self.scale_radiuscon_alpha.pack()
        self.radiuscon_k = Spinbox(group, from_=1, to=15)
        self.radiuscon_k.pack()

        self.rowconfigure(0, weight=1)
        self.rowconfigure(1, weight=0)
        self.rowconfigure(2, weight=0)
        self.columnconfigure(0, weight=1, minsize=self.sizex/3)
        self.columnconfigure(1, weight=1, minsize=self.sizex/3)
        self.columnconfigure(2, weight=1, minsize=self.sizex/3)


        self.bind('q', master.exit)
        self.bind('s', master.spawn_shrinkhistapp)

        self.bind("<ButtonRelease-1>", self.highlight_points)#self.click_draw)
class Layout(object):
    def __init__(self, root, title, size=5):
        fig = Figure(figsize=(7, 7), dpi=100)
        self.weights = None
        self.has_been_trained = False
        self.ax = fig.add_subplot(111)
        self.ax.set_title(title)

        # Makes the plot fixed (prevents from resizing)
        self.ax.set(xlim=(-size, size), ylim=(-size, size))
        # Adds guide lines
        self.ax.axhline(y=0, color="black")
        self.ax.axvline(x=0, color="black")
        # Draw arrow points
        self.ax.scatter(0, size - .1, marker='^', color='black')
        self.ax.scatter(size - .1, 0, marker='>', color='black')
        self.ax.scatter(0, -size + .1, marker='v', color='black')
        self.ax.scatter(-size + .1, 0, marker='<', color='black')

        # Connect the plot with the GUI interface
        self.canvas = FigureCanvasTkAgg(fig, master=root)
        self.canvas.draw()
        self.canvas.get_tk_widget().pack(side=tk.TOP, fill=tk.BOTH, expand=1)
        self.canvas.mpl_connect("button_press_event", self.on_click)

        toolbar = NavigationToolbar2Tk(self.canvas, root)
        toolbar.update()
        self.canvas.get_tk_widget().pack(side=tk.TOP, fill=tk.BOTH, expand=1)

    # Left click -> Class with 0s
    # Right click -> Class with 1s
    def on_click(self, event):
        ix, iy = event.xdata, event.ydata
        if (self.has_been_trained):
            point = {'coord': None, 'class': None, 'color': 'red'}
            point['coord'] = [-1, round(ix, 2), round(iy, 2)]
            point['class'] = 0
            if (np.dot(self.weights, np.array(point['coord'])) >= 0):
                point['class'] = 1
                point['color'] = 'green'

            self.ax.scatter(point['coord'][1],
                            point['coord'][2],
                            color=point['color'])
            self.ax.annotate('Class {}'.format(point['class']),
                             (point['coord'][1] + .5, point['coord'][2]))
            self.canvas.draw()  # Refreshes the canvas
        else:
            if (ix != None):
                point = {'coord': None, 'expected': None}
                color = 'orange'
                point['expected'] = 0
                if (event.button == 3):
                    point['expected'] = 1
                    color = 'purple'
                # The round operation on the coords is to prevent a slow convergence of the algorithm,
                # the plot detects a very precise coord of almost 10 decimal places and it is harder for
                # the algorithm to process those values
                point['coord'] = [-1, round(ix, 2), round(iy, 2)]
                self.ax.scatter(point['coord'][1],
                                point['coord'][2],
                                color=color)
                self.canvas.draw()  # Refreshes the canvas
                # Open the file, then read it to append new points in active session
                with open('bulk_data.json', 'r+') as file:
                    data = json.load(file)
                    data.append(point)
                    file.seek(0)
                    json.dump(data, file)
Example #19
0
class gui(tk.Frame):

    ##### Standard Data ####################################################

    open_times = [list(t / 2 for t in range(h[0], h[1])) for h in open_hours]

    day_abbr = ("Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun")
    day_index = 0

    ##### Button Functions #################################################

    def check_escape(self, event):
        if event.keysym == "Escape":
            self.master.quit()
            self.master.destroy()

    def set_day(self, diff):
        self.day_index = (self.day_index + diff) % 7
        self.label_day.configure(text=self.day_abbr[self.day_index])
        self.plot_figure()

    def recalculate(self):
        if sum(self.weeks_selected) == 0:
            mbox.showwarning("No Weeks Selected",
                             "Please select at least 1 week")
            return
        self.week_switches = [i for i in self.weeks_selected]
        self.rewrite_weeks()
        self.waitscreen_start()
        self.update()
        self.calculate_data()
        self.plot_figure()
        self.waitscreen_stop()
        self.update()

    def save_weeks(self):
        savefile = data("saved_weeks.csv")
        str_data = [str(c) for c in self.weeks_selected]
        save_data = ",".join(str_data)
        with open(savefile, "w") as f:
            f.write(save_data)

    def load_weeks(self):
        loadfile = data("saved_weeks.csv")
        if not os.path.isfile(loadfile):
            default_file = data("term_weeks.csv")
            if os.path.isfile(default_file):
                with open(default_file, "r") as f:
                    weeks_str = f.read().split(",")
            else:
                mbox.showwarning("ERROR", "No 'term_dates.csv' file exists")
                return
        else:
            with open(loadfile, "r") as f:
                weeks_str = f.read().split(",")
        weeks_int = [int(i) for i in weeks_str]
        self.weeks_selected = weeks_int
        self.rewrite_weeks()

    def reset(self):
        loadfile = data("term_weeks.csv")
        if not os.path.isfile(loadfile):
            print(loadfile)
            mbox.showwarning("ERROR", "No 'term_dates.csv' file exists")
            return
        else:
            with open(loadfile, "r") as f:
                weeks_str = f.read().split(",")
        weeks_int = [int(i) for i in weeks_str]
        self.weeks_selected = weeks_int
        self.rewrite_weeks()

    def restart_and_update(self):
        result = mbox.askyesno("Update",
                               "Restart program and update database?")
        if not result:
            return
        args = sys.argv
        if not (any(x in ("--update", "-u") for x in args)):
            args.append("-u")
        try:
            p = psutil.Process(os.getpid())
            for handler in p.open_files() + p.connections():
                os.close(handler.fd)
        except Exception as e:
            pass
            #logging.error(e)
        python = sys.executable
        os.execl(python, python, *args)

    def update_database(self):
        self.waitscreen_start()
        self.gc.update_from_aws()
        self.get_week_starts()
        self.rewrite_weeks()
        self.update()
        self.calculate_data()
        self.plot_figure()
        self.waitscreen_stop()
        self.update()
        # End waitscreen

    def hover(self, event):
        if event.inaxes == self.ax:
            self.show_value(event)

    def mouse_leave_plot(self, event):
        self.show_value(None)

    def week_select(self, widget, single):
        index = widget.curselection()[0]
        if single:
            for i in range(len(self.weeks_selected)):
                self.weeks_selected[i] = 0
            self.weeks_selected[index] = 1
        else:
            index = widget.curselection()[0]
            if self.weeks_selected[index] == 0:
                self.weeks_selected[index] = 1
            else:
                self.weeks_selected[index] = 0
        self.rewrite_weeks()

    ##### Follow-up Functions ##############################################

    def rewrite_weeks(self):
        lb = self.lb_weeks
        lb.delete(0, "end")
        for i in range(len(self.week_starts)):
            text = self.week_starts[i]

            if self.week_switches[i] == 0:
                lb.insert("end", strikethrough(text))
            else:
                lb.insert("end", text)

            if self.weeks_selected[i] == 0:
                lb.itemconfig("end", foreground="#999999")

    def show_value(self, event):
        if event == None:
            self.label_values.configure(text="")
            self.label_mousepos.configure(text="")
            return

        # Find the appropriate x_value:
        x, y = event.xdata, event.ydata
        time_pos = round(x * 2) / 2.

        # Get index of time position
        try:
            time_index = self.open_times[self.day_index].index(time_pos)
            # value = round(self.data[self.day_index][time_index],1)
            value = round(self.errors[self.day_index][time_index], 1)
        except ValueError:
            value = 0

        hours = str(int(time_pos))
        hours = hours if (len(hours) == 2) else "0" + hours
        minutes = "30" if (time_pos % 1 == 0.5) else "00"
        self.label_values.configure(text="{} {}:{} = {}%".format(\
            day_names[self.day_index], hours, minutes, value))

        # Show relative mouse position, for evaluating lines and such
        self.label_mousepos.configure(text="t={}; y={}%".format(\
            round(x,1), round(y,1)))

    ##### Drawing / Positioning ############################################

    def position(self):
        # Base Frames
        self.f1 = tk.Frame(self)
        self.f2 = tk.Frame(self, bg="#ffffff")
        self.f3 = tk.Frame(self)
        self.f4 = tk.Frame(self)

        self.f1.rowconfigure(1, weight=1)
        self.f4.columnconfigure(1, minsize=50)
        self.f2.rowconfigure(0, weight=1)

        self.f1.grid(row=0, column=0, sticky=tk.N + tk.W + tk.S + tk.E)
        self.f2.grid(row=0, column=1)
        self.f3.grid(row=1, column=0)
        self.f4.grid(row=1, column=1)

        # Frame 1
        self.label_select_weeks = tk.Label(master=self.f1,
                                           text="Selected Weeks:")
        self.label_select_weeks.grid(row=0, sticky=tk.W)

        self.lb_weeks = tk.Listbox(master=self.f1, selectmode="SINGLE")
        self.lb_weeks.grid(row=1, sticky=tk.N + tk.W + tk.S + tk.E)
        self.lb_weeks_mc = listboxControl(self.lb_weeks, self)

        self.rewrite_weeks()

        self.f5 = tk.Frame(master=self.f1)
        self.f5.grid(row=2)

        self.button_save = tk.Button(master=self.f5, text="Save", \
            command=self.save_weeks)
        self.button_save.pack(side=tk.LEFT)
        self.button_load = tk.Button(master=self.f5, text="Load", \
            command=self.load_weeks)
        self.button_load.pack(side=tk.LEFT)
        self.button_load = tk.Button(master=self.f5, text="Reset", \
            command=self.reset)
        self.button_load.pack(side=tk.RIGHT)

        # Frame 2
        self.fig = Figure(figsize=(5, 4), dpi=100)
        self.ax = self.fig.add_subplot(111)

        self.canvas = FigureCanvasTkAgg(self.fig, master=self.f2)
        self.canvas.draw()
        self.canvas.get_tk_widget().grid(row=0,
                                         sticky=tk.N + tk.W + tk.S + tk.E)

        self.plot_figure()

        self.canvas.mpl_connect("motion_notify_event", self.hover)
        self.canvas.mpl_connect("axes_leave_event", self.mouse_leave_plot)

        self.label_values = tk.Label(master=self.f2, text="", bg="#ffffff")
        self.label_values.grid(row=1, sticky=tk.W)

        self.label_mousepos = tk.Label(master=self.f2,
                                       text="",
                                       fg="#777777",
                                       bg="#ffffff")
        self.label_mousepos.grid(row=2, sticky=tk.W)

        # Frame 3
        self.button_recalc = tk.Button(master=self.f3, text="Recalculate", \
            command=self.recalculate)
        self.button_recalc.pack(side=tk.LEFT)
        self.button_update = tk.Button(master=self.f3, text="UPDATE", \
            command=self.update_database)
        self.button_update.pack(side=tk.LEFT)

        # Frame 4
        self.button_back = tk.Button(master=self.f4, text="<", \
            command=lambda : self.set_day(-1))
        self.button_back.grid(row=0, column=0)

        self.label_day = tk.Label(master=self.f4, text="day_goes_here")
        self.label_day.grid(row=0, column=1)

        self.button_forward = tk.Button(master=self.f4, text=">", \
            command=lambda : self.set_day(1))
        self.button_forward.grid(row=0, column=2)

        # Set positions
        self.grid()

    def waitscreen_start(self):
        self.waiting = True
        canvas = self.canvas.get_tk_widget()
        width, height = canvas.winfo_width(), canvas.winfo_height()
        self.waitscreen = tk.Canvas(width=width, height=height, master=self.f2)
        self.waitscreen.create_rectangle(5, 5, width - 5, height - 5)
        self.waitscreen.create_text(width/2,height/2, \
            text="Recalculating...")

        canvas.grid_forget()
        self.waitscreen.grid(row=0, sticky=tk.N + tk.W + tk.S + tk.E)

    def waitscreen_stop(self):
        self.waiting = False
        canvas = self.canvas.get_tk_widget()
        self.waitscreen.grid_forget()
        canvas.grid(row=0, sticky=tk.N + tk.W + tk.S + tk.E)

    ##### Plotting #########################################################
    def plot_figure(self):
        self.figure_type = 4
        if self.figure_type == 1:
            self.plot_figure1()
        elif self.figure_type == 2:
            self.plot_figure2()
        elif self.figure_type == 3:
            self.plot_figure3()
        elif self.figure_type == 4:
            self.plot_figure4()

    def plot_figure1(self):
        # Original Plot
        i = self.day_index
        self.ax.cla()
        self.barplot = self.ax.bar(self.open_times[i], self.data[i], width=0.4)
        self.ax.set_title("{} - Mean={}%".format(day_names[i], \
            round(mean(self.data[i]),1)))
        self.ax.set_xlim([6, 23.5])
        max_value = 5 * (round(max(map(max, self.data)) / 5) + 1)
        total_mean = mean(map(mean, self.data))
        self.ax.set_ylim([0, max_value])
        self.ax.xaxis.set_ticks(list(range(6, 24)))
        self.ax.axhline(y=mean(self.data[i]))
        self.ax.axhline(y=total_mean, alpha=0.2, color="#ff0000")
        self.canvas.draw()

    def plot_figure2(self):
        # Original Plot plus standard error bars
        i = self.day_index
        self.ax.cla()
        self.barplot = self.ax.bar(self.open_times[i],self.data[i], \
            yerr=self.errors[i],width=0.4)
        self.ax.set_title("{} - Mean={}%".format(day_names[i], \
            round(mean(self.data[i]),1)))
        self.ax.set_xlim([6, 23.5])
        max_value = 5 * (round(max(map(max, self.data)) / 5) + 1)
        total_mean = mean(map(mean, self.data))
        self.ax.set_ylim([0, max_value])
        self.ax.xaxis.set_ticks(list(range(6, 24)))
        self.ax.axhline(y=mean(self.data[i]))
        self.ax.axhline(y=total_mean, alpha=0.2, color="#ff0000")
        self.canvas.draw()

    def plot_figure3(self):
        # Envelope Line Plot
        i = self.day_index
        self.ax.cla()
        self.lineplot = self.ax.plot(self.open_times[i],
                                     self.data[i],
                                     color="gray")
        self.ax.set_title("{} - Mean={}%".format(day_names[i], \
            round(mean(self.data[i]),1)))
        self.ax.set_xlim([6, 23.5])
        bottom_line = [
            self.data[i][x] - self.errors[i][x]
            for x in range(len(self.open_times[i]))
        ]
        top_line = [
            self.data[i][x] + self.errors[i][x]
            for x in range(len(self.open_times[i]))
        ]
        self.ax.fill_between(self.open_times[i],bottom_line,\
            top_line, color="gray",alpha=0.2)
        max_value = 5 * (round(max(map(max, self.data)) / 5) + 1)
        total_mean = mean(map(mean, self.data))
        self.ax.set_ylim([0, max_value])
        self.ax.xaxis.set_ticks(list(range(6, 24)))
        self.ax.axhline(y=mean(self.data[i]))
        self.ax.axhline(y=total_mean, alpha=0.2, color="#ff0000")
        self.canvas.draw()

    def plot_figure4(self):
        # Original plot with custom error bars
        i = self.day_index
        self.ax.cla()
        self.barplot = self.ax.bar(self.open_times[i], self.data[i], width=0.4)
        elevation = [
            self.data[i][x] - self.errors[i][x] / 2
            for x in range(len(self.data[i]))
        ]
        self.errplot = self.ax.bar(self.open_times[i],self.errors[i],\
            bottom=elevation,width=0.4,alpha=0.3,color="red")
        self.ax.set_title("{} - Mean={}%".format(day_names[i], \
            round(mean(self.data[i]),1)))
        self.ax.set_xlim([6, 23.5])
        max_value = 5 * (round(max(map(max, self.data)) / 5) + 1)
        total_mean = mean(map(mean, self.data))
        self.ax.set_ylim([0, 100])
        self.ax.xaxis.set_ticks(list(range(6, 24)))
        self.ax.axhline(y=mean(self.data[i]))
        self.ax.axhline(y=total_mean, alpha=0.2, color="green")
        self.canvas.draw()

    ##### Calculation Functions ############################################

    def get_week_starts(self):
        dates = self.gc.get_uniques("date, day", "date")
        for d in dates:
            if d[1] == "Monday":
                start_date = date(d[0]).value
                break
        for d in reversed(dates):
            if d[1] == "Sunday":
                end_date = date(d[0]).value
                break
        qprint("Data ranges from {} to {}".format(start_date, end_date))
        temp_date = start_date
        week_starts = []
        while True:
            week_starts.append(str(date(temp_date)))
            temp_date += datetime.timedelta(days=7)
            if temp_date > end_date:
                break
        self.week_starts = week_starts

        for fpath in ("saved_weeks.csv", "term_weeks.csv"):
            loadfile = data(fpath)
            if os.path.isfile(loadfile):
                with open(loadfile, "r") as f:
                    weeks_str = f.read().split(",")
                break
        try:
            self.week_switches = [int(i) for i in weeks_str]
            if len(self.week_switches) < len(week_starts):
                self.week_switches += [0] * (len(week_starts) -
                                             len(self.week_switches))
        except Error as e:
            qprint("ERROR: Neither saved_weeks.csv or term_weeks.csv found!")
            self.week_switches = [1 for _ in week_starts]
        self.weeks_selected = [i for i in self.week_switches]

    def calculate_data(self):
        data = []
        errors = []

        for d in range(7):
            day_values = []
            day_errors = []
            for t in self.open_times[d]:
                time_values = []
                for i in range(len(self.week_starts)):
                    if self.week_switches[i] == 0:
                        continue
                    w_start = date(self.week_starts[i]).value
                    w_end = w_start + datetime.timedelta(days=6)

                    com1 = "SELECT value FROM gymchecker WHERE date BETWEEN {} AND {} ".format(\
                        int(date(w_start)), int(date(w_end)))
                    com2 = "AND time={} AND day='{}'".format(t, day_names[d])
                    results = self.gc.x(com1 + com2)
                    if len(results) > 0:
                        time_values.append(results[0][0])
                    # else:
                    #     print("ERROR: {}; {}{}".format(results,com1,com2))
                total = mean(time_values)
                sd = stdev(time_values)
                day_values.append(total)
                day_errors.append(sd)

            data.append(day_values)
            errors.append(day_errors)
        self.data = data
        self.errors = errors

    ##### init function ####################################################

    def __init__(self, master, gc):
        self.gc = gc
        tk.Frame.__init__(self, master)
        master.bind("<KeyPress>", self.check_escape)
        self.get_week_starts()
        self.calculate_data()
        self.position()
        self.set_day(0)
Example #20
0
class wishbone_gui(tk.Tk):
    def __init__(self, parent):
        tk.Tk.__init__(self, parent)
        self.parent = parent
        self.initialize()

    def initialize(self):
        self.grid()
        self.vals = None
        self.currentPlot = None

        #set up menu bar
        self.menubar = tk.Menu(self)
        self.fileMenu = tk.Menu(self.menubar, tearoff=0)
        self.menubar.add_cascade(label="File", menu=self.fileMenu)
        self.fileMenu.add_command(label="Load data", command=self.loadData)
        self.fileMenu.add_command(label="Save data",
                                  state='disabled',
                                  command=self.saveData)
        self.fileMenu.add_command(label="Exit Wishbone", command=self.quitWB)

        self.analysisMenu = tk.Menu(self.menubar, tearoff=0)
        self.menubar.add_cascade(label="Analysis", menu=self.analysisMenu)
        self.analysisMenu.add_command(label="Principal component analysis",
                                      state='disabled',
                                      command=self.runPCA)
        self.analysisMenu.add_command(label="tSNE",
                                      state='disabled',
                                      command=self.runTSNE)
        self.analysisMenu.add_command(label="Diffusion map",
                                      state='disabled',
                                      command=self.runDM)
        self.analysisMenu.add_command(label="GSEA",
                                      state='disabled',
                                      command=self.runGSEA)
        self.analysisMenu.add_command(label="Wishbone",
                                      state='disabled',
                                      command=self.runWishbone)

        self.visMenu = tk.Menu(self.menubar, tearoff=0)
        self.menubar.add_cascade(label="Visualization", menu=self.visMenu)
        self.visMenu.add_command(label="Principal component analysis",
                                 state='disabled',
                                 command=self.plotPCA)
        self.visMenu.add_command(label="tSNE",
                                 state='disabled',
                                 command=self.plotTSNE)
        self.visMenu.add_command(label="Diffusion map",
                                 state='disabled',
                                 command=self.plotDM)
        self.visMenu.add_command(label="GSEA Results",
                                 state='disabled',
                                 command=self.showGSEAResults)
        self.wishboneMenu = tk.Menu(self)
        self.visMenu.add_cascade(label="Wishbone", menu=self.wishboneMenu)
        self.wishboneMenu.add_command(label="On tSNE",
                                      state='disabled',
                                      command=self.plotWBOnTsne)
        self.wishboneMenu.add_command(label="Marker trajectory",
                                      state='disabled',
                                      command=self.plotWBMarkerTrajectory)
        self.wishboneMenu.add_command(label="Heat map",
                                      state='disabled',
                                      command=self.plotWBHeatMap)
        self.visMenu.add_command(label="Gene expression",
                                 state='disabled',
                                 command=self.plotGeneExpOntSNE)
        self.visMenu.add_command(label="Set gate",
                                 state='disabled',
                                 command=self.setGate)

        self.config(menu=self.menubar)

        #intro screen
        tk.Label(self,
                 text=u"Wishbone",
                 font=('Helvetica', 48),
                 fg="black",
                 bg="white",
                 padx=100,
                 pady=50).grid(row=0)
        tk.Label(
            self,
            text=
            u"To get started, select a data file by clicking File > Load Data",
            fg="black",
            bg="white",
            padx=100,
            pady=25).grid(row=1)

        #update
        self.protocol('WM_DELETE_WINDOW', self.quitWB)
        self.grid_columnconfigure(0, weight=1)
        self.resizable(True, True)
        self.update()
        self.geometry(self.geometry())
        self.focus_force()

    def loadData(self):
        self.dataFileName = filedialog.askopenfilename(
            title='Load data file', initialdir='~/.wishbone/data')
        if (self.dataFileName != ""):
            #pop up data options menu
            self.fileInfo = tk.Toplevel()
            self.fileInfo.title("Data options")
            tk.Label(self.fileInfo, text=u"File name: ").grid(column=0, row=0)
            tk.Label(self.fileInfo,
                     text=self.dataFileName.split('/')[-1]).grid(column=1,
                                                                 row=0)

            tk.Label(self.fileInfo, text=u"Name:", fg="black",
                     bg="white").grid(column=0, row=1)
            self.fileNameEntryVar = tk.StringVar()
            tk.Entry(self.fileInfo,
                     textvariable=self.fileNameEntryVar).grid(column=1, row=1)

            if self.dataFileName.split('.')[len(self.dataFileName.split('.')) -
                                            1] == 'fcs':
                tk.Label(self.fileInfo,
                         text=u"Cofactor:",
                         fg="black",
                         bg="white").grid(column=0, row=2)
                self.cofactorVar = tk.IntVar()
                self.cofactorVar.set(5)
                tk.Entry(self.fileInfo,
                         textvariable=self.cofactorVar).grid(column=1, row=2)
            elif self.dataFileName.split('.')[len(self.dataFileName.split('.'))
                                              - 1] == 'csv':
                self.normalizeVar = tk.BooleanVar()
                tk.Checkbutton(self.fileInfo,
                               text=u"Normalize",
                               variable=self.normalizeVar).grid(column=0,
                                                                row=2,
                                                                columnspan=2)
                tk.Label(
                    self.fileInfo,
                    text=
                    u"The normalize parameter is used for correcting for library size among cells."
                ).grid(column=0, row=3, columnspan=2)

            tk.Button(self.fileInfo,
                      text="Cancel",
                      command=self.fileInfo.destroy).grid(column=0, row=4)
            tk.Button(self.fileInfo, text="Load",
                      command=self.processData).grid(column=1, row=4)

            self.wait_window(self.fileInfo)

    def processData(self):
        #clear intro screen
        for item in self.grid_slaves():
            item.grid_forget()

        #display file name
        tk.Label(self,
                 text=u"File name: " + self.fileNameEntryVar.get(),
                 fg="black",
                 bg="white").grid(column=0, row=0)

        #set up canvas for plots
        self.fig, self.ax = wishbone.wb.get_fig()
        self.canvas = FigureCanvasTkAgg(self.fig, self)
        self.canvas.show()
        self.canvas.get_tk_widget().grid(column=1,
                                         row=1,
                                         rowspan=10,
                                         columnspan=4,
                                         sticky='NSEW')
        tk.Label(self, text=u"Visualizations:", fg='black',
                 bg='white').grid(column=0, row=1)

        #load data based on input type
        if self.dataFileName.split('.')[len(self.dataFileName.split('.')) -
                                        1] == 'fcs':  # mass cytometry data
            self.scdata = wishbone.wb.SCData.from_fcs(
                os.path.expanduser(self.dataFileName),
                cofactor=self.cofactorVar.get())
            self.wb = None
        elif self.dataFileName.split('.')[len(self.dataFileName.split('.')) -
                                          1] == 'csv':  # sc-seq data
            self.scdata = wishbone.wb.SCData.from_csv(
                os.path.expanduser(self.dataFileName),
                data_type='sc-seq',
                normalize=self.normalizeVar.get())
            self.wb = None
        else:
            self.wb = wishbone.wb.Wishbone.load(self.dataFileName)
            self.scdata = self.wb.scdata

        #set up buttons based on data type
        if self.scdata.data_type == 'sc-seq':
            self.PCAButton = tk.Button(self,
                                       text=u"PCA",
                                       state='disabled',
                                       command=self.plotPCA)
            self.PCAButton.grid(column=0, row=2)
            self.tSNEButton = tk.Button(self,
                                        text=u"tSNE",
                                        state='disabled',
                                        command=self.plotTSNE)
            self.tSNEButton.grid(column=0, row=3)
            self.DMButton = tk.Button(self,
                                      text=u"Diffusion map",
                                      state='disabled',
                                      command=self.plotDM)
            self.DMButton.grid(column=0, row=4)
            self.GSEAButton = tk.Button(self,
                                        text=u"GSEA Results",
                                        state='disabled',
                                        command=self.showGSEAResults)
            self.GSEAButton.grid(column=0, row=5)
            self.WBButton = tk.Button(self,
                                      text=u"Wishbone",
                                      state='disabled',
                                      command=self.plotWBOnTsne)
            self.WBButton.grid(column=0, row=6)
            self.geneExpButton = tk.Button(self,
                                           text=u"Gene expression",
                                           state='disabled',
                                           command=self.plotGeneExpOntSNE)
            self.geneExpButton.grid(column=0, row=7)
            self.setGateButton = tk.Button(self,
                                           text=u"Set gate",
                                           state='disabled',
                                           command=self.setGate)
            self.setGateButton.grid(column=0, row=8)
            self.saveButton = tk.Button(self,
                                        text=u"Save plot",
                                        state='disabled',
                                        command=self.savePlot)
            self.saveButton.grid(column=4, row=0)
            self.diff_component = tk.StringVar()
            self.diff_component.set('Component 1')
            self.component_menu = tk.OptionMenu(self, self.diff_component,
                                                'Component 1', 'Component 2',
                                                'Component 3', 'Component 4',
                                                'Component 5', 'Component 6',
                                                'Component 7', 'Component 8',
                                                'Component 9')
            self.component_menu.config(state='disabled')
            self.component_menu.grid(row=0, column=2)
            self.updateButton = tk.Button(self,
                                          text=u"Update component",
                                          command=self.updateComponent,
                                          state='disabled')
            self.updateButton.grid(column=3, row=0)

            #enable buttons based on current state of scdata object
            if self.scdata.pca:
                self.analysisMenu.entryconfig(1, state='normal')
                self.visMenu.entryconfig(0, state='normal')
                self.PCAButton.config(state='normal')
            if isinstance(self.scdata.tsne, pd.DataFrame):
                self.analysisMenu.entryconfig(2, state='normal')
                self.visMenu.entryconfig(1, state='normal')
                self.visMenu.entryconfig(5, state='normal')
                self.tSNEButton.config(state='normal')
                self.geneExpButton.config(state='normal')
            if isinstance(self.scdata.diffusion_eigenvectors, pd.DataFrame):
                self.analysisMenu.entryconfig(3, state='normal')
                self.analysisMenu.entryconfig(4, state='normal')
                self.visMenu.entryconfig(2, state='normal')
                self.DMButton.config(state='normal')
        else:
            self.tSNEButton = tk.Button(self,
                                        text=u"tSNE",
                                        state='disabled',
                                        command=self.plotTSNE)
            self.tSNEButton.grid(column=0, row=2)
            self.DMButton = tk.Button(self,
                                      text=u"Diffusion map",
                                      state='disabled',
                                      command=self.plotDM)
            self.DMButton.grid(column=0, row=3)
            self.WBButton = tk.Button(self,
                                      text=u"Wishbone",
                                      state='disabled',
                                      command=self.plotWBOnTsne)
            self.WBButton.grid(column=0, row=4)
            self.geneExpButton = tk.Button(self,
                                           text=u"Gene expression",
                                           state='disabled',
                                           command=self.plotGeneExpOntSNE)
            self.geneExpButton.grid(column=0, row=5)
            self.setGateButton = tk.Button(self,
                                           text=u"Set gate",
                                           state='disabled',
                                           command=self.setGate)
            self.setGateButton.grid(column=0, row=6)
            self.saveButton = tk.Button(self,
                                        text=u"Save plot",
                                        state='disabled',
                                        command=self.savePlot)
            self.saveButton.grid(column=4, row=0)

            self.analysisMenu.delete(0)
            self.analysisMenu.delete(2)
            self.visMenu.delete(0)
            self.visMenu.delete(2)
            self.analysisMenu.entryconfig(1, state='normal')

            #enable buttons based on current state of scdata object
            if isinstance(self.scdata.tsne, pd.DataFrame):
                self.visMenu.entryconfig(0, state='normal')
                self.visMenu.entryconfig(3, state='normal')
                self.tSNEButton.config(state='normal')
                self.geneExpButton.config(state='normal')
            if isinstance(self.scdata.diffusion_eigenvectors, pd.DataFrame):
                self.analysisMenu.entryconfig(2, state='normal')
                self.visMenu.entryconfig(1, state='normal')
                self.DMButton.config(state='normal')

        #enable buttons
        self.analysisMenu.entryconfig(0, state='normal')
        self.fileMenu.entryconfig(1, state='normal')
        if self.wb:
            if isinstance(self.wb.trajectory, pd.Series):
                self.wishboneMenu.entryconfig(0, state='normal')
                self.wishboneMenu.entryconfig(1, state='normal')
                self.wishboneMenu.entryconfig(2, state='normal')
                self.WBButton.config(state='normal')
        #get genes
        self.genes = self.scdata.data.columns.values
        self.gates = {}
        self.geometry('800x550')
        #destroy pop up menu
        self.fileInfo.destroy()

    def saveData(self):
        pickleFileName = filedialog.asksaveasfilename(
            title='Save Wishbone Data',
            defaultextension='.p',
            initialfile=self.fileNameEntryVar.get())
        if pickleFileName != None:
            if self.wb != None:
                self.wb.save(pickleFileName)
            else:
                self.scdata.save_as_wishbone(pickleFileName)

    def runPCA(self):
        self.scdata.run_pca()

        #enable buttons
        self.analysisMenu.entryconfig(1, state='normal')
        self.visMenu.entryconfig(0, state='normal')
        self.PCAButton.config(state='normal')

    def runTSNE(self):
        #pop up for # components
        self.tsneOptions = tk.Toplevel()
        self.tsneOptions.title("tSNE options")
        if self.scdata.data_type == 'sc-seq':
            tk.Label(self.tsneOptions,
                     text=u"Number of components:",
                     fg="black",
                     bg="white").grid(column=0, row=0)
            self.nCompVar = tk.IntVar()
            self.nCompVar.set(15)
            tk.Entry(self.tsneOptions,
                     textvariable=self.nCompVar).grid(column=1, row=0)
        tk.Label(self.tsneOptions, text=u"Perplexity:", fg="black",
                 bg="white").grid(column=0, row=1)
        self.perplexityVar = tk.IntVar()
        self.perplexityVar.set(30)
        tk.Entry(self.tsneOptions,
                 textvariable=self.perplexityVar).grid(column=1, row=1)
        tk.Button(self.tsneOptions, text="Run",
                  command=self._runTSNE).grid(column=1, row=2)
        tk.Button(self.tsneOptions,
                  text="Cancel",
                  command=self.tsneOptions.destroy).grid(column=0, row=2)
        self.wait_window(self.tsneOptions)

    def _runTSNE(self):
        if self.scdata.data_type == 'sc-seq':
            self.scdata.run_tsne(n_components=self.nCompVar.get(),
                                 perplexity=self.perplexityVar.get())
        else:
            self.scdata.run_tsne(n_components=None,
                                 perplexity=self.perplexityVar.get())
        self.gates = {}

        #enable buttons
        if self.scdata.data_type == 'sc-seq':
            self.analysisMenu.entryconfig(2, state='normal')
            self.visMenu.entryconfig(1, state='normal')
            self.visMenu.entryconfig(5, state='normal')
        else:
            self.visMenu.entryconfig(0, state='normal')
            self.visMenu.entryconfig(3, state='normal')
        self.tSNEButton.config(state='normal')
        self.geneExpButton.config(state='normal')
        self.tsneOptions.destroy()

    def runDM(self):
        self.scdata.run_diffusion_map()

        #enable buttons
        if self.scdata.data_type == 'sc-seq':
            self.analysisMenu.entryconfig(3, state='normal')
            self.analysisMenu.entryconfig(4, state='normal')
            self.visMenu.entryconfig(2, state='normal')
        else:
            self.analysisMenu.entryconfig(2, state='normal')
            self.visMenu.entryconfig(1, state='normal')
        self.DMButton.config(state='normal')

    def runGSEA(self):
        self.GSEAFileName = filedialog.askopenfilename(
            title='Select gmt File', initialdir='~/.wishbone/tools')
        if self.GSEAFileName != "":
            self.scdata.run_diffusion_map_correlations()
            self.scdata.data.columns = self.scdata.data.columns.str.upper()
            self.outputPrefix = filedialog.asksaveasfilename(
                title='Input file prefix for saving output',
                initialdir='~/.wishbone/gsea')
            if 'mouse' in self.GSEAFileName:
                gmt_file_type = 'mouse'
            else:
                gmt_file_type = 'human'
            self.reports = self.scdata.run_gsea(
                output_stem=os.path.expanduser(self.outputPrefix),
                gmt_file=(gmt_file_type, self.GSEAFileName.split('/')[-1]))
            #enable buttons
            self.visMenu.entryconfig(3, state='normal')
            self.GSEAButton.config(state='normal')

    def runWishbone(self):
        #popup menu for wishbone options
        self.wbOptions = tk.Toplevel()
        self.wbOptions.title("Wishbone Options")

        #s
        tk.Label(self.wbOptions, text=u"Start cell:", fg="black",
                 bg="white").grid(column=0, row=0)
        self.start = tk.StringVar()
        tk.Entry(self.wbOptions, textvariable=self.start).grid(column=1, row=0)
        if (len(self.gates) > 0):
            self.cell_gate = tk.StringVar()
            self.cell_gate.set('Use cell gate')
            self.gate_menu = tk.OptionMenu(self.wbOptions, self.cell_gate,
                                           *list(self.gates.keys()))
            self.gate_menu.grid(row=0, column=2)

        #k
        tk.Label(self.wbOptions, text=u"k:", fg="black",
                 bg="white").grid(column=0, row=1)
        self.k = tk.IntVar()
        tk.Entry(self.wbOptions, textvariable=self.k).grid(column=1, row=1)
        self.k.set(15)

        #components list
        tk.Label(self.wbOptions,
                 text=u"Components list:",
                 fg='black',
                 bg='white').grid(column=0, row=2)
        self.compList = tk.StringVar()
        tk.Entry(self.wbOptions, textvariable=self.compList).grid(column=1,
                                                                  row=2)
        self.compList.set("1, 2, 3")

        #num waypoints
        tk.Label(self.wbOptions,
                 text=u"Number of waypoints:",
                 fg='black',
                 bg='white').grid(column=0, row=3)
        self.numWaypoints = tk.IntVar()
        tk.Entry(self.wbOptions, textvariable=self.numWaypoints).grid(column=1,
                                                                      row=3)
        self.numWaypoints.set(250)

        #branch
        self.branch = tk.BooleanVar()
        self.branch.set(True)
        tk.Checkbutton(self.wbOptions, text=u"Branch",
                       variable=self.branch).grid(column=0,
                                                  row=4,
                                                  columnspan=2)

        tk.Button(self.wbOptions, text="Run",
                  command=self._runWishbone).grid(column=1, row=5)
        tk.Button(self.wbOptions,
                  text="Cancel",
                  command=self.wbOptions.destroy).grid(column=0, row=5)
        self.wait_window(self.wbOptions)

    def _runWishbone(self):
        self.wb = wishbone.wb.Wishbone(self.scdata)

        if self.cell_gate.get() == 'Use cell gate':
            self.wb.run_wishbone(start_cell=self.start.get(),
                                 k=self.k.get(),
                                 components_list=[
                                     int(comp)
                                     for comp in self.compList.get().split(',')
                                 ],
                                 num_waypoints=self.numWaypoints.get(),
                                 branch=self.branch.get())
        else:
            #randomly select start cell in gate
            print('Using cell gate:')
            print(self.cell_gate.get())
            start_cell = random.sample(list(self.gates[self.cell_gate.get()]),
                                       1)[0]
            print(start_cell)
            self.wb.run_wishbone(start_cell=start_cell,
                                 k=self.k.get(),
                                 components_list=[
                                     int(comp)
                                     for comp in self.compList.get().split(',')
                                 ],
                                 num_waypoints=self.numWaypoints.get(),
                                 branch=self.branch.get())

        #enable buttons
        self.wishboneMenu.entryconfig(0, state='normal')
        self.wishboneMenu.entryconfig(1, state='normal')
        self.wishboneMenu.entryconfig(2, state='normal')
        self.WBButton.config(state='normal')
        self.wbOptions.destroy()

    def plotPCA(self):
        self.saveButton.config(state='normal')
        self.setGateButton.config(state='disabled')
        if self.scdata.data_type == 'sc-seq':
            self.component_menu.config(state='disabled')
            self.updateButton.config(state='disabled')
            self.visMenu.entryconfig(6, state='disabled')
        else:
            self.visMenu.entryconfig(4, state='disabled')

        #pop up for # components
        self.PCAOptions = tk.Toplevel()
        self.PCAOptions.title("PCA Plot Options")
        tk.Label(self.PCAOptions,
                 text=u"Max variance explained (ylim):",
                 fg="black",
                 bg="white").grid(column=0, row=0)
        self.yLimVar = tk.DoubleVar()
        self.yLimVar.set(round(self.scdata.pca['eigenvalues'][0][0], 2))
        tk.Entry(self.PCAOptions, textvariable=self.yLimVar).grid(column=1,
                                                                  row=0)
        tk.Label(self.PCAOptions,
                 text=u"Number of components:",
                 fg='black',
                 bg='white').grid(column=0, row=1)
        self.compVar = tk.IntVar()
        self.compVar.set(15)
        tk.Entry(self.PCAOptions, textvariable=self.compVar).grid(column=1,
                                                                  row=1)
        tk.Button(self.PCAOptions, text="Plot",
                  command=self._plotPCA).grid(column=1, row=2)
        tk.Button(self.PCAOptions,
                  text="Cancel",
                  command=self.PCAOptions.destroy).grid(column=0, row=2)
        self.wait_window(self.PCAOptions)

    def _plotPCA(self):
        self.resetCanvas()
        self.fig, self.ax = self.scdata.plot_pca_variance_explained(
            ylim=(0, self.yLimVar.get()), n_components=self.compVar.get())
        self.canvas = FigureCanvasTkAgg(self.fig, self)
        self.canvas.show()
        self.canvas.get_tk_widget().grid(column=1,
                                         row=1,
                                         rowspan=10,
                                         columnspan=4,
                                         sticky='NW')
        self.currentPlot = 'pca'

        #enable buttons
        self.saveButton.config(state='normal')
        self.PCAOptions.destroy()

    def plotTSNE(self):
        self.saveButton.config(state='normal')
        self.setGateButton.config(state='normal')
        if self.scdata.data_type == 'sc-seq':
            self.component_menu.config(state='disabled')
            self.updateButton.config(state='disabled')
            self.visMenu.entryconfig(6, state='normal')
        else:
            self.visMenu.entryconfig(4, state='normal')

        self.resetCanvas()
        self.fig, self.ax = self.scdata.plot_tsne()
        self.canvas = FigureCanvasTkAgg(self.fig, self)
        self.canvas.show()
        self.canvas.get_tk_widget().grid(column=1,
                                         row=1,
                                         rowspan=10,
                                         columnspan=4,
                                         sticky='NW')
        self.currentPlot = 'tsne'

    def plotDM(self):
        self.saveButton.config(state='normal')
        self.setGateButton.config(state='disabled')
        if self.scdata.data_type == 'sc-seq':
            self.component_menu.config(state='disabled')
            self.updateButton.config(state='disabled')
            self.visMenu.entryconfig(6, state='disabled')
        else:
            self.visMenu.entryconfig(4, state='disabled')

        self.geometry('950x550')

        self.resetCanvas()
        self.fig, self.ax = self.scdata.plot_diffusion_components()
        self.canvas = FigureCanvasTkAgg(self.fig, self)
        self.canvas.show()
        self.canvas.get_tk_widget().grid(column=1,
                                         row=1,
                                         rowspan=10,
                                         columnspan=4,
                                         sticky='W')
        self.currentPlot = 'dm_components'

    def showGSEAResults(self):
        self.saveButton.config(state='disabled')
        self.component_menu.config(state='normal')
        self.updateButton.config(state='normal')
        self.setGateButton.config(state='disabled')
        self.visMenu.entryconfig(6, state='disabled')

        self.resetCanvas()
        self.canvas = tk.Canvas(self, width=600, height=300)
        self.canvas.grid(column=1, row=1, rowspan=17, columnspan=4)
        self.outputText(1)
        self.currentPlot = 'GSEA_result_' + self.diff_component.get()

    def updateComponent(self):
        self.resetCanvas()
        self.canvas = tk.Canvas(self, width=600, height=300)
        self.canvas.grid(column=1,
                         row=1,
                         rowspan=17,
                         columnspan=4,
                         sticky='NSEW')
        self.outputText(int(self.diff_component.get().split(' ')[-1]))
        self.currentPlot = 'GSEA_result_' + self.diff_component.get()

    def outputText(self, diff_component):
        pos_text = str(self.reports[diff_component]['pos']).split('\n')
        pos_text = pos_text[1:len(pos_text) - 1]
        pos_text = '\n'.join(pos_text)
        neg_text = str(self.reports[diff_component]['neg']).split('\n')
        neg_text = neg_text[1:len(neg_text) - 1]
        neg_text = '\n'.join(neg_text)
        self.canvas.create_text(5,
                                5,
                                anchor='nw',
                                text='Positive correlations:\n\n',
                                font=('Helvetica', 16, 'bold'))
        self.canvas.create_text(5, 50, anchor='nw', text=pos_text)
        self.canvas.create_text(5,
                                150,
                                anchor='nw',
                                text='Negative correlations:\n\n',
                                font=('Helvetica', 16, 'bold'))
        self.canvas.create_text(5, 200, anchor='nw', text=neg_text)

    def plotWBOnTsne(self):
        self.saveButton.config(state='normal')
        self.setGateButton.config(state='disabled')
        if self.scdata.data_type == 'sc-seq':
            self.component_menu.config(state='disabled')
            self.updateButton.config(state='disabled')
            self.visMenu.entryconfig(6, state='disabled')
        else:
            self.visMenu.entryconfig(4, state='disabled')

        self.resetCanvas()
        self.fig, self.ax = self.wb.plot_wishbone_on_tsne()
        self.canvas = FigureCanvasTkAgg(self.fig, self)
        self.canvas.show()
        self.canvas.get_tk_widget().grid(column=1,
                                         row=1,
                                         rowspan=10,
                                         columnspan=4)
        self.currentPlot = 'wishbone_on_tsne'

    def plotWBMarkerTrajectory(self):
        self.getGeneSelection()
        if len(self.selectedGenes) < 1:
            print('Error: must select at least one gene')

        else:
            self.saveButton.config(state='normal')
            self.setGateButton.config(state='disabled')
            if self.scdata.data_type == 'sc-seq':
                self.component_menu.config(state='disabled')
                self.updateButton.config(state='disabled')
                self.visMenu.entryconfig(6, state='disabled')
            else:
                self.visMenu.entryconfig(4, state='disabled')

            self.resetCanvas()
            self.vals, self.fig, self.ax = self.wb.plot_marker_trajectory(
                self.selectedGenes)
            self.fig.set_size_inches(10, 4, forward=True)
            self.fig.tight_layout()
            self.fig.subplots_adjust(right=0.8)
            self.canvas = FigureCanvasTkAgg(self.fig, self)
            self.canvas.show()
            self.canvas.get_tk_widget().grid(column=1,
                                             row=1,
                                             rowspan=10,
                                             columnspan=5,
                                             sticky='W')
            self.currentPlot = 'wishbone_marker_trajectory'
            self.geometry('1050x550')

            #enable buttons
            self.wishboneMenu.entryconfig(2, state='normal')

    def plotWBHeatMap(self):
        self.getGeneSelection()
        if len(self.selectedGenes) < 1:
            print('Error: must select at least one gene')

        else:
            self.saveButton.config(state='normal')
            self.setGateButton.config(state='disabled')
            if self.scdata.data_type == 'sc-seq':
                self.component_menu.config(state='disabled')
                self.updateButton.config(state='disabled')
                self.visMenu.entryconfig(6, state='disabled')
            else:
                self.visMenu.entryconfig(4, state='disabled')

            self.resetCanvas()
            self.vals, self.fig, self.ax = self.wb.plot_marker_trajectory(
                self.selectedGenes)
            self.fig, self.ax = self.wb.plot_marker_heatmap(self.vals)
            self.fig.set_size_inches(10, 4, forward=True)
            self.fig.tight_layout()
            self.canvas = FigureCanvasTkAgg(self.fig, self)
            self.canvas.show()
            self.canvas.get_tk_widget().grid(column=1,
                                             row=1,
                                             rowspan=10,
                                             columnspan=5,
                                             sticky='W')
            self.currentPlot = 'wishbone_marker_heatmap'

    def plotGeneExpOntSNE(self):
        self.getGeneSelection()
        if len(self.selectedGenes) < 1:
            print('Error: must select at least one gene')

        else:
            self.saveButton.config(state='normal')
            self.setGateButton.config(state='disabled')
            if self.scdata.data_type == 'sc-seq':
                self.component_menu.config(state='disabled')
                self.updateButton.config(state='disabled')
                self.visMenu.entryconfig(6, state='disabled')
            else:
                self.visMenu.entryconfig(4, state='disabled')

            self.resetCanvas()
            self.fig, self.ax = self.scdata.plot_gene_expression(
                self.selectedGenes)
            self.canvas = FigureCanvasTkAgg(self.fig, self)
            self.canvas.show()
            self.canvas.get_tk_widget().grid(column=1,
                                             row=1,
                                             rowspan=10,
                                             columnspan=4,
                                             sticky='W')
            self.currentPlot = 'gene_expression_tsne'
            self.geometry('950x550')

    def getGeneSelection(self):
        #popup menu to get selected genes
        self.geneSelection = tk.Toplevel()
        self.geneSelection.title("Select Genes")
        tk.Label(self.geneSelection, text=u"Genes:", fg="black",
                 bg="white").grid(row=0)

        self.geneInput = wishbone.autocomplete_entry.AutocompleteEntry(
            self.genes.tolist(), self.geneSelection, listboxLength=6)
        self.geneInput.grid(row=1)
        self.geneInput.bind('<Return>', self.AddToSelected)

        self.geneSelectBox = tk.Listbox(self.geneSelection,
                                        selectmode=tk.EXTENDED)
        self.geneSelectBox.grid(row=2, rowspan=10)
        self.geneSelectBox.bind('<BackSpace>', self.DeleteSelected)
        self.selectedGenes = []

        tk.Button(self.geneSelection,
                  text="Use selected genes",
                  command=self.geneSelection.destroy).grid(row=12)
        tk.Button(self.geneSelection,
                  text="Cancel",
                  command=self.cancelGeneSelection).grid(row=13)
        self.wait_window(self.geneSelection)

    def cancelGeneSelection(self):
        self.selectedGenes = []
        self.geneSelection.destroy()

    def AddToSelected(self, event):
        self.selectedGenes.append(self.geneInput.get())
        self.geneSelectBox.insert(
            tk.END, self.selectedGenes[len(self.selectedGenes) - 1])

    def DeleteSelected(self, event):
        selected = self.geneSelectBox.curselection()
        pos = 0
        for i in selected:
            idx = int(i) - pos
            self.geneSelectBox.delete(idx, idx)
            self.selectedGenes = self.selectedGenes[:idx] + self.selectedGenes[
                idx + 1:]
            pos = pos + 1

    def savePlot(self):
        self.plotFileName = filedialog.asksaveasfilename(
            title='Save Plot',
            defaultextension='.png',
            initialfile=self.fileNameEntryVar.get() + "_" + self.currentPlot)
        if self.plotFileName != None:
            self.fig.savefig(self.plotFileName)

    def setGate(self):
        #pop up for gate name
        self.gateOptions = tk.Toplevel()
        self.gateOptions.title("Create gate for start cells")
        tk.Label(self.gateOptions, text=u"Gate name:", fg="black",
                 bg="white").grid(column=0, row=0)
        self.gateName = tk.StringVar()
        self.gateName.set('Gate ' + str(len(self.gates) + 1))
        tk.Entry(self.gateOptions, textvariable=self.gateName).grid(column=1,
                                                                    row=0)
        tk.Button(self.gateOptions, text="Select gate",
                  command=self._setGate).grid(column=1, row=1)
        tk.Button(self.gateOptions,
                  text="Cancel",
                  command=self.gateOptions.destroy).grid(column=0, row=1)
        self.wait_window(self.gateOptions)

    def _setGate(self):
        self.gateOptions.destroy()
        self.buttonPress = self.canvas.mpl_connect('button_press_event',
                                                   self._startGate)
        self.buttonRelease = self.canvas.mpl_connect('button_release_event',
                                                     self._endGate)
        self.canvas.get_tk_widget().config(cursor='plus')

    def _startGate(self, event):
        self.start_x = event.xdata
        self.start_y = event.ydata

    def _endGate(self, event):
        #draw gate rectangle
        start_x = self.start_x if self.start_x < event.xdata else event.xdata
        start_y = self.start_y if self.start_y < event.ydata else event.ydata
        width = np.absolute(event.xdata - self.start_x)
        height = np.absolute(event.ydata - self.start_y)
        rect = Rectangle((start_x, start_y),
                         width,
                         height,
                         fill=False,
                         ec='black',
                         alpha=1,
                         lw=2)
        self.ax.add_patch(rect)
        self.canvas.draw()

        #disable mouse events
        self.canvas.mpl_disconnect(self.buttonPress)
        self.canvas.mpl_disconnect(self.buttonRelease)
        self.canvas.get_tk_widget().config(cursor='arrow')

        #save cell gate
        gate = Path([[start_x, start_y], [start_x + width, start_y],
                     [start_x + width, start_y + height],
                     [start_x, start_y + height], [start_x, start_y]])
        gated_cells = self.scdata.tsne.index[gate.contains_points(
            self.scdata.tsne)]
        self.gates[self.gateName.get()] = gated_cells

        #replot tSNE w gate colored
        self.fig.clf()
        plt.scatter(self.scdata.tsne['x'],
                    self.scdata.tsne['y'],
                    s=10,
                    edgecolors='none',
                    color='lightgrey')
        plt.scatter(self.scdata.tsne.ix[gated_cells, 'x'],
                    self.scdata.tsne.ix[gated_cells, 'y'],
                    s=10,
                    edgecolors='none')
        self.canvas.draw()

        self.setGateButton.config(state='disabled')
        self.visMenu.entryconfig(6, state='disabled')

    def resetCanvas(self):
        self.fig.clf()
        if type(self.canvas) is FigureCanvasTkAgg:
            for item in self.canvas.get_tk_widget().find_all():
                self.canvas.get_tk_widget().delete(item)
        else:
            for item in self.canvas.find_all():
                self.canvas.delete(item)

    def quitWB(self):
        self.quit()
        self.destroy()
Example #21
0
class Viewer(tk.Frame):
    def __init__(self, parent, collection=None, with_toolbar=True):
        tk.Frame.__init__(self, parent)
        # toolbar
        if with_toolbar:
            self.create_toolbar()

        # canvas
        #canvas_frame = tk.Frame(self)
        #canvas_frame.pack(side=tk.LEFT,fill=tk.BOTH,expand=1)
        #title_frame = tk.Frame(canvas_frame)
        #title_frame.pack(side=tk.TOP,anchor=tk.NW)
        #tk.Label(title_frame,text=" Plot Title: ").pack(side=tk.LEFT)
        #self._title = tk.Entry(title_frame,width=30)
        #self._title.pack(side=tk.LEFT)
        #tk.Button(title_frame, text='Set', command=lambda: self.updateTitle()
        #        ).pack(side=tk.LEFT)

        self.fig = plt.Figure(figsize=(8, 6))
        self.ax = self.fig.add_subplot(111)
        self.canvas = FigureCanvasTkAgg(self.fig, master=self)
        self.setupMouseNavigation()
        self.navbar = ToolBar(self.canvas, self,
                              self.ax)  # for matplotlib features
        self.setupNavBarExtras(self.navbar)
        self.canvas.get_tk_widget().pack(side=tk.LEFT, fill=tk.BOTH, expand=1)
        # spectra list
        self.create_listbox()
        # toggle options
        self.mean = False
        self.median = False
        self.max = False
        self.min = False
        self.std = False

        self.spectrum_mode = False
        self.show_flagged = True
        # data
        self.collection = collection
        self.head = 0
        self.flag_filepath = os.path.abspath('./flagged_spectra.txt')
        if collection:
            self.update_artists(new_lim=True)
            self.update_list()

        # pack
        self.pack(fill=tk.BOTH, expand=1)
        self.color = '#000000'

    def returnToSelectMode(self):
        if self.ax.get_navigate_mode() == 'PAN':
            #Turn panning off
            self.navbar.pan()
        elif self.ax.get_navigate_mode() == 'ZOOM':
            #Turn zooming off
            self.navbar.zoom()

    def setupNavBarExtras(self, navbar):
        working_dir = os.path.dirname(os.path.abspath(__file__))
        self.select_icon = tk.PhotoImage(
            file=os.path.join(working_dir, "select.png"))

        self.select_button = tk.Button(navbar,
                                       width="24",
                                       height="24",
                                       image=self.select_icon,
                                       command=self.returnToSelectMode).pack(
                                           side=tk.LEFT, anchor=tk.W)

        self.dirLbl = tk.Label(navbar, text="Viewing: None")
        self.dirLbl.pack(side=tk.LEFT, anchor=tk.W)

    def plotConfig(self):
        config = PlotConfigDialog(self,
                                  title=self.ax.get_title(),
                                  xlabel=self.ax.get_xlabel(),
                                  ylabel=self.ax.get_ylabel(),
                                  xlim=self.ax.get_xlim(),
                                  ylim=self.ax.get_ylim())
        if (config.applied):
            print(config.title)
            print(config.xlim)
            self.ax.set_title(config.title)
            self.ax.set_xlabel(config.xlabel)
            self.ax.set_ylabel(config.ylabel)
            self.ax.set_xlim(*config.xlim)
            self.ax.set_ylim(*config.ylim)
            self.canvas.draw()

    def rectangleStartEvent(self, event):
        self._rect = None
        self._rect_start = event

    def rectangleMoveEvent(self, event):
        try:
            dx = event.xdata - self._rect_start.xdata
            dy = event.ydata - self._rect_start.ydata
        except TypeError:
            #we're out of canvas bounds
            return

        if self._rect is not None:
            self._rect.remove()

        self._rect = Rectangle(
            (self._rect_start.xdata, self._rect_start.ydata),
            dx,
            dy,
            color='k',
            ls='--',
            lw=1,
            fill=False)
        self.ax.add_patch(self._rect)
        self.ax.draw_artist(self._rect)

    def rectangleEndEvent(self, event):
        if self._rect is not None:
            self._rect.remove()
        else:
            #make a small, fake rectangle
            class FakeEvent(object):
                def __init__(self, x, y):
                    self.xdata, self.ydata = x, y

            dy = (self.ax.get_ylim()[1] - self.ax.get_ylim()[0]) / 100.
            self._rect_start = FakeEvent(event.xdata - 10, event.ydata + dy)
            event = FakeEvent(event.xdata + 10, event.ydata - dy)

        if not self.collection is None:
            x0 = min(self._rect_start.xdata, event.xdata)
            x1 = max(self._rect_start.xdata, event.xdata)
            y0 = min(self._rect_start.ydata, event.ydata)
            y1 = max(self._rect_start.ydata, event.ydata)
            try:
                #if our data is sorted, we can easily isolate it
                x_data = self.collection.data.loc[x0:x1]
            except:
                #Pandas builtin throws an error, use another pandas builtin
                data = self.collection.data
                in_xrange = (data.index >= x0) & (data.index <= x1)
                x_data = data.iloc[in_xrange]

            ylim = sorted([self._rect_start.ydata, event.ydata])
            is_in_box = ((x_data > y0) & (x_data < y1)).any()

            highlighted = is_in_box.index[is_in_box].tolist()
            key_list = list(self.collection._spectra.keys())

            self.update_selected(highlighted)
            flags = self.collection.flags
            for highlight in highlighted:
                #O(n^2) woof
                if (not (highlight in flags)) or self.show_flagged:
                    pos = key_list.index(highlight)
                    self.listbox.selection_set(pos)

    def setupMouseNavigation(self):
        self.clicked = False
        self.select_mode = 'rectangle'
        self._bg_cache = None

        START_EVENTS = {'rectangle': self.rectangleStartEvent}

        MOVE_EVENTS = {'rectangle': self.rectangleMoveEvent}

        END_EVENTS = {'rectangle': self.rectangleEndEvent}

        def onMouseDown(event):
            if self.ax.get_navigate_mode() is None:
                self._bg_cache = self.canvas.copy_from_bbox(self.ax.bbox)
                self.clicked = True
                START_EVENTS[self.select_mode](event)

        def onMouseUp(event):
            if self.ax.get_navigate_mode() is None:
                self.canvas.restore_region(self._bg_cache)
                self.canvas.blit(self.ax.bbox)
                self.clicked = False
                END_EVENTS[self.select_mode](event)

        def onMouseMove(event):
            if self.ax.get_navigate_mode() is None:
                if (self.clicked):
                    self.canvas.restore_region(self._bg_cache)
                    MOVE_EVENTS[self.select_mode](event)
                    self.canvas.blit(self.ax.bbox)

        self.canvas.mpl_connect('button_press_event', onMouseDown)
        self.canvas.mpl_connect('button_release_event', onMouseUp)
        self.canvas.mpl_connect('motion_notify_event', onMouseMove)

    @property
    def head(self):
        return self._head

    @head.setter
    def head(self, value):
        if not hasattr(self, '_head'):
            self._head = 0
        else:
            self._head = value % len(self.collection)

    def set_head(self, value):
        if isinstance(value, Iterable):
            if len(value) > 0:
                value = value[0]
            else:
                value = 0
        self.head = value
        if self.spectrum_mode:
            self.update()
        self.update_selected()

    @property
    def collection(self):
        return self._collection

    @collection.setter
    def collection(self, value):
        if isinstance(value, Spectrum):
            # create new collection
            self._collection = Collection(name=Spectrum.name, spectra=[value])
        if isinstance(value, Collection):
            self._collection = value
        else:
            self._collection = None

    def move_selected_to_top(self):
        selected = self.listbox.curselection()
        keys = [self.collection.spectra[s].name for s in selected]
        for s in selected[::-1]:
            self.listbox.delete(s)
        self.listbox.insert(0, *keys)
        self.listbox.selection_set(0, len(keys))

    def unselect_all(self):
        self.listbox.selection_clear(0, tk.END)
        self.update_selected()

    def select_all(self):
        self.listbox.selection_set(0, tk.END)
        self.update_selected()

    def invert_selection(self):
        for i in range(self.listbox.size()):
            if self.listbox.selection_includes(i):
                self.listbox.selection_clear(i)
            else:
                self.listbox.selection_set(i)
        self.update_selected()

    def change_color(self):
        cpicker = ColorPickerDialog(self)
        #rgb,color = askcolor(self.color)
        if cpicker.applied:
            self.color = cpicker.color
            self.color_pick.config(bg=self.color)
            #update our list of chosen colors
            selected = self.listbox.curselection()
            selected_keys = [self.collection.spectra[s].name for s in selected]

            for key in selected_keys:
                self.colors[key] = self.color
            self.update()

    def select_by_name(self):
        pattern = self.name_filter.get()
        for i in range(self.listbox.size()):
            if pattern in self.listbox.get(i):
                self.listbox.selection_set(i)
            else:
                self.listbox.selection_clear(i)
        self.update_selected()

    def create_listbox(self):
        self._sbframe = tk.Frame(self)

        list_label = tk.Frame(self._sbframe)
        list_label.pack(side=tk.TOP, anchor=tk.N, fill=tk.X)
        tk.Label(list_label, text="Name:").pack(side=tk.LEFT, anchor=tk.W)
        self.name_filter = tk.Entry(list_label, width=14)
        self.name_filter.pack(side=tk.LEFT, anchor=tk.W)
        tk.Button(list_label,
                  text="Select",
                  command=lambda: self.select_by_name()).pack(side=tk.LEFT,
                                                              anchor=tk.W)
        self.sblabel = tk.Label(list_label, text="Showing: 0")
        self.sblabel.pack(side=tk.RIGHT)

        self.scrollbar = tk.Scrollbar(self._sbframe)
        self.listbox = tk.Listbox(self._sbframe,
                                  yscrollcommand=self.scrollbar.set,
                                  selectmode=tk.EXTENDED,
                                  width=30)
        self.scrollbar.config(command=self.listbox.yview)

        self.list_tools = tk.Frame(self._sbframe)
        tk.Button(self.list_tools,
                  text="To Top",
                  command=lambda: self.move_selected_to_top()).pack(
                      side=tk.TOP, anchor=tk.NW, fill=tk.X)
        tk.Button(self.list_tools,
                  text="Select All",
                  command=lambda: self.select_all()).pack(side=tk.TOP,
                                                          anchor=tk.NW,
                                                          fill=tk.X)
        tk.Button(self.list_tools,
                  text="Clear",
                  command=lambda: self.unselect_all()).pack(side=tk.TOP,
                                                            anchor=tk.NW,
                                                            fill=tk.X)
        tk.Button(self.list_tools,
                  text="Invert",
                  command=lambda: self.invert_selection()).pack(side=tk.TOP,
                                                                anchor=tk.NW,
                                                                fill=tk.X)

        self.color_field = tk.Frame(self.list_tools)
        tk.Label(self.color_field, text="Color:").pack(side=tk.LEFT)

        self.color_pick = tk.Button(self.color_field,
                                    text="",
                                    command=lambda: self.change_color(),
                                    bg='#000000')
        self.color_pick.pack(side=tk.RIGHT,
                             anchor=tk.NW,
                             fill=tk.X,
                             expand=True)

        self.color_field.pack(side=tk.TOP, anchor=tk.NW, fill=tk.X)

        self.list_tools.pack(side=tk.RIGHT, anchor=tk.NW)
        self.scrollbar.pack(side=tk.RIGHT, anchor=tk.E, fill=tk.Y)
        self.listbox.pack(side=tk.RIGHT, anchor=tk.E, fill=tk.Y)
        self.listbox.bind('<<ListboxSelect>>',
                          lambda x: self.set_head(self.listbox.curselection()))
        self._sbframe.pack(side=tk.RIGHT, anchor=tk.E, fill=tk.Y)

    def create_toolbar(self):
        self.toolbar = tk.Frame(self)
        tk.Button(self.toolbar, text='Read',
                  command=lambda: self.read_dir()).pack(side=tk.LEFT,
                                                        fill=tk.X,
                                                        expand=1)
        tk.Button(self.toolbar,
                  text='Mode',
                  command=lambda: self.toggle_mode()).pack(side=tk.LEFT,
                                                           fill=tk.X,
                                                           expand=1)
        tk.Button(self.toolbar,
                  text="Plot Config",
                  command=lambda: self.plotConfig()).pack(side=tk.LEFT,
                                                          fill=tk.X,
                                                          expand=1)
        tk.Button(self.toolbar,
                  text='Show/Hide Flagged',
                  command=lambda: self.toggle_show_flagged()).pack(
                      side=tk.LEFT, fill=tk.X, expand=1)
        tk.Button(self.toolbar,
                  text='Flag/Unflag',
                  command=lambda: self.toggle_flag()).pack(side=tk.LEFT,
                                                           fill=tk.X,
                                                           expand=1)
        tk.Button(self.toolbar,
                  text='Unflag all',
                  command=lambda: self.unflag_all()).pack(side=tk.LEFT,
                                                          fill=tk.X,
                                                          expand=1)
        #tk.Button(self.toolbar, text='Save Flag', command=lambda:
        #          self.save_flag()).pack(side=tk.LEFT,fill=tk.X,expand=1)
        tk.Button(self.toolbar,
                  text='Save Flags',
                  command=lambda: self.save_flag_as()).pack(side=tk.LEFT,
                                                            fill=tk.X,
                                                            expand=1)
        tk.Button(self.toolbar, text='Stitch',
                  command=lambda: self.stitch()).pack(side=tk.LEFT,
                                                      fill=tk.X,
                                                      expand=1)
        tk.Button(self.toolbar,
                  text='Jump_Correct',
                  command=lambda: self.jump_correct()).pack(side=tk.LEFT,
                                                            fill=tk.X,
                                                            expand=1)
        tk.Button(self.toolbar,
                  text='mean',
                  command=lambda: self.toggle_mean()).pack(side=tk.LEFT,
                                                           fill=tk.X,
                                                           expand=1)
        tk.Button(self.toolbar,
                  text='median',
                  command=lambda: self.toggle_median()).pack(side=tk.LEFT,
                                                             fill=tk.X,
                                                             expand=1)
        tk.Button(self.toolbar, text='max',
                  command=lambda: self.toggle_max()).pack(side=tk.LEFT,
                                                          fill=tk.X,
                                                          expand=1)
        tk.Button(self.toolbar, text='min',
                  command=lambda: self.toggle_min()).pack(side=tk.LEFT,
                                                          fill=tk.X,
                                                          expand=1)
        tk.Button(self.toolbar, text='std',
                  command=lambda: self.toggle_std()).pack(side=tk.LEFT,
                                                          fill=tk.X,
                                                          expand=1)
        self.toolbar.pack(side=tk.TOP, fill=tk.X)

    def updateTitle(self):
        print("Hello world!")
        self.ax.set_title(self._title.get())
        self.canvas.draw()

    def set_collection(self, collection):
        new_lim = True if self.collection is None else False
        self.collection = collection
        self.update_artists(new_lim=new_lim)
        self.update()
        self.update_list()

    def read_dir(self):
        try:
            directory = os.path.split(
                filedialog.askopenfilename(filetypes=(
                    ("Supported types", "*.asd *.sed *.sig *.pico"),
                    ("All files", "*"),
                )))[0]
        except:
            return
        if not directory:
            return
        c = Collection(name="collection", directory=directory)
        self.set_collection(c)
        self.dirLbl.config(text="Viewing: " + directory)

    def reset_stats(self):
        if self.mean_line:
            self.mean_line.remove()
            self.mean_line = None
            self.mean = False
        if self.median_line:
            self.median_line.remove()
            self.median_line = None
            self.median = False
        if self.max_line:
            self.max_line.remove()
            self.max_line = None
            self.max = False
        if self.min_line:
            self.min_line.remove()
            self.min_line = None
            self.min = False
        if self.std_line:
            self.std_line.remove()
            self.std_line = None
            self.std = False

    def toggle_mode(self):
        if self.spectrum_mode:
            self.spectrum_mode = False
        else:
            self.spectrum_mode = True
        self.update()

    def toggle_show_flagged(self):
        if self.show_flagged:
            self.show_flagged = False
        else:
            self.show_flagged = True
        self.update()

    def unflag_all(self):
        #new flags -> new statistics
        self.reset_stats()

        for spectrum in list(self.collection.flags):
            self.collection.unflag(spectrum)
        self.update()
        self.update_list()

    def toggle_flag(self):
        #new flags -> new statistics
        self.reset_stats()

        selected = self.listbox.curselection()
        keys = [self.listbox.get(s) for s in selected]

        for i, key in enumerate(keys):
            print(i, key)
            spectrum = key
            if spectrum in self.collection.flags:
                self.collection.unflag(spectrum)
                self.listbox.itemconfigure(selected[i], foreground='black')
            else:
                self.collection.flag(spectrum)
                self.listbox.itemconfigure(selected[i], foreground='red')
        # update figure
        self.update()

    def save_flag(self):
        ''' save flag to self.flag_filepath'''
        with open(self.flag_filepath, 'w') as f:
            for spectrum in self.collection.flags:
                print(spectrum, file=f)

    def save_flag_as(self):
        ''' modify self.flag_filepath and call save_flag()'''
        flag_filepath = filedialog.asksaveasfilename()
        if os.path.splitext(flag_filepath)[1] == '':
            flag_filepath = flag_filepath + '.txt'
        self.flag_filepath = flag_filepath
        self.save_flag()

    def update_list(self):
        self.listbox.delete(0, tk.END)
        for i, spectrum in enumerate(self.collection.spectra):
            self.listbox.insert(tk.END, spectrum.name)
            if spectrum.name in self.collection.flags:
                self.listbox.itemconfigure(i, foreground='red')
        self.update_selected()

    def ask_for_draw(self):
        #debounce canvas updates
        now = datetime.now()
        print(now - self.last_draw)
        if ((now - self.last_draw).total_seconds() > 0.5):
            self.canvas.draw()
            self.last_draw = now

    def update_artists(self, new_lim=False):
        if self.collection is None:
            return
        #update values being plotted -> redo statistics
        self.mean_line = None
        self.median_line = None
        self.max_line = None
        self.min_line = None
        self.std_line = None
        # save limits
        if new_lim == False:
            xlim = self.ax.get_xlim()
            ylim = self.ax.get_ylim()
        # plot
        self.ax.clear()
        # show statistics
        if self.spectrum_mode:
            idx = self.listbox.curselection()
            if len(idx) == 0:
                idx = [self.head]
            spectra = [self.collection.spectra[i] for i in idx]
            flags = [s.name in self.collection.flags for s in spectra]
            print("flags = ", flags)
            flag_style = ' '
            if self.show_flagged:
                flag_style = 'r'
            artists = Collection(name='selection', spectra=spectra).plot(
                ax=self.ax,
                style=list(np.where(flags, flag_style, self.color)),
                picker=1)
            self.ax.set_title('selection')
            # c = str(np.where(spectrum.name in self.collection.flags, 'r', 'k'))
            # spectrum.plot(ax=self.ax, label=spectrum.name, c=c)
        else:
            # red curves for flagged spectra
            flag_style = ' '
            if self.show_flagged:
                flag_style = 'r'
            flags = [
                s.name in self.collection.flags
                for s in self.collection.spectra
            ]
            print("flags = ", flags)
            self.collection.plot(ax=self.ax,
                                 style=list(np.where(flags, flag_style, 'k')),
                                 picker=1)
            #self.ax.set_title(self.collection.name)

        keys = [s.name for s in self.collection.spectra]
        artists = self.ax.lines
        self.artist_dict = {key: artist for key, artist in zip(keys, artists)}
        self.colors = {key: 'black' for key in keys}
        self.ax.legend().remove()
        self.navbar.setHome(self.ax.get_xlim(), self.ax.get_ylim())
        self.canvas.draw()
        self.sblabel.config(text="Showing: {}".format(len(artists)))

    def update_selected(self, to_add=None):
        """ Update, only on flaged"""
        if self.collection is None:
            return

        if to_add:
            for key in to_add:
                self.artist_dict[key].set_linestyle('--')
        else:
            keys = [s.name for s in self.collection.spectra]
            selected = self.listbox.curselection()
            selected_keys = [self.collection.spectra[s].name for s in selected]
            for key in keys:
                if key in selected_keys:
                    self.artist_dict[key].set_linestyle('--')
                else:
                    self.artist_dict[key].set_linestyle('-')
        self.canvas.draw()

    def update(self):
        """ Update the plot """
        if self.collection is None:
            return
        # show statistics
        if self.spectrum_mode:
            self.ax.clear()
            idx = self.listbox.curselection()
            if len(idx) == 0:
                idx = [self.head]
            spectra = [self.collection.spectra[i] for i in idx]
            flags = [s.name in self.collection.flags for s in spectra]
            print("flags = ", flags)
            flag_style = ' '
            if self.show_flagged:
                flag_style = 'r'
            Collection(name='selection', spectra=spectra).plot(
                ax=self.ax,
                style=list(np.where(flags, flag_style, 'k')),
                picker=1)
            self.ax.set_title('selection')
            # c = str(np.where(spectrum.name in self.collection.flags, 'r', 'k'))
            # spectrum.plot(ax=self.ax, label=spectrum.name, c=c)
        else:
            # red curves for flagged spectra

            keys = [s.name for s in self.collection.spectra]
            for key in keys:
                if key in self.collection.flags:
                    if self.show_flagged:
                        self.artist_dict[key].set_visible(True)
                        self.artist_dict[key].set_color('red')
                    else:
                        self.artist_dict[key].set_visible(False)
                else:
                    self.artist_dict[key].set_color(self.colors[key])
                    self.artist_dict[key].set_visible(True)

            if self.show_flagged:
                self.sblabel.config(
                    text="Showing: {}".format(len(self.artist_dict)))
            else:
                self.sblabel.config(text="Showing: {}".format(
                    len(self.artist_dict) - len(self.collection.flags)))
            '''
            self.collection.plot(ax=self.ax,
                                 style=list(np.where(flags, flag_style, 'k')),
                                 picker=1)
            self.ax.set_title(self.collection.name)
            '''

        if self.spectrum_mode:
            #self.ax.legend()
            pass
        else:
            #self.ax.legend().remove()
            pass
        self.ax.set_ylabel(self.collection.measure_type)
        #toggle appearance of statistics
        if self.mean_line != None: self.mean_line.set_visible(self.mean)
        if self.median_line != None: self.median_line.set_visible(self.median)
        if self.max_line != None: self.max_line.set_visible(self.max)
        if self.min_line != None: self.min_line.set_visible(self.min)
        if self.std_line != None: self.std_line.set_visible(self.std)
        self.canvas.draw()

    def next_spectrum(self):
        if not self.spectrum_mode:
            return
        self.head = (self.head + 1) % len(self.collection)
        self.update()

    def stitch(self):
        ''' 
        Known Bugs
        ----------
        Can't stitch one spectrum and plot the collection
        '''
        self.collection.stitch()
        self.update_artists()

    def jump_correct(self):
        ''' 
        Known Bugs
        ----------
        Only performs jump correction on 1000 and 1800 wvls and 1 reference
        '''
        self.collection.jump_correct([1000, 1800], 1)
        self.update_artists()

    def toggle_mean(self):
        if self.mean:
            self.mean = False

        else:
            self.mean = True
            if not self.mean_line:
                self.collection.mean().plot(ax=self.ax,
                                            c='b',
                                            label=self.collection.name +
                                            '_mean',
                                            lw=3)
                self.mean_line = self.ax.lines[-1]
        self.update()

    def toggle_median(self):
        if self.median:
            self.median = False
        else:
            self.median = True
            if not self.median_line:
                self.collection.median().plot(ax=self.ax,
                                              c='g',
                                              label=self.collection.name +
                                              '_median',
                                              lw=3)
                self.median_line = self.ax.lines[-1]
        self.update()

    def toggle_max(self):
        if self.max:
            self.max = False
        else:
            self.max = True
            if not self.max_line:
                self.collection.max().plot(ax=self.ax,
                                           c='y',
                                           label=self.collection.name + '_max',
                                           lw=3)
                self.max_line = self.ax.lines[-1]
        self.update()

    def toggle_min(self):
        if self.min:
            self.min = False
        else:
            self.min = True
            if not self.min_line:
                self.collection.min().plot(ax=self.ax,
                                           c='m',
                                           label=self.collection.name + '_min',
                                           lw=3)
                self.min_line = self.ax.lines[-1]
        self.update()

    def toggle_std(self):
        if self.std:
            self.std = False
        else:
            self.std = True
            if not self.std_line:
                self.collection.std().plot(ax=self.ax,
                                           c='c',
                                           label=self.collection.name + '_std',
                                           lw=3)
                self.std_line = self.ax.lines[-1]
        self.update()
# plt.title('Databricks Visualization')


t = arange(0.0, 3.0, 0.01)
s = sin(2*pi*t)

# ax.plot(t, s)



canvas = FigureCanvasTkAgg(fig, master=root)
canvas.show()
canvas.get_tk_widget().pack(side=Tk.TOP, fill=Tk.BOTH, expand=1)

canvas.set_window_title('AMON')
canvas.mpl_connect('button_press_event', onClick)
canvas.show()
# using evaluate built-in function-- taken in an expression and evaluates it!

def evaluate(event):
    data = e.get()
    print data


e = Entry(root)
e.bind("<Return>", evaluate)
e.pack()

while True:
    im = ax.imshow(np.random.random([128,128]), origin = 'upper', cmap=plt.cm.RdYlGn, interpolation = 'nearest', vmax = 0, vmin = -400000)
s = sin(2 * pi * t)
a.plot(t, s)

# canvas

canvas = FigureCanvasTkAgg(f, master=root)
canvas.show()
canvas.get_tk_widget().pack(side=Tk.BOTTOM, fill=Tk.BOTH, expand=True)

toolbar = NavigationToolbar2TkAgg(canvas, root)
toolbar.update()
canvas._tkcanvas.pack(side=Tk.TOP, fill=Tk.BOTH, expand=True)


def on_key_event(event):
    print('presiona %s' % event.key)
    key_press_handler(event, canvas, toolbar)


canvas.mpl_connect('key_press_event', on_key_event)


def _quit():
    root.quit()
    root.destroy()


button = Tk.Button(master=root, text='Salir', command=_quit)
button.pack(side=Tk.BOTTOM)
root.mainloop()
def quickPlayer(soundfile,
                data,
                stamps,
                names,
                h=128,
                onlyValues=False,
                regions=None):
    """
    USAGE:
    press spacebar to start/stop playing. 
    Navigate by clicking on plot, and with 'zoom' and 'pan' features of the toolbar.
    Zoom: Click and drag. Right click to zoom out.
   
    Plot and player will automatically follow if zoomed. But if zoomed too much, it may cause stuttering.
    Panning while audio is being played will cause stuttering.
    
    ARGS:
    onlyValues: If  provided time stamps does not have IDs or names (so just lines to be drawn), this should be True. Manually annotated files will have IDs and names for the stamps  . 
    
    soundfile: sound file to be played
    data: data that shown on the player plot
    stamps: lines will be drawed on these points on the data
    h: hopsize
    
    size(data) * h = size(sound)      If you pass audio samples as data, h (hop size) should be 1.
    """

    wf = wave.open(soundfile, 'rb')
    parent = Tk()

    chunk_size = 2048
    sem = asyncio.Semaphore()
    play_mode = tk.BooleanVar(parent, False)

    fig = plt.figure(figsize=(18, 7), dpi=100)
    mainplot = fig.add_subplot(111)

    canvas = FigureCanvasTkAgg(fig, parent)
    canvaswidget = canvas.get_tk_widget()
    canvaswidget.grid(row=2, column=0, columnspan=5, sticky=W)

    toolbarFrame = Frame(master=parent)
    toolbarFrame.grid(row=3, column=0, columnspan=7)
    toolbar = NavigationToolbar2Tk(canvas, toolbarFrame)
    toolbar.update()

    canvas._tkcanvas.grid(row=2, column=0, columnspan=7, sticky=W)
    global background
    background = canvas.copy_from_bbox(mainplot.bbox)
    cursor = mainplot.axvline(color="k", animated=True)
    cursor.set_xdata(0)

    for d in data:
        if d.ndim == 2:
            ymax = d.shape[1]
            ymin = 0
            mainplot.pcolormesh(np.arange(d.shape[0]), np.arange(d.shape[1]),
                                np.transpose(d))
        if d.ndim == 1:
            ymax = np.max(data[0])
            ymin = np.min(data[0])
            mainplot.plot(d)
    global x0, x1
    x0, x1 = mainplot.get_xlim()

    p = pyaudio.PyAudio()

    def callbackstream(in_data, frame_count, time_info, status):
        sem.acquire()
        data = wf.readframes(frame_count)
        parent.event_generate("<<playbackmove>>", when="now")
        sem.release()
        return (data, pyaudio.paContinue)

    _callbackstream = callbackstream

    def initStream():
        global stream
        stream = p.open(format=8,
                        channels=1,
                        rate=44100,
                        output=True,
                        stream_callback=_callbackstream,
                        start=True,
                        frames_per_buffer=chunk_size)

    def playsound(event=None):
        if sem.locked():
            return
        if play_mode.get() == True:
            # this is broken
            global stream
            stream.close()
            play_mode.set(False)
        else:
            try:
                initStream()
                play_mode.set(True)
            except:
                print("play failed")

    def playbackMove(event=None):  # move cursor by audio chunk size
        global x0, x1
        global background
        incr = (chunk_size) // h
        nextpos = cursor.get_xdata() + incr
        cursor.set_xdata(nextpos)
        updateCursor()
        if (x1 - nextpos) < 0:
            mainplot.set_xlim(x1, x1 + x1 - x0)
            canvas.draw()

            toolbar.push_current()
            background = canvas.copy_from_bbox(mainplot.bbox)
            x0, x1 = mainplot.get_xlim()

    def new_release_zoom(*args, **kwargs):
        global x0, x1
        release_zoom_orig(*args, **kwargs)
        s = 'toolbar_event'
        event = Event(s, canvas)
        canvas.callbacks.process(s, Event('toolbar_event', canvas))
        x0, x1 = mainplot.get_xlim()

    def new_release_pan(*args, **kwargs):
        global x0, x1
        release_pan_orig(*args, **kwargs)
        s = 'toolbar_event'
        event = Event(s, canvas)
        canvas.callbacks.process(s, Event('toolbar_event', canvas))
        x0, x1 = mainplot.get_xlim()

    def new_update_view(*args, **kwargs):
        global x0, x1
        _update_view_orig(*args, **kwargs)
        s = 'toolbar_event'
        event = Event(s, canvas)
        canvas.callbacks.process(s, Event('toolbar_event', canvas))
        x0, x1 = mainplot.get_xlim()

    def handle_toolbar(event):
        global x0, x1
        canvas.draw()
        global background
        background = canvas.copy_from_bbox(mainplot.bbox)

    def onclick(event):
        if (toolbar._active == 'ZOOM' or toolbar._active == 'PAN'):
            pass
        else:
            cursor.set_xdata(event.xdata)
            wf.setpos(int(event.xdata * h))
            updateCursor()

    def updateCursor():
        canvas.restore_region(background)
        mainplot.draw_artist(cursor)
        canvas.blit(mainplot.bbox)

    parent.bind("<space>", playsound)
    parent.bind("<<playbackmove>>", playbackMove)

    release_zoom_orig = toolbar.release_zoom
    toolbar.release_zoom = new_release_zoom
    release_pan_orig = toolbar.release_pan
    toolbar.release_pan = new_release_pan
    _update_view_orig = toolbar._update_view
    toolbar._update_view = new_update_view

    canvas.mpl_connect('toolbar_event', handle_toolbar)
    cid1 = canvas.mpl_connect("button_press_event", onclick)

    canvas.draw()

    colors = [
        'c', 'm', 'y', 'r', '#FFBD33', '#924A03', '#D00000', '#D000D0',
        '#6800D0', '#095549', 'b', 'r', 'r'
    ]
    if onlyValues:
        for i in range(len(stamps)):
            mainplot.draw_artist(
                mainplot.vlines(x=np.array(stamps[i]) / h,
                                color=colors[i],
                                ymin=ymin,
                                ymax=ymax,
                                label=names[i]))
            mainplot.legend(loc="upper left")
    else:
        for i in range(len(stamps)):
            for j in stamps[i]:
                mainplot.draw_artist(
                    mainplot.axvline(x=j[1] / h,
                                     ymin=ymin,
                                     ymax=ymax,
                                     color=colors[i]))
                mainplot.text(j[1] / h + 2, (0.8 * ymax) + (i * 0.04),
                              names[i] + str(j[0]),
                              bbox=dict(fill=False,
                                        edgecolor=colors[i],
                                        linewidth=1))

    if regions != None:
        for r in regions:
            mainplot.fill_betweenx([ymin, ymax],
                                   r[0],
                                   r[1],
                                   facecolor='blue',
                                   alpha=0.5)

    canvas.draw()
    background = canvas.copy_from_bbox(mainplot.bbox)

    parent.mainloop()

    for func in [stream.close, wf.close, p.terminate, parent.destroy]:
        try:
            func()
        except:
            pass

    return
Example #25
0
class MapPage(tk.Frame):
    '''
    A page that will show the map of currently plotted earthquakes from the 'current_data.json' file
    '''
    def __init__(self, parent, controller):
        super().__init__(parent)
        self.controller = controller
        self.local_url = None
        self.mappage_balloon = Pmw.Balloon(self)

        self.bind("<<RefreshPlot>>", self.refresh_plot)

        self.menubar = Pmw.MenuBar(self, hull_relief="raised", hull_borderwidth=1, balloon=self.mappage_balloon)
        self.menubar.pack(side="top", fill="x")

        self.menubar.addmenu("pages", "Switch Pages", "", "right")
        self.menubar.addmenu("file", "File And Data Options")
        self.menubar.addmenuitem("file", "command", "Quit The Program",
            command=self.controller.on_close_window, label="Quit")

        self.menubar.addmenuitem("pages", "command", "Switch To Settings Page",
            command=lambda: self.controller.show_frame("SettingsPage"), label="Settings Page")

        self.map_frame = tk.Frame(self)
        self.map_frame.pack(side="bottom", fill="both", expand=True)

        #Line2D objects are used here to be placed in the legend of the graph for more detail on the map
        legend_elements = [Line2D([0], [0], marker="o", color="green", label="Small (below 3)"),
                    Line2D([0], [0], marker="o", color="yellow", label="Medium (below 6)"),
                    Line2D([0], [0], marker="o", color="red", label="Large (above 6)")]

        self.map_figure = plt.figure(num=None, figsize=(12, 4))
        self.map_axes = self.map_figure.add_subplot(111)
        self.map_axes_legend = self.map_axes.legend(handles=legend_elements, loc="upper right") #placing the legend
        self.map_axes.set_title("Earthquake Events - Mercator Projection")
        self.map_figure.tight_layout() #makes sure that when placing the map onto the GUI, it is responsive

        self.figure_basemap = Basemap(projection="merc", llcrnrlat=-80, urcrnrlat=80,
            llcrnrlon=-180, urcrnrlon=180, resolution="c") #defines that the map is using mercator projection
        
        self.figure_basemap.drawcoastlines()
        self.figure_basemap.fillcontinents(color="tan", lake_color="lightblue")
        self.figure_basemap.drawstates(color="darkred")
        self.figure_basemap.drawparallels(np.arange(-90.,91.,30.), labels=(True, True, False, False), dashes=(2,2))
        self.figure_basemap.drawmeridians(np.arange(-180.,181.,60.), labels=(False, False, False, True), dashes=(2,2))
        self.figure_basemap.drawmapboundary(fill_color="lightblue")
        self.figure_basemap.drawcountries()

        self.figure_canvas = FigureCanvasTkAgg(self.map_figure, self.map_frame) #creates the figure and draws the map onto it
        self.figure_canvas.draw()
        self.figure_canvas.get_tk_widget().pack(side="bottom", fill="both", expand=True)
        self.canvas_pick_event = self.figure_canvas.mpl_connect("pick_event", self.display_point_info)
        
        self.figure_toolbar = NavigationToolbar2Tk(self.figure_canvas, self.map_frame) #Toolbar with additional options is added to the figure
        self.figure_toolbar.update()
        self.figure_canvas._tkcanvas.pack(side="top", fill="both", expand=True)
    
    def refresh_plot(self, event):
        '''
        Method for checking whether there is any different data to plot and if so
        reads it from the json file, done by checking the local_url against controller's current_url
        '''
        if self.local_url == self.controller.current_url:
            return "Same Request"

        self.local_url = self.controller.current_url
        with open("current_data.json", "r") as json_file:
            data = json.load(json_file)
        
        self.plot_points(data)
        messagebox.showinfo(title="Data Plotted", message="{} points plotted".format(data["metadata"]["count"]))

    def plot_points(self, filedata):
        '''
        Method for creating MapPoint objects and plotting them on the figure, by first clearing the figure of any
        previous plots and then reading 'current_data.json'
        '''
        self.map_axes.lines.clear()
        
        for quake in filedata["features"]:
            lat=quake["geometry"]["coordinates"][1]
            if lat > 80: lat=80
            elif lat <-80: lat=-80
            nx,ny = self.figure_basemap((quake["geometry"]["coordinates"][0],), (lat,))

            new_point = MapPoint(nx, ny, quake["properties"]["mag"], quake["properties"]["place"],
                quake["properties"]["time"], quake["properties"]["felt"], quake["properties"]["cdi"],
                quake["properties"]["mmi"], quake["properties"]["alert"], quake["properties"]["tsunami"],
                quake["properties"]["sig"], quake["properties"]["title"], quake["properties"]["status"],
                quake["properties"]["dmin"], quake["properties"]["gap"], quake["properties"]["magType"],
                quake["properties"]["type"])
            
            self.map_axes.add_line(new_point)
        self.figure_canvas.draw()
    
    def display_point_info(self, event):
        '''
        Method when an individual point is picked, prompts the user to view information about it
        '''
        line_obj = event.artist
        
        messagebox.showinfo(title="Point Selected", message="Here is more info about the point - {}".format(line_obj.place))
        self.figure_canvas.mpl_disconnect(self.canvas_pick_event)
        self.controller.call_display_info(line_obj)
        self.controller.show_frame("PointInfoPage")

    def reconnect_pick_event(self):
        '''
        Method to reconnect pick event with the figure after a previous disconnect
        '''
        self.canvas_pick_event = self.figure_canvas.mpl_connect("pick_event", self.display_point_info)
Example #26
0
class Gui :
    """
    A tkinter GUI to quickly visualize ARPES data, i.e. cuts and maps. Should 
    be built in a modular fashion such that any data reader can be 'plugged in'.

    data      : 3D array; the raw data from the selected file. This is 
                expected to be in the shape (z, x, y) (z may be equal to 1)
    pp_data   : 3D array; the postprocessed data to be displayed.
    cmaps     : list of str; a list of available matplotlib colormap names.
    xscale, yscale, zscale
              : 1D arrays; the x, y and z-axis data.
    cursor_xy : tuple; current location of the cursor in the bottom left plot.
    dpi       : int; resolution at which to save .png`s.
    """
    data = STARTUP_DATA
    pp_data = STARTUP_DATA.copy()
    cmaps = CMAPS
    xscale = None
    yscale = None
    zscale = None
    cursor_xy = None
    dpi = DPI
    main_mesh = None
    vmain_mesh = None
    cut1 = None
    cut2 = None

    def __init__(self, master, filename=None) :
        """ This init function mostly just calls all 'real' initialization 
        functions where the actual work is outsourced to. """
        # Create the main container/window
        frame = tk.Frame(master)

        # Define some elements
        self._set_up_load_button(master)
        self._set_up_pp_selectors(master)
        self._set_up_plots(master)
        self._set_up_colormap_sliders(master)
        self._set_up_z_slider(master)
        self._set_up_integration_range_selector(master)
        self._set_up_status_label(master)

        # Align all elements
        self._align()

        # Load the given file
        if filename :
            self.filepath.set(filename)
            self.load_data()

        # The setup of event handling requires there to be some data already
        self._set_up_event_handling()

    def _align(self) :
        """ Use the grid() layout manager to align the elements of the GUI. 
        At this stage of development the grid has 12 columns of unequal size.
        """
        # The plot takes up the space of PLOT_COLUMNSPAN widgets
        PLOT_COLUMNSPAN = 8
        PLOT_ROWSPAN = 3
        N_PATH_FIELD = PLOT_COLUMNSPAN

        # 'Load file' elements
        LOADROW = 0
        c = 0
        self.browse_button.grid(row=LOADROW, column=c, sticky='ew')
        c += 1
        self.load_button.grid(row=LOADROW, column=c, sticky='ew')
        c += 1
        self.decrement_button.grid(row=LOADROW, column=c, sticky='ew')
        c += 1
        self.increment_button.grid(row=LOADROW, column=c, sticky='ew')
        c += 1
        self.path_field.grid(row=LOADROW, column=c, columnspan=N_PATH_FIELD, 
                             sticky='ew') 

        # Postprocessing selectors
        PPROW = LOADROW + 1
        c = 0
        for lst in self.radiobuttons :
            r = 0
            for btn in lst :
                btn.grid(row=PPROW+r, column=c, sticky='ew')
                r += 1
            c += 1

        # Plot & colormap sliders & selector
        PLOTROW = PPROW + max([len(lst) for lst in self.radiobuttons])
        PLOTCOLUMN = 1
        self.canvas.get_tk_widget().grid(row=PLOTROW, column=PLOTCOLUMN, 
                                         rowspan=PLOT_ROWSPAN, columnspan=PLOT_COLUMNSPAN)
        right_of_plot = PLOT_COLUMNSPAN + PLOTCOLUMN
        self.cm_min_slider.grid(row=PLOTROW, column=right_of_plot + 1)
        self.cm_max_slider.grid(row=PLOTROW, column=right_of_plot + 2)
        self.cmap_dropdown.grid(row=PLOTROW + 1, column=right_of_plot + 1)
        self.invert_cmap_checkbutton.grid(row=PLOTROW + 1, column=right_of_plot + 2)

        # Save png button
        self.save_button.grid(row=PLOTROW + 2, column=right_of_plot + 1)

        # z slider, integration range selector
        self.z_slider.grid(row=PLOTROW, column=0)
        self.integration_range_entry.grid(row=PLOTROW+1, column=0)

        # Put the status label at the very bottom left
        STATUSROW = PLOTROW + PLOT_ROWSPAN + 1
        self.status_label.grid(row=STATUSROW, column=0, columnspan=10,
                               sticky='ew')

    def _set_up_load_button(self, master) :
        """ Add a button which opens a filebrowser to choose the file to load
        and a textbox (Entry widget) where the filepath can be changed.
        """
        # Define the Browse button
        self.browse_button = tk.Button(master, text='Browse',
                                     command=self.browse)

        # and the Load button
        self.load_button = tk.Button(master, text='Load',
                                     command=self.load_data)
        
        # and the entry field which holds the path to the current file
        self.filepath = tk.StringVar()
        self.path_field = tk.Entry(master, textvariable=self.filepath)

        # Also add inc and decrement buttons
        self.increment_button = tk.Button(master, text='>',
                                          command=lambda : self.increment(1)) 
        self.decrement_button = tk.Button(master, text='<',
                                          command=lambda : self.increment(-1)) 

        # Add a 'save' button for creating png s
        self.save_button = tk.Button(master, text='Save png', 
                                     command=self.save_plot)

    def _set_up_pp_selectors(self, master) :
        """ Create radiobuttons for the selction of postprocessing methods. 
        The order of the pp methods in all lists is:
            0) Make map
            1) BG subtraction
            2) Normalization
            3) derivative
        """
        # Create control variables to hold the selections and store them in a 
        # list for programmatic access later on
        self.map = tk.StringVar()
        self.subtractor = tk.StringVar()
        self.normalizer = tk.StringVar()
        self.derivative = tk.StringVar()
        self.selection = [self.map,
                          self.subtractor,
                          self.normalizer,
                          self.derivative]
        # Create sets of radiobuttons and set all to default value 'Off'
        self.radiobuttons = []
        for i, D  in enumerate(PP_DICTS) :
            variable = self.selection[i]
            variable.set('Off')
            self.radiobuttons.append([])
            for key in D :
                rb = tk.Radiobutton(master, text=key, variable=variable,
                                   value=key, command=self.process_data,
                                   indicatoron=0)
                self.radiobuttons[i].append(rb)

    def _set_up_plots(self, master) :
        """ Take care of all the matplotlib stuff for the plot. """
        fig = Figure(figsize=FIGSIZE)
        fig.patch.set_alpha(0)
        ax_cut1 = fig.add_subplot(221)
        ax_cut2 = fig.add_subplot(224)
        ax_map = fig.add_subplot(223)#, sharex=ax_cut1, sharey=ax_cut2)
        ax_energy = fig.add_subplot(222)

        # Virtual figure and ax for creation of png's
        self.vfig = Figure(figsize=VFIGSIZE)
        vax = self.vfig.add_subplot(111)
        self.vcanvas = FigureCanvasTkAgg(self.vfig, master=master)
        
        # Remove padding between min and max of data and plot border
        ax_cut2.set_ymargin(0)

        # Move ticks to the other side
        ax_energy.xaxis.tick_top()
        ax_energy.yaxis.tick_right()

        ax_cut1.xaxis.tick_top()
        ax_cut2.yaxis.tick_right()

        # Get a handle on all axes through the dictionary self.axes
        self.axes = {'cut1': ax_cut1,
                     'cut2': ax_cut2,
                     'map': ax_map,
                     'energy': ax_energy,
                     'vax': vax}

        # Set bg color
        for ax in self.axes.values() :
            ax.set_facecolor(BGCOLOR)

        # Remove spacing between plots
        fig.subplots_adjust(wspace=PLOT_SPACING, hspace=PLOT_SPACING)

        self.canvas = FigureCanvasTkAgg(fig, master=master)
        self.canvas.show()

    def _set_up_colormap_sliders(self, master) :
        """ Add the colormap adjust sliders, set their starting position and add 
        its binding such that it only triggers upon release. Also, couple 
        them to the variables vmin/max_index.
        Then, also create a dropdown with all available cmaps and a checkbox 
        to invert the cmap.
        """
        self.vmin_index = tk.IntVar()
        self.vmax_index = tk.IntVar()
        cm_slider_kwargs = { 'showvalue' : 0,
                             'to' : CM_SLIDER_RESOLUTION, 
                             'length':SLIDER_LENGTH }
        self.cm_min_slider = tk.Scale(master, variable=self.vmin_index,
                                      label='Min', **cm_slider_kwargs)
        self.cm_min_slider.set(CM_SLIDER_RESOLUTION)

        self.cm_max_slider = tk.Scale(master, variable=self.vmax_index,
                                      label='Max', **cm_slider_kwargs)
        self.cm_max_slider.set(0)

        # StringVar to keep track of the cmap and whether it's inverted
        self.cmap = tk.StringVar()
        self.invert_cmap = tk.StringVar()
        # Default to the first cmap
        self.cmap.set(self.cmaps[0])
        self.invert_cmap.set('')

        # Register callbacks for colormap-range change
        for var in [self.vmin_index, self.vmax_index, self.cmap, 
                    self.invert_cmap] :
            var.trace('w', self.redraw_mesh)

        # Create the dropdown menu, populated with all strings in self.cmaps
        self.cmap_dropdown = tk.OptionMenu(master, self.cmap, *self.cmaps)

        # And a button to invert
        self.invert_cmap_checkbutton = tk.Checkbutton(master, text='Invert',
                                                      variable=self.invert_cmap,
                                                      onvalue='_r',
                                                      offvalue='')

    def _set_up_z_slider(self, master) :
        """ Create a Slider which allows to select the z value of the data.
        This value is stored in the DoubleVar self.z """
        self.z = tk.IntVar()
        self.z.set(0)
        self.zmax = tk.IntVar()
        self.zmax.set(1)
        self.z_slider = tk.Scale(master, variable=self.z, label='z', 
                                 to=self.zmax.get(), showvalue=1, 
                                 length=SLIDER_LENGTH) 
        self.z_slider.bind('<ButtonRelease-1>', self.process_data)

    def _set_up_integration_range_selector(self, master) :
        """ Create widgets that will allow setting the integration range when 
        creating a map. """
        self.integrate = tk.IntVar()
        self.integration_range_entry = tk.Entry(master, width=3,
                                           textvariable=self.integrate)

    def _set_up_status_label(self, master) :
        """ Create a label which can hold informative text about the current
        state of the GUI or success/failure of certain operations. This text 
        is held in the StringVar self.status.
        """
        self.status = tk.StringVar()
        # Initialize the variable with the default status
        self.update_status()
        self.status_label = tk.Label(textvariable=self.status, justify=tk.LEFT,
                                    anchor='w')

    def redraw_mesh(self, *args, **kwargs) :
        """ Efficiently redraw the pcolormesh without having to redraw the 
        axes, ticks, labels, etc. """
        # Get the new colormap parameters and apply them to the pcolormesh
        cmap = self.get_cmap()
        vmin, vmax = self.vminmax(self.pp_data)
        mesh = self.main_mesh
        mesh.set_clim(vmin=vmin, vmax=vmax)
        mesh.set_cmap(cmap)

        # Redraw the mesh
        ax = self.axes['map']
        ax.draw_artist(mesh)

        # Cursors need to be redrawn - the blitting happens there
        self.redraw_cursors()

        # Also redraw the cuts if they are pcolormeshes
        if self.map.get() != 'Off' :
            self.redraw_cuts()

    def redraw_cuts(self, *args, **kwargs) :
        """ Efficiently redraw the cuts (meshes or lines, depending on state 
        of `self.map`) without having to redraw the axes, ticks, labels, etc. 
        """
        axes = [self.axes['cut1'], self.axes['cut2']]
        data = [self.cut1, self.cut2]
        artists = [self.cut1_plot, self.cut2_plot] 
        cmap = self.get_cmap()
        for i,ax in enumerate(axes) :
            artist = artists[i]
            if self.map.get() != 'Off' :
                vmin, vmax = self.vminmax(data[i])
                artist.set_clim(vmin=vmin, vmax=vmax)
                artist.set_cmap(cmap)
            ax.draw_artist(artist)
            self.canvas.blit(ax.bbox)

    def redraw_cursors(self, *args, **kwargs) :
        """ Efficiently redraw the cursors in the bottom left plot without 
        having to redraw the axes, ticks, labels, etc. """
        ax = self.axes['map']
        #self.canvas.restore_region(self.bg_mesh)
        ax.draw_artist(self.xcursor)
        ax.draw_artist(self.ycursor)
        self.canvas.blit(ax.bbox)

    def update_z_slider(self, state) :
        """ Change the relief of the z slider to indicate that it is 
        inactive/active. Also update the z slider range"""
        if state == 'active' :
            config = dict(sliderrelief='raised', showvalue=1)
        else :
            config = dict(sliderrelief='flat', showvalue=0)
        self.zmax.set( len(self.data) - 1) 
        config.update(dict(to=self.zmax.get()))
        self.z_slider.config(**config)

    def get_filename(self) :
        """ Return the filename (without path) of the currently selected 
        file. """
        return self.filepath.get().split('/')[-1]

    def increment(self, plusminus) :
        # Get the path and the name of the current file
        filepath = self.filepath.get()
        split = filepath.split('/')
        # If just a filename is given, assume the current directory
        if filepath[0] is not '/' :
            path = './'
        else :
            #path = '/' + '/'.join(split[:-1]) + '/'
            path = '/'.join(split[:-1]) + '/'

        old_filename = split[-1]
        
        # Get a list of the files in the current directory
        dir_content = sorted( os.listdir(path) )
        dir_size = len(dir_content)

        # Get the index of the current file in the directory 
        index = dir_content.index(old_filename)

        # Raise/lower the index until a not-obiously skippable entry is found
        while True :
            index += plusminus
            # Cycle through the list
            index %= dir_size
            new_filename = dir_content[index]
            suffix = new_filename.split('.')[-1]
            if suffix not in SKIPPABLE :
                self.filepath.set(path+new_filename)
                break

    def update_status(self, status=DEFAULT_STATUS) :
        """ Update the status StringVar with the current time and the given
        status argument. 
        """
        now = datetime.now().strftime('%H:%M:%S')
        new_status = '[{}] {}'.format(now, status)
        self.status.set(new_status)

    def browse(self) :
        """ Open a filebrowser dialog and put the selected file into  
        self.path_field. 
        """
        # If the file entry field already contains a path to a file use it
        # as the default file for the browser
        old_filepath = self.filepath.get() 
        if old_filepath :
            default_file = old_filepath
            initialdir = None
        else :
            default_file = None
            initialdir = '/'

        # Open a browser dialog
        new_filepath = askopenfilename(initialfile=default_file,
                                       initialdir=initialdir)

        # Update the path only if a selection was made
        if new_filepath != "" :
            self.filepath.set(new_filepath)

    def load_data(self) :
        """ Load data from the file currently selected by self.filepath. And 
        reset and prepare several things such that the GUI is able to handle 
        the new data properly. 
        """
        # Show the user that something is happening
        self.update_status('Loading data...')

        # Try to load the data with the given dataloader
        try :
            ns = dl.load_data(self.filepath.get())
        except Exception as e :
            print(e)
            self.update_status('Failed to load data.')
            # Leave the function
            return 1

        # Extract the fields from the namespace
        self.data = ns.data
        self.xscale = ns.xscale
        self.yscale = ns.yscale
        try :
            self.zscale = ns.zscale
        except KeyError :
            # Set zscale to None
            self.zscale = None
            pass

        # Notify user of success
        self.update_status('Loaded data: {}.'.format(self.get_filename())) 

        # Update the max z value/toggle z slider (should better be handled in 
        # background by tkinter)
        if self.data.shape[0] == 1 :
            self.update_z_slider('disabled')
        else :
            self.update_z_slider('active')

        # Initiate new cursors
        self.cursor_xy = None

        # The postprocessing also creates copy of the raw data and replots
        self.process_data()

    def process_data(self, event=None) :
        """ Apply all the selected postprocessing routines in the following 
        order:
            0) Make map
            1) bg subtraction
            2) normalization
            3) derivative
        """
        # Retain a copy of the raw data
        self.pp_data = self.data.copy()
        z = self.z.get()

        # Make a map if necessary
        if self.map.get() != 'Off' :
            integrate = self.integrate.get()
            self.pp_data = pp.make_slice(self.pp_data, d=0, i=z, integrate=integrate)
            #self.pp_data = pp.make_map(self.pp_data, z, integrate=integrate)
            
            # Need to reshape
            shape = self.pp_data.shape
            self.pp_data = self.pp_data.reshape(1, shape[0], shape[1])


        # Apply all pp, unless they are set to 'Off' (None)
        for i, D in enumerate(PP_DICTS) :
            pp_operation = D[self.selection[i].get()]
            if pp_operation :
                self.pp_data = pp_operation(self.pp_data)
                #self.pp_data[z,:,:] = pp_operation(self.pp_data[z,:,:])

        # Replot
        self.plot_data()

    def plot_intensity(self) :
        """ Plot the binding energy distribution in the top right if we have 
        a map. """
        # Clear the current distribution
        ax = self.axes['energy']
        ax.clear()

        # Write the value of the energy in the upper right plot
        z = self.z.get()
        if self.zscale is not None :
            z_val = self.zscale[z]
        else :
            z_val = z
        ax.text(0.1, 0.05, z_val, color='red', transform=ax.transAxes)

        # Nothing else to do if we don't have a map
        if self.map.get() == 'Off' : 
            return

        # Get the energies and number of energies
        if self.zscale is not None :
            energies = self.zscale
        else :
            energies = np.arange(len(self.data))
        N_e = len(energies)
        
        # Get the intensities
        intensities = []
        for i in range(N_e) :
            this_slice = self.data[i,:,:]
            intensity = sum( sum(this_slice) )
            intensities.append(intensity)

        # Plot energy distribution
        ax.plot(energies, intensities, **intensity_kwargs)

        # Plot a cursor indicating the current value of z
        y0 = min(intensities)
        y1 = max(intensities)
        ylim = [y0, y1]
        ax.plot(2*[z_val], ylim, **intensity_cursor_kwargs)
        ax.set_ylim(ylim)

    def calculate_cuts(self) :
        """ """
        if self.map.get() != 'Off' :
            # Create a copy of the original map (3D) data
            data = self.data.copy()
            # Slice and dice it
            self.cut1 = pp.make_slice(data, d=1, i=self.yind, integrate=1)
            self.cut2 = pp.make_slice(data, d=2, i=self.xind, integrate=1)
        else :
            z = self.z.get()
            self.cut1 = self.pp_data[z, self.yind, :]
            self.cut2 = self.pp_data[z, :, self.xind]

    def plot_cuts(self) :
        """ Plot cuts of whatever is in the bottom left ('map') axis along 
        the current positions of the cursors. 
        """
        self.calculate_cuts()

        # Clear the current cuts
        for ax in ['cut1', 'cut2'] :
            self.axes[ax].clear()

        # Get the right xscale/yscale information
        xscale, yscale = self.get_xy_scales()

        if self.map.get() != 'Off' :
            kwargs = dict(cmap=self.get_cmap())

            # Ensure zscale is defined
            if self.zscale is None :
                zscale = np.arange(self.cut1.shape[0])
            else :
                zscale = self.zscale

            # Plot x cut in upper left
            vmin, vmax = self.vminmax(self.cut1)
            kwargs.update(dict(vmin=vmin, vmax=vmax))
            self.cut1_plot = self.axes['cut1'].pcolormesh(xscale, zscale, 
                                                      self.cut1, **kwargs)
            # Plot y cut in lower right (rotated by 90 degrees)
            vmin, vmax = self.vminmax(self.cut2)
            kwargs.update(dict(vmin=vmin, vmax=vmax))
            self.cut2_plot = self.axes['cut2'].pcolormesh(zscale, yscale, 
                                                      self.cut2.T, **kwargs)
        else :
            # Plot the x cut in the upper left
            self.cut1_plot = self.axes['cut1'].plot(xscale, self.cut1, 
                                                    **cut_kwargs)[0]
            # Plot the y cut in the lower right
            self.cut2_plot = self.axes['cut2'].plot(self.cut2, yscale, 
                                                    **cut_kwargs)[0]

            # Make sure the cut goes over the full range of the plot
            #self.axes['cut2'].set_ymargin(0) # For some reason this doesn't work
            ymin = min(yscale)
            ymax = max(yscale)
            self.axes['cut2'].set_ylim([ymin, ymax])

    def get_plot_args_and_kwargs(self) :
        """ Prepare args and kwargs for plotting, depending on the 
        circumstances. """
        # Add x and y scales to args if available
        args = []
        if self.xscale is not None and self.yscale is not None :
            args.append(self.xscale)
            args.append(self.yscale)

        # Use z=0 in case of a map (as pp_data is of length 1 along this 
        # dimension as a result of pp_make_cut())
        if self.map.get() != 'Off' :
            z = 0
        else :
            z = self.z.get()

        args.append(self.pp_data[z,:,:])

        vmin, vmax = self.vminmax(self.pp_data)
        kwargs = dict(cmap=self.get_cmap(), vmin=vmin, 
                      vmax=vmax)
        return args, kwargs

    def plot_data(self, event=None, *args, **kwargs) :
        """ Update the colormap range and (re)plot the data. """
        # Remove old plots
        for ax in self.axes.values() :
            ax.clear()

        args, kwargs = self.get_plot_args_and_kwargs()
        # Do the actual plotting with just defined args and kwargs
        ax = self.axes['map']
        self.main_mesh = ax.pcolormesh(*args, **kwargs)

        self.bg_mesh = self.canvas.copy_from_bbox(ax.bbox)

        # Update the cursors (such that they are above the pcolormesh) and cuts
        self.plot_cursors()
        self.plot_cuts()
        self.plot_intensity()
        self.canvas.draw()

    def get_cmap(self) :
        """ Build the name of the colormap by combining the value stored in 
        `self.cmap` (the basename of the colormap) and `self.invert_cmap` 
        (either empty string or '_r', which is the suffix for inverted cmaps 
        in matplotlib) """
        # Build the name of the cmap
        cmap_name = self.cmap.get() + self.invert_cmap.get()
        # Make sure this name exists in the list of cmaps. Otherwise reset to 
        # default cmap
        try :
            cmap = get_cmap(cmap_name)
        except ValueError :
            # Notify user
            message = \
            'Colormap {} not found. Using default instead.'.format(cmap_name)
            self.update_status(message)
            # Set default
            cmap = get_cmap(self.cmaps[0])

        return cmap

    def vminmax(self, data) :
        """ Helper function that returns appropriate values for vmin and vmax
        for a given set of data. """
        # Note: vmin_index goes from 100 to 0 and vice versa for vmax_index.
        # This is to turn the sliders upside down.
        # Crude method to avoid unreasonable colormap settings
        if self.vmin_index.get() < self.vmax_index.get() :
            self.vmin_index.set(CM_SLIDER_RESOLUTION)

        # Split the data value range into equal parts
        #drange = np.linspace(self.pp_data.min(), data.max(), 
        #                     CM_SLIDER_RESOLUTION + 1)
        drange = np.linspace(data.min(), data.max(), 
                             CM_SLIDER_RESOLUTION + 1)

        # Get the appropriate vmin and vmax values from the data
        vmin = drange[CM_SLIDER_RESOLUTION - self.vmin_index.get()]
        vmax = drange[CM_SLIDER_RESOLUTION - self.vmax_index.get()]

        return vmin, vmax

    def get_xy_minmax(self) :
        """ Return the min and max for the x and y axes, depending on whether 
        xscale and yscale are defined. 
        """
        xscale, yscale =  self.get_xy_scales()

        xmin = min(xscale)
        xmax = max(xscale)
        ymin = min(yscale)
        ymax = max(yscale)

        return xmin, xmax, ymin, ymax

    def get_xy_scales(self) :
        """ Depending on whether we have actual data scales (self.xscale and 
        self.yscale are defined) or not, return arrays which represent data 
        coordinates. 
        """
        if self.xscale is None or self.yscale is None :
            shape = self.data.shape
            yscale = np.arange(0, shape[1], 1)
            xscale = np.arange(0, shape[2], 1)
        else :
            xscale = self.xscale
            yscale = self.yscale

        return xscale, yscale

    def snap_to(self, x, y) :
        """ Return the closest data value to the given values of x and y. """
        xscale, yscale = self.get_xy_scales()

        # Find the index where element x/y would have to be inserted in the 
        # sorted array.
        self.xind = np.searchsorted(xscale, x)
        self.yind = np.searchsorted(yscale, y)

        # Find out whether the lower or upper 'neighbour' is closest
        x_lower = xscale[self.xind-1]
        y_lower = yscale[self.yind-1]
        # NOTE In principle, these IndexErrors shouldn't occur. Try-except 
        # only helps when debugging.
        try :
            x_upper = xscale[self.xind]
        except IndexError :
            x_upper = max(xscale)
        try :
            y_upper = yscale[self.yind]
        except IndexError :
            y_upper = max(yscale)

        dx_upper = x_upper - x
        dx_lower = x - x_lower
        dy_upper = y_upper - y
        dy_lower = y - y_lower

        # Assign the exact data value and update self.xind/yind if necessary
        if dx_upper < dx_lower :
            x_snap = x_upper
        else :
            x_snap = x_lower
            self.xind -= 1
            
        if dy_upper < dy_lower :
            y_snap = y_upper
        else :
            y_snap = y_lower
            self.yind -= 1

        return x_snap, y_snap

    def plot_cursors(self) :
        """ Plot the cursors in the bottom left axis. """
        # Delete current cursors (NOTE: this is dangerous if there are any 
        # other lines in the plot)
        ax = self.axes['map']
        ax.lines = []

        # Retrieve information about current data range
        xmin, xmax, ymin, ymax = self.get_xy_minmax()
       
        xlimits = [xmin, xmax]
        ylimits = [ymin, ymax]

        # Initiate cursors in the center of graph if necessary
        if self.cursor_xy is None :
            x = 0.5 * (xmax + xmin)
            y = 0.5 * (ymax + ymin)

            # Keep a handle on cursor positions
            self.cursor_xy = (x, y)
        else : 
            x, y = self.cursor_xy

        # Make the cursor snap to actual data points
        x, y = self.snap_to(x, y)

        # Plot cursors and keep handles on them (need the [0] because plot() 
        # returns a list of Line objects)
        self.xcursor = ax.plot([x, x], ylimits, zorder=3, **cursor_kwargs)[0]
        self.ycursor = ax.plot(xlimits, [y, y], zorder=3, **cursor_kwargs)[0]

    def _set_up_event_handling(self) :
        """ Define what happens when user clicks in the plot (move cursors to 
        clicked position) or presses an arrow key (move cursors in specified 
        direction). 
        """
        def on_click(event):
            event_ax = event.inaxes
            if event_ax == self.axes['map'] :
                self.cursor_xy = (event.xdata, event.ydata)
                self.plot_cursors()
                # Also update the cuts
                self.plot_cuts()
                self.canvas.draw()
            elif event_ax == self.axes['energy'] and \
                 self.map.get() != 'Off' :
                if self.zscale is not None :
                    z = np.where(self.zscale > event.xdata)[0][0]
                else :
                    z = int(event.xdata)
                self.z.set(z)
                # Since z changed we need to apply the whole data processing
                # and replot
                self.process_data()
                
        def on_press(event):
            # Get the name of the pressed key and info on the current cursors
            key = event.key
            x, y = self.cursor_xy
            xmin, xmax, ymin, ymax = self.get_xy_minmax()

            # Stop if no arrow key was pressed
            if key not in ['up', 'down', 'left', 'right'] : return

            # Move the cursor by one unit in data points
            xscale, yscale = self.get_xy_scales()
            dx = xscale[1] - xscale[0]
            dy = yscale[1] - yscale[0]

            # In-/decrement cursor positions depending on what button was 
            # pressed and only if we don't leave the axis
            if key == 'up' and y+dy <= ymax :
                y += dy
            elif key == 'down' and y-dy >= ymin :
                y -= dy
            elif key == 'right' and x+dx <= xmax :
                x += dx
            elif key == 'left' and x-dx >= xmin:
                x -= dx

            # Update the cursor position and redraw it
            self.cursor_xy = (x, y)
            #self.plot_cursors()
            self.redraw_cursors()
            # Now the cuts have to be redrawn as well
            self.calculate_cuts()
            #self.plot_cuts()
            self.redraw_cuts()

        cid = self.canvas.mpl_connect('button_press_event', on_click)
        pid = self.canvas.mpl_connect('key_press_event', on_press)

        # Inititate the cursors
        self.plot_cursors()

    def save_plot(self) :
        """ Save a png image of the currently plotted data (only what is in 
        bottom left) """
        # Plot the same thing into a virtual figure such that a png can be 
        # created
        args, kwargs = self.get_plot_args_and_kwargs()
        self.vmain_mesh = self.axes['vax'].pcolormesh(*args, **kwargs)

        # Open a filebrowser where user can select a place to store the result
        filename = asksaveasfilename(filetypes=[('PNG', '*.png')])
        if filename :
            self.vfig.savefig(filename, transparent=True, dpi=self.dpi)
            self.update_status('Saved file {}.'.format(filename))
        else :
            self.update_status('Saving file aborted.')
class matplotlibSwitchGraphs:
    def __init__(self, master):
        self.master = master
        self.frame = Frame(self.master)
        self.fig, self.ax = config_plot()
        self.graphIndex = 0
        self.canvas = FigureCanvasTkAgg(self.fig, self.master)  
        self.config_window()
        self.draw_graph('janvier')
        self.frame.pack(expand=YES, fill=BOTH)

    def config_window(self):
        self.canvas.mpl_connect("key_press_event", self.on_key_press)
        toolbar = NavigationToolbar2Tk(self.canvas, self.master)
        toolbar.update()
        self.canvas.get_tk_widget().pack(side=TOP, fill=BOTH, expand=1)
        self.button = Button(self.master, text="Quit", command=self._quit)
        self.button.pack(side=BOTTOM)
        self.button_back = Button(self.master, text="Graphique précédent", command=self.back_graph)
        self.button_back.pack(side=BOTTOM)
        self.button_next = Button(self.master, text="Graphique suivant", command=self.next_graph)
        self.button_next.pack(side=BOTTOM)
    def draw_graph(self, month):
        self.ax.clear()
        self.ax.plot(df[month])
        self.ax.set(title=month)
        self.canvas.draw()

    def on_key_press(event):
        key_press_handler(event, self.canvas, toolbar)

    def _quit(self):
        self.master.quit() 

    def next_graph(self):
        if self.graphIndex == 0:
            self.draw_graph('février')
            self.graphIndex = 1
        elif self.graphIndex == 1:
            self.draw_graph('mars')
            self.graphIndex = 2
        elif self.graphIndex == 2:
            self.draw_graph('avril')
            self.graphIndex = 3
        elif self.graphIndex == 3:
            self.draw_graph('mai')
            self.graphIndex = 4
        elif self.graphIndex == 4:
            self.draw_graph('juin')
            self.graphIndex = 5
        elif self.graphIndex == 5:
            self.draw_graph('juillet')
            self.graphIndex = 6
        elif self.graphIndex == 6:
            self.draw_graph('août')
            self.graphIndex = 7
        elif self.graphIndex == 7:
            self.draw_graph('septembre')
            self.graphIndex = 8
        elif self.graphIndex == 8:
            self.draw_graph('octobre')
            self.graphIndex = 9
        elif self.graphIndex == 9:
            self.draw_graph('novembre')
            self.graphIndex = 10
        elif self.graphIndex == 10:
            self.draw_graph('décembre')
            self.graphIndex = 11
        elif self.graphIndex == 11:
            self.draw_graph('janvier')
            self.graphIndex = 0

    def back_graph(self):
        if self.graphIndex == 0:
            self.draw_graph('décembre')
            self.graphIndex = 11
        elif self.graphIndex == 11:
            self.draw_graph('novembre')
            self.graphIndex = 10
        elif self.graphIndex == 10:
            self.draw_graph('octobre')
            self.graphIndex = 9
        elif self.graphIndex == 9:
            self.draw_graph('septembre')
            self.graphIndex = 8
        elif self.graphIndex == 8:
            self.draw_graph('août')
            self.graphIndex = 7
        elif self.graphIndex == 7:
            self.draw_graph('juillet')
            self.graphIndex = 6
        elif self.graphIndex == 6:
            self.draw_graph('juin')
            self.graphIndex = 5
        elif self.graphIndex == 5:
            self.draw_graph('mai')
            self.graphIndex = 4
        elif self.graphIndex == 4:
            self.draw_graph('avril')
            self.graphIndex = 3
        elif self.graphIndex == 3:
            self.draw_graph('mars')
            self.graphIndex = 2
        elif self.graphIndex == 2:
            self.draw_graph('février')
            self.graphIndex = 1
        elif self.graphIndex == 1:
            self.draw_graph('janvier')
            self.graphIndex = 0
Example #28
0
class ApSynSim_UV_Plotter1(object):
    def quit(self):
        self.FFTwin.destroy()

    def __init__(self, parent):

        self.parent = parent

        self.FFTwin = Tk.Toplevel(self.parent.tks)
        self.FFTwin.title("UV space")

        menubar = Tk.Menu(self.FFTwin)
        menubar.add_command(label="Quit", command=self.quit)
        self.FFTwin.config(menu=menubar)

        self.figUV1 = pl.figure(figsize=(8.5, 7))

        self.UVPSF = self.figUV1.add_subplot(231, aspect='equal')
        pl.setp(self.UVPSF.get_xticklabels(), visible=False)
        self.UVCLEANMOD = self.figUV1.add_subplot(232,
                                                  sharex=self.UVPSF,
                                                  sharey=self.UVPSF,
                                                  aspect='equal')
        pl.setp(self.UVCLEANMOD.get_xticklabels(), visible=False)
        pl.setp(self.UVCLEANMOD.get_yticklabels(), visible=False)

        self.UVResid = self.figUV1.add_subplot(234,
                                               sharex=self.UVPSF,
                                               sharey=self.UVPSF,
                                               aspect='equal')
        self.UVCLEAN = self.figUV1.add_subplot(235,
                                               sharex=self.UVPSF,
                                               sharey=self.UVPSF,
                                               aspect='equal')
        pl.setp(self.UVCLEAN.get_yticklabels(), visible=False)

        self.UVSOURCE = self.figUV1.add_subplot(233,
                                                sharex=self.UVPSF,
                                                sharey=self.UVPSF,
                                                aspect='equal')
        pl.setp(self.UVSOURCE.get_xticklabels(), visible=False)
        pl.setp(self.UVSOURCE.get_yticklabels(), visible=False)

        self.UVSOURCECONV = self.figUV1.add_subplot(236,
                                                    sharex=self.UVPSF,
                                                    sharey=self.UVPSF,
                                                    aspect='equal')
        pl.setp(self.UVSOURCECONV.get_yticklabels(), visible=False)

        self.figUV1.subplots_adjust(left=0.1,
                                    right=0.98,
                                    top=0.90,
                                    bottom=0.15,
                                    wspace=0.02,
                                    hspace=0.15)

        self.UVfmt = '%.2e Jy'
        self.PSFfmt = '%.2e'

        self.PSFText = self.UVPSF.text(0.05,
                                       0.87,
                                       self.PSFfmt % (0.0),
                                       transform=self.UVPSF.transAxes,
                                       bbox=dict(facecolor='white', alpha=0.7))

        self.ResidText = self.UVResid.text(0.05,
                                           0.87,
                                           self.UVfmt % (0.0),
                                           transform=self.UVResid.transAxes,
                                           bbox=dict(facecolor='white',
                                                     alpha=0.7))

        self.CLEANText = self.UVCLEAN.text(0.05,
                                           0.87,
                                           self.UVfmt % (0.0),
                                           transform=self.UVCLEAN.transAxes,
                                           bbox=dict(facecolor='white',
                                                     alpha=0.7))

        self.CLEANMODText = self.UVCLEANMOD.text(
            0.05,
            0.87,
            self.UVfmt % (0.0),
            transform=self.UVCLEANMOD.transAxes,
            bbox=dict(facecolor='white', alpha=0.7))

        self.UVSOURCEText = self.UVSOURCE.text(
            0.05,
            0.87,
            self.UVfmt % (0.0),
            transform=self.UVSOURCE.transAxes,
            bbox=dict(facecolor='white', alpha=0.7))

        self.UVSOURCECONVText = self.UVSOURCECONV.text(
            0.05,
            0.87,
            self.UVfmt % (0.0),
            transform=self.UVSOURCECONV.transAxes,
            bbox=dict(facecolor='white', alpha=0.7))

        self.frames = {}
        self.frames['FigUV'] = Tk.Frame(self.FFTwin)
        self.frames['BFr'] = Tk.Frame(self.FFTwin)

        self.canvasUV1 = FigureCanvasTkAgg(self.figUV1,
                                           master=self.frames['FigUV'])

        self.canvasUV1.show()
        self.frames['FigUV'].pack(side=Tk.TOP)
        self.frames['BFr'].pack(side=Tk.TOP)

        self.buttons = {}
        self.buttons['reload'] = Tk.Button(self.frames['BFr'],
                                           text="Reload",
                                           command=self._FFTRead)
        self.buttons['reload'].pack()

        self.canvasUV1.mpl_connect('pick_event', self._onUVPick)
        self.canvasUV1.get_tk_widget().pack(
            side=Tk.LEFT)  # , fill=Tk.BOTH, expand=1)
        toolbar_frame = Tk.Frame(self.FFTwin)
        __toolbar = NavigationToolbar2TkAgg(self.canvasUV1, toolbar_frame)
        toolbar_frame.pack(side=Tk.LEFT)

        self._FFTRead()

    def _FFTRead(self):

        Toplot = np.abs(
            np.fft.fftshift(np.fft.fft2(np.fft.fftshift(self.parent.beam))))

        vmax = np.max(Toplot)
        __vmin = np.min(Toplot)
        self.UVPSFPlot = self.UVPSF.imshow(Toplot,
                                           vmin=0.0,
                                           vmax=vmax,
                                           cmap=self.parent.currcmap,
                                           picker=True,
                                           interpolation='nearest')
        pl.setp(self.UVPSFPlot,
                extent=(-self.parent.UVmax + self.parent.UVSh,
                        self.parent.UVmax + self.parent.UVSh,
                        -self.parent.UVmax - self.parent.UVSh,
                        self.parent.UVmax - self.parent.UVSh))
        self.UVPSF.set_ylabel(self.parent.vlab)

        self.UVPSF.set_title('UV - PSF')

        try:
            Toplot = np.abs(
                np.fft.fftshift(
                    np.fft.fft2(np.fft.fftshift(
                        self.parent.myCLEAN.residuals))))
        except:
            Toplot = np.zeros(np.shape(self.parent.beam))

        vmax = np.max(np.abs(np.fft.fft2(self.parent.dirtymap)))
        self.UVResidPlot = self.UVResid.imshow(Toplot,
                                               vmin=0.0,
                                               vmax=vmax,
                                               cmap=self.parent.currcmap,
                                               picker=True,
                                               interpolation='nearest')
        pl.setp(self.UVResidPlot,
                extent=(-self.parent.UVmax + self.parent.UVSh,
                        self.parent.UVmax + self.parent.UVSh,
                        -self.parent.UVmax - self.parent.UVSh,
                        self.parent.UVmax - self.parent.UVSh))
        self.UVResid.set_xlabel(self.parent.ulab)
        self.UVResid.set_ylabel(self.parent.vlab)

        self.UVResid.set_title('UV - RESIDUALS (REST.)')

        try:
            Toplot = np.abs(
                np.fft.fftshift(
                    np.fft.fft2(np.fft.fftshift(
                        self.parent.myCLEAN.cleanmod))))
        except:
            Toplot = np.zeros(np.shape(self.parent.beam))

        vmax = np.max(Toplot)
        self.UVCLEANPlot = self.UVCLEAN.imshow(Toplot,
                                               vmin=0.0,
                                               vmax=vmax,
                                               cmap=self.parent.currcmap,
                                               picker=True,
                                               interpolation='nearest')
        pl.setp(self.UVCLEANPlot,
                extent=(-self.parent.UVmax + self.parent.UVSh,
                        self.parent.UVmax + self.parent.UVSh,
                        -self.parent.UVmax - self.parent.UVSh,
                        self.parent.UVmax - self.parent.UVSh))
        self.UVCLEAN.set_xlabel(self.parent.ulab)

        self.UVCLEAN.set_title('UV - CLEAN (REST.)')

        try:
            Toplot = np.abs(
                np.fft.fftshift(
                    np.fft.fft2(np.fft.fftshift(
                        self.parent.myCLEAN.cleanmodd))))
        except:
            Toplot = np.zeros(np.shape(self.parent.beam))

        vmax = np.max(Toplot)
        self.UVCLEANMODPlot = self.UVCLEANMOD.imshow(Toplot,
                                                     vmin=0.0,
                                                     vmax=vmax,
                                                     cmap=self.parent.currcmap,
                                                     picker=True,
                                                     interpolation='nearest')
        pl.setp(self.UVCLEANMODPlot,
                extent=(-self.parent.UVmax + self.parent.UVSh,
                        self.parent.UVmax + self.parent.UVSh,
                        -self.parent.UVmax - self.parent.UVSh,
                        self.parent.UVmax - self.parent.UVSh))

        self.UVCLEANMOD.set_title('UV - CLEAN (MODEL)')

        try:
            Toplot = np.fft.fftshift(
                np.abs(self.parent.modelfft *
                       np.fft.fft2(self.parent.myCLEAN.cleanBeam)))
        except:
            Toplot = np.zeros(np.shape(self.parent.beam))

        vmax = np.max(Toplot)
        self.UVSOURCECONVPlot = self.UVSOURCECONV.imshow(
            Toplot,
            vmin=0.0,
            vmax=vmax,
            cmap=self.parent.currcmap,
            picker=True,
            interpolation='nearest')
        pl.setp(self.UVSOURCECONVPlot,
                extent=(-self.parent.UVmax + self.parent.UVSh,
                        self.parent.UVmax + self.parent.UVSh,
                        -self.parent.UVmax - self.parent.UVSh,
                        self.parent.UVmax - self.parent.UVSh))

        self.UVSOURCECONV.set_title('UV - SOURCE (REST.)')

        Toplot = np.fft.fftshift(np.abs(self.parent.modelfft))

        vmax = np.max(Toplot)
        self.UVSOURCEPlot = self.UVSOURCE.imshow(Toplot,
                                                 vmin=0.0,
                                                 vmax=vmax,
                                                 cmap=self.parent.currcmap,
                                                 picker=True,
                                                 interpolation='nearest')
        pl.setp(self.UVSOURCEPlot,
                extent=(-self.parent.UVmax + self.parent.UVSh,
                        self.parent.UVmax + self.parent.UVSh,
                        -self.parent.UVmax - self.parent.UVSh,
                        self.parent.UVmax - self.parent.UVSh))

        self.UVSOURCE.set_title('UV - SOURCE')

        self.canvasUV1.draw()

    def _onUVPick(self, event):

        Up = event.mouseevent.xdata - self.parent.UVSh
        Vp = event.mouseevent.ydata + self.parent.UVSh

        yi = int(
            np.floor((self.parent.UVmax + Up) / (self.parent.UVmax) *
                     self.parent.Npix / 2.))
        xi = int(
            np.floor((self.parent.UVmax - Vp) / (self.parent.UVmax) *
                     self.parent.Npix / 2.))

        if xi > 0 and yi > 0 and xi < self.parent.Npix and yi < self.parent.Npix:
            self.PSFText.set_text(self.PSFfmt %
                                  self.UVPSFPlot.get_array()[xi, yi])
            self.ResidText.set_text(self.UVfmt %
                                    self.UVResidPlot.get_array()[xi, yi])
            self.CLEANText.set_text(self.UVfmt %
                                    self.UVCLEANPlot.get_array()[xi, yi])
            self.CLEANMODText.set_text(self.UVfmt %
                                       self.UVCLEANMODPlot.get_array()[xi, yi])
            self.UVSOURCEText.set_text(self.UVfmt %
                                       self.UVSOURCEPlot.get_array()[xi, yi])
            self.UVSOURCECONVText.set_text(
                self.UVfmt % self.UVSOURCECONVPlot.get_array()[xi, yi])
        else:
            self.PSFText.set_text(self.PSFfmt % 0.0)
            self.ResidText.set_text(self.UVfmt % 0.0)
            self.CLEANText.set_text(self.UVfmt % 0.0)
            self.CLEANMODText.set_text(self.UVfmt % 0.0)
            self.UVSOURCEText.set_text(self.UVfmt % 0.0)
            self.UVSOURCECONVText.set_text(self.UVfmt % 0.0)

        self.canvasUV1.draw()
Example #29
0
class App():
    def __init__(self):
        self.root = Tk()
        self.root.wm_title("Animated Graph embedded in TK")
        self.root.protocol("WM_DELETE_WINDOW", self.quit_app)
        self.root.resizable(width=True, height=True)
        self.root.geometry("800x400")
        self.colors = ['#B2E4CF', '#E4E4B2']

        # the networkx part
        self.G = List()

        # figure
        self.f = plt.figure(figsize=(5, 4))
        # a tk.DrawingArea
        self.canvas = FigureCanvasTkAgg(self.f, master=self.root)
        self.canvas.show()
        self.canvas.mpl_connect('button_press_event', self.on_press)
        self.canvas.get_tk_widget().pack(side=TOP, fill=BOTH, expand=1)
        # axes
        self.a = self.f.add_subplot(111)
        self.pos = (1, 1)
        self.draw()

    def update(self):
        self.root.mainloop()

    def quit_app(self):
        if messagebox.askokcancel("Quit", "Do you want to quit?"):
            self.root.quit()

    def draw(self):
        self.a.cla()
        nx.draw_networkx(self.G.getGraph(),
                         self.G.getPos(),
                         ax=self.a,
                         with_labels=True,
                         node_color=self.G.getColors(),
                         node_size=1000)
        self.a.plot(self.pos[0], self.pos[1], 'r.')
        plt.axis('off')
        self.a.set_xlim(0, 1)
        self.a.set_ylim(0, 1)
        plt.tight_layout()
        self.canvas.draw()

    def closeEntryWindow(self):
        self.entryWindow.destroy()

    def openEntryWindow(self, x, y):
        self.pos = (x, y)
        self.draw()
        self.entryWindow = Tk()
        self.entryWindow.wm_title("Type in node details")
        self.entryWindow.protocol("WM_DELETE_WINDOW", self.closeEntryWindow)

        Label(self.entryWindow, text="Genotype").grid(row=0,
                                                      column=0,
                                                      sticky=W,
                                                      pady=1)
        self.genentry = Entry(self.entryWindow)
        self.genentry.grid(row=0, column=1, sticky=W, pady=1)
        self.genentry.bind("<Return>", self.Enter)
        Label(self.entryWindow, text="Date").grid(row=1,
                                                  column=0,
                                                  sticky=W,
                                                  pady=1)
        self.datentry = Entry(self.entryWindow)
        self.datentry.grid(row=1, column=1, sticky=W, pady=1)
        self.datentry.bind("<Return>", self.Enter)

    def Enter(self, event):
        name = self.genentry.get()
        date = self.datentry.get()
        print(name, date)
        self.G.addNode(name, self.pos, self.colors[0], date)
        self.draw()
        self.entryWindow.destroy()

    def on_press(self, event):
        if event.xdata is not None and event.ydata is not None:
            #print('you pressed', event.button, event.xdata, event.ydata)
            if not self.G.isNear((event.xdata, event.ydata),
                                 self.getScale(self.f.gca().get_xlim(),
                                               self.f.gca().get_ylim())):
                self.openEntryWindow(event.xdata, event.ydata)

    def getScale(self, x, y):
        return (x[1] - x[0], y[1] - y[0])
Example #30
0
class VBDCMM_gui_simul:
  def __init__( self, parent ):
    self.myParent = parent

    # --- Model parameters ------------------------------
    self.K_true = Tk.IntVar(master=parent)
    self.K_true.trace('w', self.on_K_change)
    self.K_true_max = 4
    self.L_true = Tk.IntVar(master=parent)
    self.L_true.trace('w', self.on_L_change )
    self.L_true_max = 4

    self.T_xhh = Tk.IntVar(master=parent)
    self.T_xhh.trace('w', self.on_T_xhh_change )
    self.T_o = Tk.IntVar(master=parent)
    self.T_xhh_default = 4400
    self.T_o_default = self.T_xhh_default+1

    self.time_xhh = arange(0, self.T_xhh_default, 1)
    self.xhh_arr = zeros( self.T_xhh_default )  # internal states index starts from 0. However, for plotting, it starts from 1
    self.time_o = arange(0, self.T_o_default, 1) 
    self.xh_arr = zeros( self.T_o_default )  # internal states index starts from 0. However, for plotting, it starts from 1
    self.o_arr = 0.5*ones(self.T_o_default ) + 0.1*randn( self.T_o_default )

    # Grids coordinates -----------------------------
    grid_label_K_true = (0, 0)  # row, column, rowspan, columnspan
    grid_entry_K_true = (0, 1)
    grid_label_T_xhh = (0, 2)
    grid_entry_T_xhh = (0, 3)
    grid_label_A = (0, 4)
    grid_entry_A = (0, 5)
    grid_button_generate_params = (1, 5+self.K_true_max, 2, 2)
    grid_button_generate_trace_xhh = (0+self.K_true_max, 4, 1, 2)
    grid_canvas_xhh = (0+self.K_true_max, 0, 1, self.L_true_max*4 + 6)

    grid_label_L_true = (0+self.K_true_max+1, 0)  # row, column, rowspan, columnspan
    grid_entry_L_true = (0+self.K_true_max+1, 1)
    grid_label_mu_true = (0+self.K_true_max+1, 2)
    grid_entry_mu1_true = (0+self.K_true_max+1, 3)
    grid_entry_mu2_true = (0+self.K_true_max+2, 3)
    grid_entry_mu3_true = (0+self.K_true_max+3, 3)
    grid_entry_mu4_true = (0+self.K_true_max+4, 3)
    grid_label_sig_true = (0+self.K_true_max+1, 4)
    grid_entry_sig1_true = (0+self.K_true_max+1, 5)
    grid_entry_sig2_true = (0+self.K_true_max+2, 5)
    grid_entry_sig3_true = (0+self.K_true_max+3, 5)
    grid_entry_sig4_true = (0+self.K_true_max+4, 5)

    grid_label_B1 = (0+self.K_true_max+1, 6)
    grid_entry_B1 = (0+self.K_true_max+1, 7)
    grid_label_B2 = (0+self.K_true_max+1, 7+self.L_true_max)
    grid_entry_B2 = (0+self.K_true_max+1, 7+self.L_true_max+1)
    grid_label_B3 = (0+self.K_true_max+1, 7+2*self.L_true_max+1)
    grid_entry_B3 = (0+self.K_true_max+1, 7+2*self.L_true_max+2)
    grid_label_B4 = (0+self.K_true_max+1, 7+3*self.L_true_max+2)
    grid_entry_B4 = (0+self.K_true_max+1, 7+3*self.L_true_max+3)
 
    grid_button_generate_trace_o = (0+self.K_true_max+1+self.L_true_max, 4, 1, 2)
    grid_canvas_o = (0+self.K_true_max+1+self.L_true_max, 0, 1, self.L_true_max*4+6)

    grid_label_save_filename = (0+1*self.K_true_max+1+self.L_true_max, 17, 1, 2)
    grid_entry_save_filename = (0+1*self.K_true_max+1+self.L_true_max, 19, 1, 2)
    grid_button_save_traces = (0+1*self.K_true_max+1+self.L_true_max, 22, 1, 2)
    grid_button_analysis = (0+1*self.K_true_max+1+self.L_true_max, 24, 1, 2)

    # Variables ---------------------------
    _s = ''
    for i in range(1,self.K_true_max+1):
      for j in range(1,self.K_true_max+1):
        _s += '\n'+'self.A' + str(i) + str(j) + ' = Tk.DoubleVar(master=parent)'
        _s += '\n'+'self.A' + str(i) + str(j) + '.trace("w", self.on_A_change)'
    exec(_s)

    _s = ''
    for k in range(1, self.K_true_max+1):
      for i in range(1,self.L_true_max+1):
        for j in range(1,self.L_true_max+1):
          _s += '\n'+'self.B' +str(k)  + str(i) + str(j) + ' = Tk.DoubleVar(master=parent)'
          _s += '\n'+'self.B' +str(k)  + str(i) + str(j) + '.trace("w", self.on_B_change)'
    exec(_s)
 
    _s = ''
    for i in range(1,self.L_true_max+1):
      _s += '\n'+'self.mu'+str(i)+'_true = Tk.DoubleVar(master=parent)'
      _s += '\n'+'self.mu'+str(i)+'_true.trace("w", self.on_mu_change)'
      _s += '\n'+'self.sig'+str(i)+'_true = Tk.DoubleVar(master=parent)'
      _s += '\n'+'self.sig'+str(i)+'_true.trace("w", self.on_sig_change)'
    exec(_s)
       
      
    # --- Set initial values -----------------------------
    self.K_default = 2
    self.K_true.set(self.K_default)
    self.T_xhh.set(self.T_xhh_default)
    self.T_o.set(self.T_o_default)
    self.L_default = 2
    self.L_true.set(self.L_default)

    _s = ''
    for i in range(1,self.K_default+1):
      for j in range(1,self.K_default+1):
        if i != j:
          _s += '\n'+'self.A' + str(i) + str(j) + '.set(' + str( 0.001/(self.K_default-1)) + ')'
        if i == j:
          _s += '\n'+'self.A' + str(i) + str(j) + '.set(' + str( 1 - 0.001) + ')'
    exec(_s)
 
    _s = ''
    for k in range(1, self.K_default+1):
      for i in range(1,self.L_default+1):
        for j in range(1,self.L_default+1):
          if i != j:
            _s += '\n'+'self.B' + str(k) + str(i) + str(j) + '.set(' + str( (1/4**(k-1) * 0.1)/(self.L_default-1)) + ')'
          if i == j:
            _s += '\n'+'self.B' + str(k) + str(i) + str(j) + '.set(' + str( 1 - 1/4**(k-1) * 0.1) + ')'
    exec(_s)

    _s = ''
    for i in range(1,self.L_default+1):
      _s += '\n'+'self.mu'+str(i)+'_true.set(' + str( 0.1 + 0.8/(self.L_default-1)* (i-1) ) + ')'
    exec(_s)
 
    _s = ''
    for i in range(1,self.L_default+1):
      _s += '\n'+'self.sig'+str(i)+'_true.set('+ str( 0.15/self.L_default ) + ')'
    exec(_s)
 
    # --- Set trace function --- 
    #self.K_true.trace('w', on_change_K_true)


    # --- Labels ---
    self.label_K_true = Tk.Label( master=parent, width=2, text='K:' )
    self.label_A = Tk.Label( master=parent, width=2, text='A:' )
    self.label_T_xhh = Tk.Label( master=parent, width=2, text='T:' )
    self.label_L_true = Tk.Label( master=parent, width=2, text='N:' )
    self.label_mu_true = Tk.Label( master=parent, width=2, text='mu:')
    self.label_sig_true = Tk.Label( master=parent, width=2, text='sig:')
    self.label_B1 = Tk.Label( master=parent, width=2, text='B1:')
    self.label_B2 = Tk.Label( master=parent, width=2, text='B2:')
    self.label_B3 = Tk.Label( master=parent, width=2, text='B3:')
    self.label_B4 = Tk.Label( master=parent, width=2, text='B4:')

    # --- Labels grid ---
    self.label_K_true.grid( row=grid_label_K_true[0], column=grid_label_K_true[1] )
    self.label_A.grid( row=grid_label_A[0], column=grid_label_A[1] )
    self.label_T_xhh.grid( row=grid_label_T_xhh[0], column=grid_label_T_xhh[1] )
    self.label_L_true.grid( row=grid_label_L_true[0], column=grid_label_L_true[1] )
    self.label_mu_true.grid( row=grid_label_mu_true[0], column=grid_label_mu_true[1] )
    self.label_sig_true.grid( row=grid_label_sig_true[0], column=grid_label_sig_true[1] )
    self.label_B1.grid( row=grid_label_B1[0], column=grid_label_B1[1] )
    self.label_B2.grid( row=grid_label_B2[0], column=grid_label_B2[1] )
    self.label_B3.grid( row=grid_label_B3[0], column=grid_label_B3[1] )
    self.label_B4.grid( row=grid_label_B4[0], column=grid_label_B4[1] )

    self.save_filename = Tk.StringVar(master=parent, value='batch1')
    self.label_save_filename = Tk.Label( master=parent, width=9, text='Filename:')
    self.label_save_filename.grid( row=grid_label_save_filename[0], column=grid_label_save_filename[1], 
        rowspan=grid_entry_save_filename[2],columnspan=grid_entry_save_filename[3])

    self.entry_save_filename = Tk.Entry(master=parent, width=9, textvariable=self.save_filename )
    self.entry_save_filename.grid( row=grid_entry_save_filename[0], column=grid_entry_save_filename[1],
        rowspan=grid_entry_save_filename[2],columnspan=grid_entry_save_filename[3])


    # --- Button ---
    self.button_generate_params = Tk.Button(text='Gen. Params', width=8, command=self.on_click_button_generate_params, height=4)
    self.button_generate_params.grid( row=grid_button_generate_params[0], column=grid_button_generate_params[1],
                                        rowspan=grid_button_generate_params[2], columnspan=grid_button_generate_params[3],
                                        sticky='EW')
    self.button_save_traces = Tk.Button(text='Save. traces', width=10, command=self.on_click_button_save_traces, height=4)
    self.button_save_traces.grid( row=grid_button_save_traces[0], column=grid_button_save_traces[1],
                                        rowspan=grid_button_save_traces[2], columnspan=grid_button_save_traces[3],
                                        sticky='EW')
    self.button_analysis = Tk.Button(text='Analyze traces', width=8, command=self.on_click_button_analysis, height=4)
    self.button_analysis.grid( row=grid_button_analysis[0], column=grid_button_analysis[1],
                                        rowspan=grid_button_analysis[2], columnspan=grid_button_analysis[3],
                                        sticky='EW')



    self.button_generate_trace_xhh = Tk.Button(text='Gen. X', width=8, command=self.on_click_button_generate_trace_xhh, relief=Tk.SUNKEN, height=4)
    self.button_generate_trace_xhh.grid( row=grid_button_generate_trace_xhh[0], column=grid_button_generate_trace_xhh[1],
                                        rowspan=grid_button_generate_trace_xhh[2], columnspan=grid_button_generate_trace_xhh[3],
                                        sticky='EW')

    self.button_generate_trace_o = Tk.Button(text='Gen. O', width=8, command=self.on_click_button_generate_trace_o, relief=Tk.SUNKEN, height=4)
    self.button_generate_trace_o.grid( row=grid_button_generate_trace_o[0], column=grid_button_generate_trace_o[1],
                                        rowspan=grid_button_generate_trace_o[2], columnspan=grid_button_generate_trace_o[3],
                                        sticky='EW')


    # --- Entries --- 
    #self.entry_K_true = Tk.Entry( relief=Tk.SOLID, master=parent, textvariable=self.K_true, width=3) # SOLID: style. Clearer boundary
    self.entry_K_true = Tk.Spinbox( relief=Tk.RIDGE, master=parent, textvariable=self.K_true, width=3, value=(1,2,3,4) ) # SOLID: style. Clearer boundary
    self.K_true.set(self.K_default)
    self.entry_T_xhh = Tk.Entry( relief=Tk.SOLID, master=parent, textvariable=self.T_xhh, width=5) # SOLID: style. Clearer boundary
    #self.entry_L_true = Tk.Entry( relief=Tk.SOLID, master=parent, textvariable=self.L_true, width=3) # SOLID: style. Clearer boundary
    self.entry_L_true = Tk.Spinbox( relief=Tk.RIDGE, master=parent, textvariable=self.L_true, width=3, value=(1,2,3,4) ) # SOLID: style. Clearer boundary
    self.L_true.set(self.L_default)
    _s = ''
    for i in range(1,self.K_true_max+1):
      for j in range(1,self.K_true_max+1):
        _s += '\n'+'self.entry_A' + str(i) + str(j) + ' = Tk.Entry(relief=Tk.RIDGE, master=parent, textvariable=self.A'+str(i)+str(j)+', width=7)'
        if i <= self.K_default and j <= self.K_default:
          _s += '\n'+'self.entry_A' + str(i) + str(j) + '.config(relief=Tk.SOLID)'
    exec(_s)

    _s = ''
    for i in range(1,self.L_true_max+1):
      _s += '\n'+'self.entry_mu' + str(i) + '_true = Tk.Entry(relief=Tk.RIDGE, master=parent, textvariable=self.mu'+str(i)+'_true, width=5)'
      _s += '\n'+'self.entry_sig' + str(i) + '_true = Tk.Entry(relief=Tk.RIDGE, master=parent, textvariable=self.sig'+str(i)+'_true, width=5)'
      if i <= self.L_default:
        _s += '\n'+'self.entry_mu' + str(i) + '_true.config(relief=Tk.SOLID)' 
        _s += '\n'+'self.entry_sig' + str(i) + '_true.config(relief=Tk.SOLID)' 
    exec(_s)

    _s = ''
    for k in range(1, self.K_true_max+1): 
      for i in range(1,self.L_true_max+1):
        for j in range(1,self.L_true_max+1):
          _s += '\n'+'self.entry_B' + str(k) + str(i) + str(j) + ' = Tk.Entry(relief=Tk.RIDGE, master=parent, textvariable=self.B'+str(k)+str(i)+str(j)+', width=5)'
          if k <= self.K_default and i <= self.L_default and j <=self.L_default:
            _s += '\n'+'self.entry_B' + str(k) + str(i) + str(j) + '.config(relief=Tk.SOLID)'
    exec(_s)
   

    # --- Entry grid --- 
    self.entry_K_true.grid(row=grid_entry_K_true[0], column=grid_entry_K_true[1], pady=0.1)
    self.entry_T_xhh.grid(row=grid_entry_T_xhh[0], column=grid_entry_T_xhh[1], pady=0.1)
    self.entry_L_true.grid(row=grid_entry_L_true[0], column=grid_entry_L_true[1], pady=0.1)

    _s = ''
    for i in range(1,self.K_true_max+1):
      for j in range(1,self.K_true_max+1):
        _row = (i-1) + grid_entry_A[0]
        _column = (j-1) + grid_entry_A[1]
        _s += '\n'+'self.entry_A' + str(i) + str(j) + '.grid(row='+str(_row)+', column='+str(_column)+', pady=0.1)'    
    exec(_s)
 
    _s = ''
    for i in range(1,self.L_true_max+1):
      _row = eval( 'grid_entry_mu' + str(i) + '_true[0]')
      _column = eval( 'grid_entry_mu' + str(i) + '_true[1]')
      _s += '\n'+'self.entry_mu' + str(i) + '_true.grid(row='+str(_row)+', column='+str(_column)+', pady=0.1)'    
    exec(_s)

    _s = ''
    for i in range(1,self.L_true_max+1):
      _row = eval( 'grid_entry_sig' + str(i) + '_true[0]')
      _column = eval( 'grid_entry_sig' + str(i) + '_true[1]')
      _s += '\n'+'self.entry_sig' + str(i) + '_true.grid(row='+str(_row)+', column='+str(_column)+', pady=0.1)'    
    exec(_s)
 
    _s = ''
    for k in range(1, self.K_true_max+1):
      for i in range(1,self.L_true_max+1):
        for j in range(1,self.L_true_max+1):
          # "exec" doesnt work inside of loop.
          _row = (i-1) + eval('grid_entry_B'+str(k)+'[0]' )
          _column = (j-1) + eval('grid_entry_B'+str(k)+'[1]' )

          _s += '\n'+'self.entry_B' + str(k) + str(i) + str(j) + '.grid(row='+str(_row)+', column='+str(_column)+', pady=0.1)'    
    exec(_s)
   
  
    # -------- Canvas --------
    _figsize_x = 7
    _figsize_y = 2
    _padx_1 = 0
    _pady_1 = 0
    _rect = [0.10, 0.3, 0.8, 0.6]
    fign_xhh = 1
    fign_o = 2
    fign_xhh_VBDCMM = 3

    self.fig_xhh = figure(num=fign_xhh, figsize=(_figsize_x, _figsize_y), facecolor='w')
    self.ax_xhh = self.fig_xhh.add_axes(_rect)
    self.ax_xhh.plot(self.time_xhh, self.xhh_arr+1,'k', linewidth=2)
    self.ax_xhh.set_ylim([0.5, self.K_default + 0.5] )
    self.ax_xhh.set_yticks( arange(1, self.K_default+1, 1) )
    self.ax_xhh.grid(True)
 
    self.ax_xhh.hold(False)

    self.canvas_xhh = FigureCanvasTkAgg(self.fig_xhh, master=parent)
    self.canvas_xhh.show()
    self.tk_canvas_xhh = self.canvas_xhh.get_tk_widget()
    self.tk_canvas_xhh.grid( row=grid_canvas_xhh[0], column=grid_canvas_xhh[1], 
                             rowspan=grid_canvas_xhh[2], columnspan=grid_canvas_xhh[3], 
                             padx=_padx_1, pady=_pady_1 )
 
    xlabel('Time (dt=1)')
    ylabel('X')

    cid1 = self.canvas_xhh.mpl_connect('button_press_event', self.on_figure_click)
    cid2 = self.canvas_xhh.mpl_connect('close_event', self.on_destroy)

    self.fig_o = figure(num=fign_o, figsize=(_figsize_x, _figsize_y), facecolor='w')
    self.ax_o = self.fig_o.add_axes(_rect)
    self.ax_o.plot(self.time_o, self.o_arr,'b')
    self.ax_o.set_ylim([-0.2, 1.2])
    self.ax_o.set_yticks([0, 0.5, 1.0])
    self.ax_o.grid(True)

    self.ax_o.hold(False)

    self.canvas_o = FigureCanvasTkAgg(self.fig_o, master=parent)
    self.canvas_o.show()
    self.tk_canvas_o = self.canvas_o.get_tk_widget()
    self.tk_canvas_o.grid( row=grid_canvas_o[0], column=grid_canvas_o[1], 
                           rowspan=grid_canvas_o[2], columnspan=grid_canvas_o[3], 
                           padx=_padx_1, pady=_pady_1 )
 
    xlabel('Time (dt=1)')
    ylabel('O')

    cid1 = self.canvas_o.mpl_connect('button_press_event', self.on_figure_click)
    cid2 = self.canvas_o.mpl_connect('close_event', self.on_destroy)

  def on_destroy(self, event):
    """ 
    Without this..., loop after close the figure
    """
    print('Destroy!!') 
    self.myParent.quit()

  def on_figure_click(self, event):
    print('you pressed', event.button, event.x, event.y, event.xdata, event.ydata)
    #print('e1_number: ' + str(self.e1_number.get()) )

  def on_click_button_generate_params(self):
    print('Generated parameters')
    _K = self.K_true.get()
    _L = self.L_true.get()
    _T = self.T_xhh.get()

    _s = ''
    for i in range(1,_K+1):
      for j in range(1,_K+1):
        if i != j:
          _s += '\n'+'self.A' + str(i) + str(j) + '.set(' + str( 0.0005/(_K-1)) + ')'
        if i == j:
          _s += '\n'+'self.A' + str(i) + str(j) + '.set(' + str( 1 - 0.0005) + ')'
    exec(_s)
 
    _s = ''
    for k in range(1, _K+1):
      for i in range(1, _L+1):
        for j in range(1, _L+1):
          if i != j:
            _s += '\n'+'self.B' + str(k) + str(i) + str(j) + '.set(' + str( (1/4**(k-1) * 0.1)/(_L-1)) + ')'
          if i == j:
            _s += '\n'+'self.B' + str(k) + str(i) + str(j) + '.set(' + str( 1 - 1/4**(k-1) * 0.1) + ')'

    exec(_s)

    _s = ''
    for i in range(1,_L+1):
      _s += '\n'+'self.mu'+str(i)+'_true.set(' + str( 0.1 + 0.8/(_L-1)* (i-1) ) + ')'
    exec(_s)
 
    _s = ''
    for i in range(1,_L+1):
      _s += '\n'+'self.sig'+str(i)+'_true.set('+ str( 0.15/_L ) + ')'
    exec(_s)
 
  def on_click_button_save_traces(self):
    print('Save traces to %s.dat' % self.save_filename.get())
    filename_0 = self.save_filename.get()
    savetxt(filename_0 + '_X_true_trace.dat', self.xhh_arr, fmt='%d')
    savetxt(filename_0 + '_O_filt_true.dat', self.xh_arr, fmt='%.3f' )
    savetxt(filename_0 + '_O_true.dat', self.o_arr, fmt='%.3f' )

    # save A
    _K = self.K_true.get()
    _T = self.T_xhh.get()
    self.A = zeros( [_K, _K] ) 
    for i in range(1, _K+1):
      for j in range(1, _K+1):
        self.A[i-1, j-1] = eval( 'self.A' + str(i) + str(j) + '.get()' )
    savetxt(filename_0+'_A_true.dat', self.A, fmt='%.9f' )

    _L = self.L_true.get()
    self.B = zeros( [_K, _L, _L] ) 
    self.mu_arr = zeros( _L )
    self.sig_arr = zeros( _L )

    # save B
    for k in range(1, _K+1):
      for i in range(1, _L+1):
        for j in range(1, _L+1):
          self.B[k-1, i-1, j-1] = eval( 'self.B' + str(k) + str(i) + str(j) + '.get()' )

      savetxt(filename_0+'_B'+str(k)+'_true.dat', self.B[k-1,:,:], fmt='%.9f' )

    # save mu and sig
    self.mu_arr = zeros( _L )
    self.sig_arr = zeros( _L )

    for i in range(1, _L+1):
      self.mu_arr[i-1] = eval('self.mu'+str(i)+'_true.get()')
      self.sig_arr[i-1] = eval('self.sig'+str(i)+'_true.get()')

    savetxt(filename_0+'_mu_arr_true.dat', self.mu_arr, fmt='%.3f' )
    savetxt(filename_0+'_sig_arr_true.dat', self.sig_arr, fmt='%.3f' )

 
  def on_click_button_analysis(self):
    print('VB-DCMM analysis')
    VBDCMM_gui_analaysis_func(self.o_arr)

  def on_click_button_generate_trace_xhh(self):
    print('Generate trace_xhh')
    # Construct A matrix
    _K = self.K_true.get()
    _T = self.T_xhh.get()
    self.A = zeros( [_K, _K] ) 
    for i in range(1, _K+1):
      for j in range(1, _K+1):
        self.A[i-1, j-1] = eval( 'self.A' + str(i) + str(j) + '.get()' )

    self.xhh_arr = generate_xhh_func( _T, _K, self.A ) 
    self.ax_xhh.plot(self.time_xhh, self.xhh_arr+1, 'k', linewidth=2)
    self.ax_xhh.set_ylim([0.5, _K + 0.5] )
    self.ax_xhh.set_yticks( arange(1, _K+1, 1) )
    self.ax_xhh.grid(True)
    self.ax_xhh.set_xlabel('Time (dt=1)')
    self.ax_xhh.set_ylabel('X')
    self.fig_xhh.canvas.draw()

  def on_click_button_generate_trace_o(self):
    print('Generate trace_xhh')
    # Construct A matrix
    _K = self.K_true.get()
    _L = self.L_true.get()
    _T = self.T_xhh.get()
    self.A = zeros( [_K, _K] ) 
    self.B = zeros( [_K, _L, _L] ) 
    self.mu_arr = zeros( _L )
    self.sig_arr = zeros( _L )

    for k in range(1, _K+1):
      for i in range(1, _L+1):
        for j in range(1, _L+1):
          self.B[k-1, i-1, j-1] = eval( 'self.B' + str(k) + str(i) + str(j) + '.get()' )

    for i in range(1, _L+1):
      self.mu_arr[i-1] = eval('self.mu'+str(i)+'_true.get()')
      self.sig_arr[i-1] = eval('self.sig'+str(i)+'_true.get()')

    self.xh_arr, self.o_arr = generate_o_func( self.xhh_arr, _K, _L, self.B, self.mu_arr, self.sig_arr ) 
    self.ax_o.plot(self.time_o, self.o_arr)
    self.ax_o.set_ylim([-0.2, 1.2])
    self.ax_o.set_yticks([0, 0.5, 1.0])
    self.ax_o.grid(True)
    self.ax_o.set_xlabel('Time (dt=1)')
    self.ax_o.set_ylabel('O')
    self.fig_o.canvas.draw()

  def on_K_change(self, *args):
    try:
      _K = self.K_true.get()
      _L = self.L_true.get()
      #print( 'K: ' + str( _K ) )
      _s = ''
      for i in range(1, self.K_true_max+1):
        for j in range(1, self.K_true_max+1):
          #    if i >= _K+1 or j >= _K+1:
          #  _s += '\n'+'self.A' + str(i) + str(j) + '.set(0.0)'
          if i <= _K and j <= _K:
            _s += '\n'+'self.entry_A' + str(i) + str(j) + '.config(relief=Tk.SOLID)'
          else:
            _s += '\n'+'self.entry_A' + str(i) + str(j) + '.config(relief=Tk.RIDGE)'

      exec(_s)
      for k in range(1, self.K_true_max+1):
        for i in range(1, self.L_true_max+1):
          for j in range(1, self.L_true_max+1):
            if k <= _K and i <= _L and j <= _L:
              _s += '\n'+'self.entry_B' + str(k) + str(i) + str(j) + '.config(relief=Tk.SOLID)'
            else:
              _s += '\n'+'self.entry_B' + str(k) + str(i) + str(j) + '.config(relief=Tk.RIDGE)'
      exec(_s)

      # special order
      if _K == 1:
        self.A11.set(1.0)

    except:
      pass

  def on_L_change(self, *args):
    try:
      _K = self.K_true.get()
      _L = self.L_true.get()
      #print( 'N: ' + str( _L ) )

      _s = ''
      for k in range(1, self.K_true_max+1):
        for i in range(1, self.L_true_max+1):
          for j in range(1, self.L_true_max+1):
            if k <= _K and i <= _L and j <= _L:
              _s += '\n'+'self.entry_B' + str(k) + str(i) + str(j)+'.config(relief=Tk.SOLID)'
            else:
              _s += '\n'+'self.entry_B' + str(k) + str(i) + str(j) + '.config(relief=Tk.RIDGE)'
      exec(_s)

      _s = ''
      for i in range(1, self.L_true_max+1):
        if i <= _L:
          _s += '\n'+'self.entry_mu' + str(i) + '_true.config(relief=Tk.SOLID)' 
          _s += '\n'+'self.entry_sig' + str(i) + '_true.config(relief=Tk.SOLID)' 
        else:
          _s += '\n'+'self.entry_mu' + str(i) + '_true.config(relief=Tk.RIDGE)' 
          _s += '\n'+'self.entry_sig' + str(i) + '_true.config(relief=Tk.RIDGE)' 
      exec(_s)
    except:
      pass
 


  def on_A_change(self, *args):
      pass

  def on_B_change(self, *args):
    pass

  def on_mu_change(self, *args):
    pass
  def on_sig_change(self, *args):
    pass

  def on_T_xhh_change(self, *args):
    try:
      _T = self.T_xhh.get()
      self.time_xhh = arange(0, _T, 1)
      self.time_o = arange(0, _T+1, 1)
      #print('T changed to %d.' % _T )
    except: # to catch error generated when the entry is empty.
      pass
Example #31
0
class App(object):  #swapped out object, tk.Frame
    def __init__(self, master):
        self.rt = master
        self.rt.protocol("WM_DELETE_WINDOW", self.onClosing)
        self.menu = tk.Menu(self.rt)
        self.rt.title('NMR GUI - Potter')
        self.rt.config(menu=self.menu)
        self.filemenu = tk.Menu(self.menu)
        self.menu.add_cascade(label='File', menu=self.filemenu)
        self.Master = master
        self.filemenu.add_command(label='New')
        self.filemenu.add_command(label='Open', command=self.openFile)
        self.filemenu.add_separator()
        self.filemenu.add_command(
            label='Exit',
            command=lambda: [root.quit(), root.destroy()])
        self.helpmenu = tk.Menu(self.menu)
        self.menu.add_cascade(label='Help', menu=self.helpmenu)
        self.helpmenu.add_command(label='About', command=self.launchHelpWindow)
        self.analysismenu = tk.Menu(self.menu)
        self.menu.add_cascade(label='Analysis', menu=self.analysismenu)
        self.analysismenu.add_command(label='Integrate',
                                      command=self.openIntegrationModule)
        self.analysismenu.add_command(label='EditIntegralList',
                                      command=self.showIntegralList)
        self.analysismenu.add_command(label='Calibrate',
                                      command=self.calibrate)
        self.xShift = 0.0
        self.showIntVar1 = tk.IntVar()
        self.calOn = 0
        self.intVar1 = tk.IntVar()
        self.showPeakVar1 = tk.IntVar()
        self.calVar1 = tk.IntVar()
        self.startCoords = []
        self.endCoords = []
        self.integrals = []
        self.intListVar = []
        self.intGraphics1 = []
        self.intGraphics2 = []
        self.peakList = []
        self.peakGraphics1 = []
        self.intCheckBoxes = []
        self.intDeleteButtons = []

        self.rt.mainloop()

    def openFile(self):

        self.filename = askopenfilename(parent=self.rt)
        with open(self.filename, mode='r') as file:
            self.data = pd.read_csv(file, names=['x', 'y'])
        self.th = 0.0
        self.t1Top = tk.Frame(self.rt)
        self.t1Bottom = tk.Frame(self.rt)
        self.t1Top.pack(side=tk.TOP)
        self.t1Bottom.pack(side=tk.BOTTOM)
        self.t1Left = tk.Frame(self.t1Top)
        self.t1Right = tk.Frame(self.t1Top)
        self.t1Left.pack(side=tk.LEFT)
        self.t1Right.pack(side=tk.RIGHT)
        self.fig = plt.figure()
        self.ax = self.fig.add_subplot(111)
        self.ax.set_xlim(self.data['x'].max(), self.data['x'].min())
        self.ax.plot(self.data['x'], self.data['y'])
        self.canvas = FigureCanvasTkAgg(self.fig, master=self.rt)
        self.canvas.draw()
        #self.canvas.get_tk_widget().pack(in_ = self.t1Right, fill = tk.BOTH, expand = 1)
        self.canvas.get_tk_widget().pack(in_=self.t1Right,
                                         fill=tk.BOTH,
                                         expand=True)
        self.toolbar = NavigationToolbar2Tk(self.canvas, self.rt)
        self.toolbar.update()
        #self.canvas.get_tk_widget().pack(in_ = self.t1Right, fill = tk.BOTH, expand = 1)
        self.canvas.get_tk_widget().pack(in_=self.t1Right,
                                         fill=tk.BOTH,
                                         expand=True)
        self.xShiftScale = tk.Scale(self.rt,
                                    from_=self.data['y'].max(),
                                    to_=self.data['y'].min())
        self.xShiftScale.pack(in_=self.t1Left)
        self.showIntToggle = tk.Checkbutton(self.rt,
                                            text='Show Integrals',
                                            variable=self.showIntVar1,
                                            command=self.showIntegrals)
        self.showIntToggle.pack(in_=self.t1Bottom, side=tk.RIGHT)
        self.showPeaksToggle = tk.Checkbutton(self.rt,
                                              text='Show Peaks',
                                              variable=self.showPeakVar1,
                                              command=self.showPeaks)
        self.showPeaksToggle.pack(in_=self.t1Bottom, side=tk.RIGHT)

    def openIntegrationModule(self):
        self.t = tk.Toplevel(self.rt)
        self.t.protocol("WM_DELETE_WINDOW", self.onIntClosing)
        self.t.wm_title("Integration Module")
        self.intFig = plt.figure()
        self.intAx = self.intFig.add_subplot(111)
        self.intAx.set_xlim(self.data['x'].max(), self.data['x'].min())
        self.intAx.plot(self.data['x'], self.data['y'])
        self.canvas2 = FigureCanvasTkAgg(self.intFig, master=self.t)
        self.canvas2.draw()
        self.canvas2.get_tk_widget().pack(side=tk.TOP, fill=tk.BOTH, expand=1)
        self.toolbar2 = NavigationToolbar2Tk(self.canvas2, self.t)
        self.toolbar2.update()
        self.canvas2.get_tk_widget().pack(side=tk.TOP, fill=tk.BOTH, expand=1)
        self.intToggle = tk.Checkbutton(self.t,
                                        text="Integration Mode",
                                        variable=self.intVar1,
                                        command=self.integrate)
        self.intToggle.pack(side=tk.LEFT)

    def onclick(self, event):
        ix = event.xdata
        self.startCoords.append(ix)

    def onrelease(self, event):
        ix = event.xdata
        self.endCoords.append(ix)
        pint.drawTraps(self.data,
                       min([self.startCoords[-1], self.endCoords[-1]]),
                       max([self.startCoords[-1], self.endCoords[-1]]),
                       self.intAx)
        self.canvas2.draw()

    def integrate(self):
        if self.intVar1.get() == 1:
            self.cid1 = self.canvas2.mpl_connect('button_press_event',
                                                 self.onclick)
            self.cid2 = self.canvas2.mpl_connect('button_release_event',
                                                 self.onrelease)
        else:
            self.canvas2.mpl_disconnect(self.cid1)
            self.canvas2.mpl_disconnect(self.cid2)

    def onClosing(self):
        if messagebox.askokcancel("Quit", "Do you want to quit?"):
            self.rt.quit()
            self.rt.destroy()

    def onIntClosing(self):
        if messagebox.askokcancel("Quit", "Save integrals?"):
            tempInts = []
            for i in range(len(self.startCoords)):
                tempInts.append(min([self.startCoords[i], self.endCoords[i]]))
                tempInts.append(max([self.startCoords[i], self.endCoords[i]]))
                tempInts.append(
                    pint.trapInt(self.data, tempInts[0], tempInts[1]))
                tempInts.append(1)
                self.integrals.append(tempInts.copy())
                tempInts.clear()
            self.startCoords.clear()
            self.endCoords.clear()
        self.t.destroy()

    def showIntegrals(self):
        if self.showIntVar1.get() == 1:
            for i in range(len(self.integrals)):  #this is the region marker
                if (self.integrals[i][3] == 1 and not self.intListVar) or (
                        self.integrals[i][3] == 1
                        and self.intListVar[i].get() == 1):
                    self.intGraphics1.append(
                        self.ax.annotate('',
                                         xy=(self.integrals[i][0], 0),
                                         xytext=(self.integrals[i][1], 0),
                                         arrowprops=dict(arrowstyle='<->',
                                                         facecolor='red'),
                                         annotation_clip=False))
            for i in range(len(self.integrals)
                           ):  #this is the line connecting the integral value
                if (self.integrals[i][3] == 1 and not self.intListVar) or (
                        self.integrals[i][3] == 1
                        and self.intListVar[i].get() == 1):
                    self.intGraphics2.append(
                        self.ax.annotate(
                            '{:.2f}'.format(self.integrals[i][2]),
                            xy=(self.integrals[i][0] + (
                                (self.integrals[i][1] - self.integrals[i][0]) /
                                2), 0),
                            xytext=(self.integrals[i][0] + (
                                (self.integrals[i][1] - self.integrals[i][0]) /
                                2), -3),
                            arrowprops=dict(arrowstyle='-', facecolor='red'),
                            annotation_clip=False))
            self.canvas.draw()
        else:
            for i in self.intGraphics1:
                i.remove()
            for i in self.intGraphics2:
                i.remove()
            self.intGraphics1.clear()
            self.intGraphics2.clear()
            self.canvas.draw()

    def showIntegralList(self):
        self.t2 = tk.Toplevel(self.rt)
        self.t2.protocol("WM_DELETE_WINDOW", self.onCloseIntegralListWindow)
        self.t2.wm_title("Integrals")
        self.t2Top = tk.Frame(self.t2)
        self.t2Bottom = tk.Frame(self.t2)
        self.t2Top.pack(side=tk.TOP)
        self.t2Bottom.pack(side=tk.BOTTOM)

        self.t2Left = tk.Frame(self.t2Bottom)
        self.t2Right = tk.Frame(self.t2Bottom)

        self.t2Left.pack(side=tk.LEFT)
        self.t2Right.pack(side=tk.RIGHT)

        for i in range(len(self.integrals)):
            self.intListVar.append(tk.IntVar(value=1))
            self.intCheckBoxes.append(
                tk.Checkbutton(self.t2Left,
                               text=str(len(self.integrals) - i) + '\t' +
                               '{:.2f}'.format(self.integrals[i][0]) + '\t' +
                               '{:.2f}'.format(self.integrals[i][1]) + '\t' +
                               '{:.2f}'.format(self.integrals[i][2]),
                               variable=self.intListVar[i],
                               width=40))
            self.intDeleteButtons.append(
                tk.Button(
                    self.t2Right,
                    text='Delete: ' + str((len(self.integrals) - i)),
                    command=lambda c=i: self.deleteInt(self.integrals, c))
            )  # why not lambda:self.integrals[len(self.integrals)-i-1] ????
            self.intCheckBoxes[i].pack(in_=self.t2Left,
                                       side=tk.BOTTOM,
                                       fill=tk.X)
            self.intDeleteButtons[i].pack(in_=self.t2Right, side=tk.BOTTOM)

    def deleteInt(self, ar, inx):
        del self.integrals[int(inx)]

    def onCloseIntegralListWindow(self):
        self.intCheckBoxes.clear()
        self.intDeleteButtons.clear()
        self.canvas.draw()
        self.t2Left.destroy()
        self.t2Right.destroy()
        self.t2Bottom.destroy()
        self.t2Top.destroy()
        self.t2.destroy()

    def showPeaks(self):  # removed parameter th
        self.th = self.xShiftScale.get()
        self.peakList = find_peaks(self.data['y'].to_numpy(), self.th)
        if self.showPeakVar1.get() == 1:
            a = 0
            for i in range(len(self.peakList[0])):
                if ((self.data.iloc[self.peakList[0][i - 1]][1] <
                     self.data.iloc[self.peakList[0][i]][1]) and
                    ((self.data.iloc[self.peakList[0][i - 1]][1]) >=
                     (self.data.iloc[self.peakList[0][i]][1] - 0.1))
                        or ((self.data.iloc[self.peakList[0][i - 1]][1] >
                             (self.data.iloc[self.peakList[0][i]][1])) and
                            ((self.data.iloc[self.peakList[0][i - 1]][1]) <=
                             (self.data.iloc[self.peakList[0][i]][1] + 0.1)))):
                    a = a + 1
                else:
                    a = a + 0
                self.peakGraphics1.append(
                    self.ax.annotate(
                        '{:.2f}'.format(
                            self.data.iloc[self.peakList[0][i]][0]),
                        xy=(self.data.iloc[self.peakList[0][i]][0],
                            self.data.iloc[self.peakList[0][i]][1]),
                        xytext=(self.data.iloc[self.peakList[0][i]][0],
                                self.data.iloc[self.peakList[0][i]][1] + a)))
            self.canvas.draw()
        else:
            for i in self.peakGraphics1:
                i.remove()
            self.peakGraphics1.clear()
            self.canvas.draw()

    def onclick2(self, event):
        ix = event.xdata
        self.xShift = ix
        self.data['x'] = self.data['x'] - self.xShift
        self.shiftIntegrals(self.integrals, self.xShift)
        self.calOn = 0
        self.canvas.mpl_disconnect(self.cid3)
        self.rt.config(cursor='')

    def shiftIntegrals(self, iL, sh):
        msgBox = tk.messagebox.askquestion(
            'Shift Integrals',
            'Shift integrals along with spectrum?',
            icon='warning')
        if msgBox == 'yes':
            self.integralShift(iL, sh)
            self.ax.cla()
            self.ax.set_xlim(self.data['x'].max(), self.data['x'].min())
            self.ax.plot(self.data['x'], self.data['y'])
            self.canvas.draw()
        else:
            self.ax.cla()
            self.ax.set_xlim(self.data['x'].max(), self.data['x'].min())
            self.ax.plot(self.data['x'], self.data['y'])
            self.canvas.draw()

    def integralShift(self, ints, xsh):
        for i in range(len(self.integrals)):
            self.integrals[i][0] = self.integrals[i][0] - xsh
            self.integrals[i][1] = self.integrals[i][1] - xsh

    def calibrate(self):
        self.rt.config(cursor='cross')
        self.calOn = 1
        self.cid3 = self.canvas.mpl_connect('button_press_event',
                                            self.onclick2)

    def onHelpClosing(self):
        self.t3.destroy()

    def launchHelpWindow(self):
        self.t3 = tk.Toplevel(self.rt)
        self.t3.protocol("WM_DELETE_HELPWINDOW", self.onHelpClosing)
        self.helpText = tk.Text(self.t3, height=10, width=30, wrap='word')
        self.helpText.pack(expand=True, fill=tk.BOTH)
        __location__ = os.path.realpath(
            os.path.join(os.getcwd(), os.path.dirname(__file__)))
        aboutFile = open(os.path.join(__location__, 'about.rtf'))
        self.helpText.insert(tk.END, aboutFile.read())
        aboutFile.close()
Example #32
0
def display_graph_ext(dimension, b=False):

    root = Tk.Tk()
    root.wm_title("SMG2S UI")

    graphique = True

    #On ouvre les fichiers contenant les chemins des deux fichiers selectionnes
    #On ouvre le fichier 1
    fichier1 = read_file_path(1)
    #On ouvre le fichier 2
    fichier2 = read_file_path(2)

    print(fichier1, " & ", fichier2)

    f = Figure(figsize=(8, 6), dpi=100)
    a = f.add_subplot(1, 1, 1)

    reel1 = loadtxt(r'data/matrix/r1.vec')
    imaginaire1 = loadtxt(r'data/matrix/i1.vec')
    reel2 = loadtxt(r'data/matrix/r2.vec')
    imaginaire2 = loadtxt(r'data/matrix/i2.vec')

    if dimension == 2:
        if fichier1 != "":
            a.scatter(reel1,
                      imaginaire1,
                      c='black',
                      marker='o',
                      s=200,
                      label="Original solution")
            graphique = True
        if fichier2 != "":
            a.scatter(reel2,
                      imaginaire2,
                      c='red',
                      marker='+',
                      s=200,
                      label="Final solution")
            graphique = True

    elif dimension == 1:

        if fichier1 != "":
            a.scatter(reel1,
                      imaginaire1,
                      c='black',
                      marker='o',
                      s=200,
                      label="Original solution")
            graphique = True
        if fichier2 != "":
            a.scatter(reel2,
                      imaginaire2,
                      c='red',
                      marker='+',
                      s=200,
                      label="Final solution")
            graphique = True
    else:
        Tk.messagebox.showerror(
            "Error",
            "Impossible to generate the graph, the dimension is incorrect")
        graphique = False
    if graphique == True:
        if b == True:
            u = loadtxt(r'data/custom/axe.vec')
            a.set_xlim(u[0], u[1])
            a.set_ylim(u[2], u[3])
        show()

    # a tk.DrawingArea
    canvas = FigureCanvasTkAgg(f, master=root)
    canvas.get_tk_widget().pack(side=Tk.TOP, fill=Tk.BOTH, expand=1)

    toolbar = NavigationToolbar2TkAgg(canvas, root)
    toolbar.update()
    canvas._tkcanvas.pack(side=Tk.TOP, fill=Tk.BOTH, expand=1)

    def on_key_event(event):
        print('you pressed %s' % event.key)
        key_press_handler(event, canvas, toolbar)

    canvas.mpl_connect('key_press_event', on_key_event)

    def _quit():
        root.quit()  # stops mainloop
        root.destroy()  # this is necessary on Windows to prevent
        # Fatal Python Error: PyEval_RestoreThread: NULL tstate

    button = Tk.Button(master=root, text='Quit', command=_quit)
    button.pack(side=Tk.BOTTOM)

    Tk.mainloop()
Example #33
0
class SplitPrintWindow():
    def __init__(self,
                 print_manager,
                 combo_prints,
                 hulls_df,
                 print_numb,
                 vid_panel,
                 invert_axes=True):

        self.root = tk.Tk()
        self.root.wm_title("Split the Selected Print")

        self.fig = Figure(figsize=(10, 8), dpi=100)
        self.canvas = FigureCanvasTkAgg(self.fig,
                                        master=self.root)  # A tk.DrawingArea.
        self.canvas.draw()
        self.canvas.get_tk_widget().pack(side=tk.TOP, fill=tk.BOTH, expand=1)

        self.toolbar = NavigationToolbar2TkAgg(self.canvas, self.root)
        self.toolbar.update()
        self.canvas._tkcanvas.pack(side=tk.TOP, fill=tk.BOTH, expand=1)
        self.print_manager = print_manager
        self.combo_prints = combo_prints
        self.print_numb = print_numb
        self.first_frame = self.combo_prints.first_frame[print_numb]
        n_frames = (self.combo_prints.last_frame[print_numb] -
                    self.first_frame) + 1
        grid_size = int(np.ceil(np.sqrt(n_frames)))
        self.axes = []
        self.fig.set_size_inches(16, 9)
        button_axes = self.fig.add_axes([.01, .01, .05, .05])
        self.button = Button(button_axes, 'Split')
        self.button.on_clicked(self.create_new_hulls)

        these_hulls = hulls_df[hulls_df.print_numb == print_numb]
        self.collections = {}
        self.xyes = {}
        for i in range(0, n_frames):
            ax = self.fig.add_subplot(grid_size, grid_size, i + 1)
            self.axes.append(ax)
            ax.set_axis_off()
            frame = vid_panel.get_frame(self.first_frame + i)
            X = self.combo_prints.X[print_numb]
            Y = self.combo_prints.Y[print_numb]
            ax.imshow(frame)
            xes = []
            yes = []
            for c in (these_hulls.contours[these_hulls.frame ==
                                           self.first_frame + i].values[0]):
                #add all to a single list to make one collection
                xes = xes + list(c[:, 0, 0])
                yes = yes + list(c[:, 0, 1])
            self.collections[ax] = ax.scatter(xes, yes)
            self.xyes[ax] = self.collections[ax].get_offsets()
            #set it to have list of facecolors so that selection works
            facecolors = self.collections[ax].get_facecolors()
            npts = len(self.xyes[ax])
            facecolors = np.tile(facecolors, npts).reshape(npts, -1)
            self.collections[ax].set_facecolor(facecolors)

            if invert_axes:
                ax.set_xlim(X + 50, X - 50)
            else:
                ax.set_xlim(X - 50, X + 50)
            ax.set_ylim(Y - 50, Y + 50)
            ax.set_title('Frame ' + str(self.first_frame + i))
        self.axes = np.asarray(self.axes)
        self.cid = self.canvas.mpl_connect('button_press_event', self.onpress)
        self.canvas.draw()
        tk.mainloop()

    def create_new_hulls(self, event):
        new_hull_points = []
        old_hull_points = []
        frame = []
        if (sys.version_info > (3, 0)):
            iterab = self.collections.items()
        else:
            iterab = self.collections.iteritems()
        for ax, collection in iterab:
            #make np array of bools with whether color matches the selection color for each point
            inds = np.asarray([
                True if np.array_equal(i, [.4, .4, .9, 1.0]) else False
                for i in collection.get_facecolors()
            ])
            #use np bool indexing to get x,y values for selected and unselected
            new_hull_points.append(self.xyes[ax][inds])
            old_hull_points.append(self.xyes[ax][~inds])
            frame.append(self.first_frame + np.where(self.axes == ax)[0])
        self.print_manager.split_print(new_hull_points, old_hull_points, frame,
                                       self.print_numb)
        self.root.destroy()

    def callback(self, verts):
        facecolors = self.collections[self.current_axes].get_facecolors()
        p = path.Path(verts)
        ind = p.contains_points(self.xyes[self.current_axes])
        for i in range(len(self.xyes[self.current_axes])):
            if ind[i]:
                facecolors[i] = [.4, .4, .9, 1.0]
            else:
                facecolors[i] = [.4, .4, .2, .5]
        self.collections[self.current_axes].set_facecolor(facecolors)
        self.fig.canvas.draw_idle()
        self.fig.canvas.widgetlock.release(self.lasso)
        del self.lasso

    #TODO: troubleshoot widget locks
    def onpress(self, event):
        if self.fig.canvas.widgetlock.locked(): return
        if event.inaxes is None: return
        self.current_axes = event.inaxes
        self.lasso = Lasso(event.inaxes, (event.xdata, event.ydata),
                           self.callback)
        # acquire a lock on the widget drawing
        self.fig.canvas.widgetlock(self.lasso)
Example #34
0
class Graph(tk.Frame):
    ax, original_xlim, original_ylim, coll, pick_id = None, None, None, None, None
    start_end_bool = -1  # 0 is start, 1 is end, -1 is None
    start_index, end_index, move_index, remove_index = 0, None, None, None
    max_time, max_speed, max_height, min_height = 0, 0, 0, 0
    data = []
    connect_ids, move_ids = [], []
    current_color_scheme = 'd'

    def __init__(self, master):
        super().__init__(master)
        self.master = master
        self.fig = Figure(figsize=(10, 7), dpi=100, tight_layout=True)
        self.fig.set_facecolor('#f0f0ed')

        self.zoom_pan = GraphInteractions.ZoomPan()
        self.master_string = tk.StringVar()

        self.canvas = FigureCanvasTkAgg(self.fig, self)
        self.canvas.draw()
        self.canvas.get_tk_widget().pack(side=tk.TOP, fill=tk.BOTH, expand=1)

    def redraw(self, input_file_location):
        x, y, c = zip(*self.read_data(input_file_location))
        self.fig.clear()
        self.ax = self.fig.add_subplot(111, frameon=False)
        self.coll = self.ax.scatter(x, y, color=c, picker=True)
        self.end_index = len(self.data) - 1
        self.connect_ids.append(
            GraphInteractions.ZoomPan.zoom_factory(self.zoom_pan,
                                                   self.ax,
                                                   base_scale=1.3))
        self.connect_ids.extend(
            GraphInteractions.ZoomPan.pan_factory(self.zoom_pan, self.ax))
        self.original_xlim = self.ax.get_xlim()
        self.original_ylim = self.ax.get_ylim()
        self.canvas.draw()

    def redraw_color(self, x, y, c):
        self.fig.clear()
        self.ax = self.fig.add_subplot(111, frameon=False)
        self.coll = self.ax.scatter(x, y, color=c, picker=True)
        self.ax.set_xlim(self.zoom_pan.cur_xlim)
        self.ax.set_ylim(self.zoom_pan.cur_ylim)
        self.connect_ids.append(
            GraphInteractions.ZoomPan.zoom_factory(self.zoom_pan,
                                                   self.ax,
                                                   base_scale=1.3))
        self.connect_ids.extend(
            GraphInteractions.ZoomPan.pan_factory(self.zoom_pan, self.ax))
        self.canvas.draw()

    def reset_zoom(self):
        self.ax.set_xlim(self.original_xlim)
        self.ax.set_ylim(self.original_ylim)
        self.ax.figure.canvas.draw()  # force re-draw

    def reset_start(self, master_string):
        self.start_index = 0
        master_string.set("")
        self.redraw_ext()

    def reset_end(self, master_string):
        self.end_index = len(self.data) - 1
        master_string.set("")
        self.redraw_ext()

    def read_data(self, input_file_location):
        x_array = []
        y_array = []
        color_array = []
        self.data.clear()
        json_file = open(input_file_location, "r")
        file_data = json.load(json_file)
        json_file.close()
        old_time, old_x, old_y = 0, file_data['recording']['path'][0][
            'x'], file_data['recording']['path'][0]['y']
        self.max_time, self.max_speed, self.max_height, self.min_height = 0, 0, 0, file_data[
            'recording']['path'][0]['z']
        speed = 0
        for time in file_data['recording']['path']:
            x_array.append(time['x'])
            y_array.append(time['y'])
            time_div = time['t'] - old_time
            if time['t'] > self.max_time:
                self.max_time = time['t']
            if time_div != 0:
                speed = distance(time['x'], old_x, time['y'], old_y) / time_div
            if speed > self.max_speed:
                self.max_speed = speed
            if time['z'] > self.max_height:
                self.max_height = time['z']
            elif time['z'] < self.min_height:
                self.min_height = time['z']
            self.data.append(
                [time['x'], time['y'], time['t'], speed, time['z']])
            color_array.append('tab:blue')
            old_time = time['t']
            old_x, old_y = time['x'], time['y']
        return zip(x_array, y_array, color_array)

    def redraw_ext(self):
        for cid in self.connect_ids:
            self.canvas.mpl_disconnect(cid)
        self.connect_ids.clear()
        x = []
        y = []
        c = []
        for idx, row in enumerate(self.data):
            x.append(row[0])
            y.append(row[1])
            if idx == self.start_index or idx == self.end_index or idx == self.remove_index:
                c.append('tab:red')
            elif idx < self.start_index or idx > self.end_index or\
                    (self.start_index == 0 and self.end_index == len(self.data) - 1):
                c.append('tab:blue')
            elif self.start_index < idx < self.end_index:
                c.append('c')

        self.redraw_color(x, y, c)

    def redraw_simp(self):
        for cid in self.connect_ids:
            self.canvas.mpl_disconnect(cid)
        self.connect_ids.clear()
        x = []
        y = []
        c = []
        for idx, row in enumerate(self.data):
            x.append(row[0])
            y.append(row[1])
            if idx == self.move_index:
                c.append('tab:red')
            else:
                c.append('tab:blue')
        self.redraw_color(x, y, c)

    def change_color(self, event):
        if event.mouseevent.button != 1: return
        if self.start_end_bool == 0:
            self.start_index = event.ind[0]
        elif self.start_end_bool == 1:
            self.end_index = event.ind[0]
        elif self.start_end_bool == 2:
            self.remove_index = event.ind[0]
        self.redraw_ext()
        self.master_string.set(
            'x: %.4f, y: %.4f' %
            (self.data[event.ind[0]][0], self.data[event.ind[0]][1]))

    def show_time(self):
        self.current_color_scheme = 't'
        for cid in self.connect_ids:
            self.canvas.mpl_disconnect(cid)
        self.connect_ids.clear()
        x = []
        y = []
        c = []
        for idx, row in enumerate(self.data):
            x.append(row[0])
            y.append(row[1])
            gradient = row[2] / self.max_time
            c.append((0, 1 - gradient, gradient))
        self.redraw_color(x, y, c)

    def show_speed(self):
        self.current_color_scheme = 's'
        for cid in self.connect_ids:
            self.canvas.mpl_disconnect(cid)
        self.connect_ids.clear()
        x = []
        y = []
        c = []
        for idx, row in enumerate(self.data):
            x.append(row[0])
            y.append(row[1])
            gradient = row[3] / self.max_speed
            c.append((1 - gradient, gradient, 0))
        self.redraw_color(x, y, c)

    def show_height(self):
        self.current_color_scheme = 'h'
        for cid in self.connect_ids:
            self.canvas.mpl_disconnect(cid)
        self.connect_ids.clear()
        x = []
        y = []
        c = []
        for idx, row in enumerate(self.data):
            x.append(row[0])
            y.append(row[1])
            gradient = (row[4] - self.min_height) / (self.max_height -
                                                     self.min_height)
            c.append((gradient * 0.5 + 0.5, gradient * 0.8, gradient * 0.8))
        self.redraw_color(x, y, c)

    def reset_color(self):
        self.current_color_scheme = 'd'
        for cid in self.connect_ids:
            self.canvas.mpl_disconnect(cid)
        self.connect_ids.clear()
        x = []
        y = []
        c = []
        for idx, row in enumerate(self.data):
            x.append(row[0])
            y.append(row[1])
            c.append('tab:blue')
        self.redraw_color(x, y, c)

    def attach_start_stop(self, master_string_var, start_end):
        self.detach_start_stop()
        self.start_end_bool = start_end
        self.master_string = master_string_var
        self.pick_id = self.canvas.mpl_connect('pick_event', self.change_color)

    def detach_start_stop(self):
        if self.pick_id is None: return
        self.start_end_bool = -1
        self.canvas.mpl_disconnect(self.pick_id)
        for move_id in self.move_ids:
            self.canvas.mpl_disconnect(move_id)

    def attach_move_node(self):
        def on_press(event):
            if event.mouseevent.button != 1: return
            self.move_index = event.ind[0]
            self.master.move_node_location.set(
                'x: %.4f, y: %.4f' %
                (self.data[self.move_index][0], self.data[self.move_index][1]))

        def on_release(event):
            self.redraw_simp()

        def on_motion(event):
            if event.button != 1: return
            self.data[self.move_index][0] = event.xdata
            self.data[self.move_index][1] = event.ydata
            self.master.move_node_location.set(
                'x: %.4f, y: %.4f' %
                (self.data[self.move_index][0], self.data[self.move_index][1]))

            self.redraw_simp()

        self.detach_start_stop()
        self.pick_id = self.canvas.mpl_connect('pick_event', on_press)
        self.move_ids.append(
            self.canvas.mpl_connect('key_press_event', self.move_node_button))
        self.move_ids.append(
            self.canvas.mpl_connect('button_release_event', on_release))
        self.move_ids.append(
            self.canvas.mpl_connect('motion_notify_event', on_motion))

    def attach_remove_node(self, master_string):
        self.detach_start_stop()
        self.start_end_bool = 2
        self.master_string = master_string
        self.pick_id = self.canvas.mpl_connect('pick_event', self.change_color)

    def next_start(self, master_string, diff):
        self.start_index += diff
        if self.start_index < 0:
            self.start_index = 0
        self.redraw_ext()
        master_string.set(
            'x: %.4f, y: %.4f' %
            (self.data[self.start_index][0], self.data[self.start_index][1]))

    def next_end(self, master_string, diff):
        self.end_index += diff
        if self.end_index > len(self.data) - 1:
            self.end_index = len(self.data) - 1
        self.redraw_ext()
        master_string.set(
            'x: %.4f, y: %.4f' %
            (self.data[self.end_index][0], self.data[self.end_index][1]))

    def move_node_button(self, event):
        direction = ""
        if event.key == "up":
            direction = "N"
        elif event.key == "right":
            direction = "E"
        elif event.key == "down":
            direction = "S"
        elif event.key == "left":
            direction = "W"
        if direction != "":
            self.move_node(direction, float(self.master.move_entry.get()))

    def move_node(self, direction, move_distance):
        if direction == "N":
            self.data[self.move_index][1] += move_distance
        elif direction == "E":
            self.data[self.move_index][0] += move_distance
        elif direction == "S":
            self.data[self.move_index][1] -= move_distance
        elif direction == "W":
            self.data[self.move_index][0] -= move_distance
        self.master.move_node_location.set(
            'x: %.4f, y: %.4f' %
            (self.data[self.move_index][0], self.data[self.move_index][1]))
        self.redraw_simp()

    def remove_node(self):
        del self.data[self.remove_index]
        self.end_index = len(self.data) - 1
        self.redraw_ext()
        self.master_string.set(
            'x: %.4f, y: %.4f' %
            (self.data[self.remove_index][0], self.data[self.remove_index][1]))

    def apply_local_speedup(self, value):
        speedup = 1
        speed = 0
        previous_time = 0
        previous_old_time = 0
        old_x, old_y = self.data[0][0], self.data[0][1]
        for idx, row in enumerate(self.data):
            if self.start_index == idx:
                speedup = 1 - float(value) / 100
            elif self.end_index == idx:
                speedup = 1
            old_time = row[2]
            if old_time < previous_old_time:
                previous_old_time = old_time / 2
            row[2] = previous_time + (min(old_time - previous_old_time, 2) *
                                      speedup)
            time_div = row[2] - previous_time
            if row[2] > self.max_time:
                self.max_time = row[2]
            if time_div != 0:
                speed = distance(row[0], old_x, row[1], old_y) / time_div
            if speed > self.max_speed:
                self.max_speed = speed
            row[3] = speed
            previous_time = row[2]
            previous_old_time = old_time
            old_x, old_y = row[0], row[1]
            self.update_unknown()

    def update_unknown(self):
        if self.current_color_scheme == 'h':
            self.show_height()
        elif self.current_color_scheme == 's':
            self.show_speed()
        elif self.current_color_scheme == 't':
            self.show_time()
        else:
            self.reset_color()
Example #35
0
class Analysis:
    """ Main class for GUI visualising transfer functions """
    def __init__(self, parent):
        """Creates all widgets"""
        self.master = parent
        self.move_zero = None
        self.index1 = None
        self.index2 = None
        self.zeros = []
        self.poles = []

        self.topframe = tkinter.Frame(self.master)
        self.topframe.pack(expand=True, fill='both')

        self.entries = tkinter.Frame(self.topframe)
        self.entries.pack(expand=True, fill='both')

        self.figure = tkinter.Frame(self.topframe)
        self.figure.pack(expand=True, fill='both')

        header = tkinter.Label(self.entries,
            text='Define the transfer function:')
        header.grid(row=0, column=0, padx=20, pady=7)


        self.tfi = TFInput(self.entries)
        self.sys = self.tfi.get_tf()

        tkinter.Button(self.entries, text='Apply', command=self.apply,
               width=9).grid(row=0, column=1, rowspan=3, padx=10, pady=5)

        self.f_bode = plt.figure(figsize=(4, 4))
        self.f_nyquist = plt.figure(figsize=(4, 4))
        self.f_pzmap = plt.figure(figsize=(4, 4))
        self.f_step = plt.figure(figsize=(4, 4))

        self.canvas_pzmap = FigureCanvasTkAgg(self.f_pzmap,
                                                master=self.figure)
        self.canvas_pzmap.draw()
        self.canvas_pzmap.get_tk_widget().grid(row=0, column=0,
                                                padx=0, pady=0)

        self.canvas_bode = FigureCanvasTkAgg(self.f_bode,
                                                master=self.figure)
        self.canvas_bode.draw()
        self.canvas_bode.get_tk_widget().grid(row=0, column=1,
                                                padx=0, pady=0)

        self.canvas_step = FigureCanvasTkAgg(self.f_step,
                                                master=self.figure)
        self.canvas_step.draw()
        self.canvas_step.get_tk_widget().grid(row=1, column=0,
                                                padx=0, pady=0)

        self.canvas_nyquist = FigureCanvasTkAgg(self.f_nyquist, 
                                                master=self.figure)
        self.canvas_nyquist.draw()
        self.canvas_nyquist.get_tk_widget().grid(row=1, column=1,
                                                    padx=0, pady=0)

        self.canvas_pzmap.mpl_connect('button_press_event',
                                        self.button_press)
        self.canvas_pzmap.mpl_connect('button_release_event',
                                        self.button_release)
        self.canvas_pzmap.mpl_connect('motion_notify_event',
                                        self.mouse_move)    

        self.apply()    

    def button_press(self, event):
        """ Handle button presses, detect if we are going to move
        any poles/zeros"""
        # find closest pole/zero
        if (event.xdata != None and event.ydata != None):

            new = event.xdata + 1.0j*event.ydata

            tzeros = list(abs(self.zeros-new))
            tpoles = list(abs(self.poles-new))

            if (size(tzeros) > 0):
                minz = min(tzeros)
            else:
                minz = float('inf')
            if (size(tpoles) > 0):
                minp = min(tpoles)
            else:
                minp = float('inf')

            if (minz < 2 or minp < 2):
                if (minz < minp):
                    # Moving zero(s)
                    self.index1 = tzeros.index(minz)
                    self.index2 = list(self.zeros).index(
                        conj(self.zeros[self.index1]))
                    self.move_zero = True
                else:
                    # Moving pole(s)
                    self.index1 = tpoles.index(minp)
                    self.index2 = list(self.poles).index(
                        conj(self.poles[self.index1]))
                    self.move_zero = False

    def button_release(self, event):
        """ Handle button release, update pole/zero positions,
        if the were moved"""
        if (self.move_zero == True):
            self.tfi.set_zeros(self.zeros)
        elif (self.move_zero == False):
            self.tfi.set_poles(self.poles)
        else:
            return

        self.move_zero = None
        self.index1 = None
        self.index2 = None

        tfcn = self.tfi.get_tf()
        if (tfcn):
            self.zeros = tfcn.zero()
            self.poles = tfcn.pole()
            self.sys = tfcn
            self.redraw()  

    def mouse_move(self, event):
        """ Handle mouse movement, redraw pzmap while drag/dropping """
        if (self.move_zero != None and
            event.xdata != None and 
            event.ydata != None):

            if (self.index1 == self.index2):
                # Real pole/zero
                new = event.xdata
                if (self.move_zero == True):
                    self.zeros[self.index1] = new
                elif (self.move_zero == False):
                    self.poles[self.index1] = new
            else:
                # Complex poles/zeros
                new = event.xdata + 1.0j*event.ydata
                if (self.move_zero == True):
                    self.zeros[self.index1] = new
                    self.zeros[self.index2] = conj(new)
                elif (self.move_zero == False):
                    self.poles[self.index1] = new
                    self.poles[self.index2] = conj(new)
            tfcn = None
            if (self.move_zero == True):
                self.tfi.set_zeros(self.zeros)
                tfcn = self.tfi.get_tf()
            elif (self.move_zero == False):
                self.tfi.set_poles(self.poles)
                tfcn = self.tfi.get_tf()
            if (tfcn != None):
                self.draw_pz(tfcn)
                self.canvas_pzmap.draw()

    def apply(self):
        """Evaluates the transfer function and produces different plots for
           analysis"""
        tfcn = self.tfi.get_tf()

        if (tfcn):
            self.zeros = tfcn.zero()
            self.poles = tfcn.pole()
            self.sys = tfcn
            self.redraw()    

    def draw_pz(self, tfcn):
        """Draw pzmap"""
        self.f_pzmap.clf()
        # Make adaptive window size, with min [-10, 10] in range,
        # always atleast 25% extra space outside poles/zeros
        tmp = list(self.zeros)+list(self.poles)+[8]
        val = 1.25*max(abs(array(tmp)))
        plt.figure(self.f_pzmap.number)
        control.matlab.pzmap(tfcn)
        plt.suptitle('Pole-Zero Diagram')

        plt.axis([-val, val, -val, val])

    def redraw(self):
        """ Redraw all diagrams """
        self.draw_pz(self.sys)
        
        self.f_bode.clf()
        plt.figure(self.f_bode.number)
        control.matlab.bode(self.sys, logspace(-2, 2))
        plt.suptitle('Bode Diagram')

        self.f_nyquist.clf()
        plt.figure(self.f_nyquist.number)
        control.matlab.nyquist(self.sys, logspace(-2, 2))
        plt.suptitle('Nyquist Diagram')

        self.f_step.clf()
        plt.figure(self.f_step.number)
        try:
            # Step seems to get intro trouble
            # with purely imaginary poles
            tvec, yvec = control.matlab.step(self.sys)
            plt.plot(tvec.T, yvec)
        except:
            print("Error plotting step response")
        plt.suptitle('Step Response')

        self.canvas_pzmap.draw()
        self.canvas_bode.draw()
        self.canvas_step.draw()
        self.canvas_nyquist.draw()
Example #36
0
info_xy.pack()

# The setting of figure
mat_plot = Figure(figsize=(6, 4), dpi=100)
fig = mat_plot.add_subplot(111)
fig.set_xlabel('x')
fig.set_ylabel('y')

# Draw the figure by tk.DrawingArea
canvas_frame = FigureCanvasTkAgg(mat_plot, master=left)
canvas_frame.show()
canvas_frame.get_tk_widget().pack(side='top', fill='both', expand=1)
canvas_frame._tkcanvas.pack(side='top', fill='both', expand=1)

# Help to show the x, y positions
canvas_frame.mpl_connect('motion_notify_event', showXY_handler)

# Help to show the cut lines
canvas_frame.mpl_connect('button_press_event', cut_lines)

# Choose the central position
# Give the central line
var_cen = IntVar()  # boolean value: var_cut.get()
check_cen = Checkbutton(right_top, text='Show central line', variable=var_cen)
check_cen.pack()

# Show the opened files
var = StringVar(root)
var.set(choices)

# all submenus to main menu
Example #37
0
    #plt.xlim((-15000, 20000))
    #plt.ylim((-15000, 20000))
    canvas.show()


if __name__ == '__main__':
    matplotlib.use('TkAgg')

    root = tkinter.Tk()

    #在Tk的GUI上放置一个画布,并用.grid()来调整布局
    fig = Figure(figsize=(7, 5), dpi=100)
    canvas = FigureCanvasTkAgg(fig, master=root)
    canvas.show()
    canvas.get_tk_widget().grid(row=0, columnspan=4)
    canvas.mpl_connect('button_release_event', onPress)
    canvas.mpl_connect('motion_notify_event', onMotion)
    #polygon = plt.Polygon([[150, 150], [350, 400], [200, 600]], facecolor='g', alpha=0.5)
    #circ = mpatches.Circle((0, 0), 100, color = 'g', alpha=0.5)
    circ = mpatches.RegularPolygon((0, 0), 30, 100, color='g', alpha=0.5)

    root.bind("<Motion>", showLocation)

    #放置标签、文本框和按钮等部件,并设置文本框的默认值和按钮的事件函数
    path = tkinter.StringVar()
    tkinter.Label(root, text='目标路径:').grid(row=1, column=0)
    tkinter.Entry(root, textvariable=path).grid(row=1, column=1)
    tkinter.Button(root, text='Json文件选择', command=selectPath).grid(row=1,
                                                                   column=2)
    tkinter.Button(root, text='画图', command=drawDNA).grid(row=1,
                                                          column=3,
Example #38
0
t = arange(0.0,3.0,0.01)
s = sin(2*pi*t)

a.plot(t,s)


# a tk.DrawingArea
canvas = FigureCanvasTkAgg(f, master=root)
canvas.show()
canvas.get_tk_widget().pack(side=Tk.TOP, fill=Tk.BOTH, expand=1)

toolbar = NavigationToolbar2TkAgg( canvas, root )
toolbar.update()
canvas._tkcanvas.pack(side=Tk.TOP, fill=Tk.BOTH, expand=1)

def on_key_event(event):
    print('you pressed %s'%event.key)
    key_press_handler(event, canvas, toolbar)

canvas.mpl_connect('key_press_event', on_key_event)

def _quit():
    root.quit()     # stops mainloop
    root.destroy()  # this is necessary on Windows to prevent
                    # Fatal Python Error: PyEval_RestoreThread: NULL tstate

button = Tk.Button(master=root, text='Quit', command=_quit)
button.pack(side=Tk.BOTTOM)

Tk.mainloop()
Example #39
0
dx_dt = None
step = float()
error = float()
sigma = float()

# WINDOW INIT
root = tk.Tk()
root.title("Phase portrait")
root.geometry(SCREEN_WIDTH+"x"+SCREEN_HEIGHT)
root.resizable(False, False)

# WIDGETS
figure = plt.figure(figsize=(5, 5), dpi=100)
plot = figure.add_subplot(111)
canvas = FigureCanvasTkAgg(figure)
canvas.mpl_connect('button_press_event', onPlotClick)
move = NavigationToolbar2Tk(canvas, root)

vcmd = (root.register(validate))

sigma_label = tk.Label(text="σ", font=("roboto", 12))
sigma_input = tk.Entry(width=7, validate="all", validatecommand=(vcmd, '%P'))
sigma_input.insert(tk.END, "0")

error_label = tk.Label(text="Error", font="roboto-11")
error_input = tk.Entry(width=7, validate="all", validatecommand=(vcmd, '%P'))
error_input.insert(tk.END, "0")

step_label = tk.Label(text="Step", font="roboto-11")
step_input = tk.Entry(width=7, validate="all", validatecommand=(vcmd, '%P'))
step_input.insert(tk.END, "0")
Example #40
0
class SpectrumViewer(object, ttk.Frame):
    def __init__(self, master):
        ttk.Frame.__init__(self, master)
        self.root = master
        self._ms_file_name = None
        self.reader = None
        self.scan = None
        self.configure_toolbar()
        self.configure_canvas()
        self.configure_treeview()
        self.configure_display_row()
        self.populate()
        self.draw_plot()

    @property
    def ms_file_name(self):
        return self._ms_file_name

    @ms_file_name.setter
    def ms_file_name(self, value):
        if value not in (None, '') and os.path.exists(value):
            print("Loading %r" % value)
            self._ms_file_name = value
            self.reader = ms_deisotope.MSFileLoader(self.ms_file_name)
            self.populate()

    def set_ms_file(self, value, populate=True):
        self._ms_file_name = value
        self.reader = ms_deisotope.MSFileLoader(self.ms_file_name)
        if populate:
            self.populate()

    def select_ms_file(self):
        file_name = tkfiledialog.askopenfilename()
        if file_name is not None and file_name != '':
            self.ms_file_name = file_name

    def do_layout(self):
        self.grid(sticky=tk.N + tk.W + tk.E + tk.S)
        tk.Grid.rowconfigure(self, 0, weight=1)
        tk.Grid.columnconfigure(self, 0, weight=1)

    def configure_canvas(self):
        self.figure = Figure(dpi=100)
        self.canvas = FigureCanvasTkAgg(self.figure, master=self)
        self.axis = self.figure.add_subplot(111)
        self.canvas.show()
        canvas_widget = self.canvas.get_tk_widget()
        canvas_widget.grid(row=0, column=0, sticky=tk.N + tk.W + tk.E + tk.S)
        self.canvas_cursor = Cursor(self.axis, tk.StringVar(master=self.root))
        self.canvas.mpl_connect('motion_notify_event', self.canvas_cursor.mouse_move)
        self.span = SpanSelector(
            self.axis, self.zoom, 'horizontal', useblit=True,
            rectprops=dict(alpha=0.5, facecolor='red'))
        self.mz_span = None
        self.scan = None
        self.annotations = []
        self.canvas.show()

    def configure_toolbar(self):
        self.toolbar = tk.Menu(self)
        self.toolbar.add_command(label='Open', command=self.select_ms_file)
        self.toolbar.add_command(label='Interact', command=lambda: interactive_console(**{'self': self}))
        self.root.config(menu=self.toolbar)

    def _zoom_in(self, min_mz, max_mz):
        arrays = self.scan.arrays
        subset = arrays.between_mz(min_mz, max_mz).intensity
        if len(subset) > 0 and subset.max() > 0 and subset.min() < subset.max():
            most_intense = np.max(subset)
            y_cap = most_intense * 1.2
            self.mz_span = (min_mz, max_mz)
            self.axis.set_xlim(min_mz, max_mz)
            self.axis.set_ylim(0, y_cap)
            self.annotate_plot(min_mz, max_mz)
            self.figure.canvas.draw()

    def zoom(self, xmin, xmax):
        # If the bounds are not close, we're zooming in
        if not self.scan:
            return
        arrays = self.scan.arrays
        if (xmax - xmin) <= 1:
            min_peak = 0
            max_peak = len(arrays[0]) - 1
            self.mz_span = None
            xmin, xmax = arrays.mz[min_peak], arrays.mz[max_peak]
        self._zoom_in(xmin, xmax)

    def clear_annotations(self):
        for anno in self.annotations:
            try:
                anno.remove()
            except ValueError:
                break
        self.annotations = []

    def annotate_plot(self, min_mz=None, max_mz=None):
        self.clear_annotations()
        if min_mz is None:
            min_mz = 0
        if max_mz is None:
            max_mz = self.scan.arrays.mz[-1]
        subset = self.scan.deconvoluted_peak_set.between(min_mz, max_mz, use_mz=True)
        if not subset:
            return
        threshold = 0.0
        threshold_list = ([max(i.intensity for i in p.envelope) for p in subset])
        if threshold_list:
            threshold = np.mean(threshold_list)
        threshold_list = ([max(i.intensity for i in p.envelope) for p in subset
                           if max(i.intensity for i in p.envelope) > threshold])
        if threshold_list:
            threshold = np.mean(threshold_list)
        for peak in subset:
            if peak.intensity > threshold:
                label = '%0.2f (%d)' % (peak.neutral_mass, peak.charge)
                pt = max(peak.envelope, key=lambda x: x.intensity)
                y = pt.intensity * 1.05
                x = np.average(
                    [p.mz for p in peak.envelope],
                    weights=[p.intensity for p in peak.envelope])
                self.annotations.append(
                    self.axis.text(x, y, label, ha='center', clip_on=True, fontsize=10))

    def _process_scan(self):
        self.scan.pick_peaks(signal_to_noise_threshold=1.5)
        if self.scan.ms_level == 1:
            averagine_value = self.ms1_averagine_combobox.get()
            averagine_value = averagine_label_map[averagine_value]
            truncate_after = 0.95
            scorer = ms_deisotope.PenalizedMSDeconVFitter(20., 2.)
        else:
            averagine_value = self.msn_averagine_combobox.get()
            averagine_value = averagine_label_map[averagine_value]
            truncate_after = 0.8
            scorer = ms_deisotope.MSDeconVFitter(10.)
        self.scan.deconvolute(
            averagine=averagine_value,
            scorer=scorer,
            truncate_after=truncate_after)

    def draw_plot(self, scan=None, children=None):
        if children is None:
            children = []
        if scan is None or scan.arrays.mz.shape[0] == 0:
            return
        self.axis.clear()
        self.scan = scan
        self.children_scans = children
        if scan.ms_level == 1:
            if scan.arrays.mz.shape[0] > 1:
                self.scan = scan.average(3)
            self.scan = scan.denoise(4)
        self._process_scan()
        scan = self.scan
        if scan.is_profile:
            draw_raw(*scan.arrays, ax=self.axis, color='black', lw=0.75)
        self.axis.set_xlim(0, max(self.axis.get_xlim()))
        draw_peaklist(
            [i for p in scan.deconvoluted_peak_set for i in p.envelope],
            ax=self.axis, alpha=0.6, lw=0.5, color='orange')
        draw_peaklist(
            [p.envelope[0] for p in scan.deconvoluted_peak_set if p.envelope[0].intensity > 0],
            ax=self.axis, alpha=0.6, lw=1,
            color='red')
        draw_peaklist(
            [EnvelopePair(p.mz, p.intensity / len(self.envelope))
             for p in scan.deconvoluted_peak_set if not (p.envelope[0].intensity > 0)],
            ax=self.axis, alpha=0.6, lw=0.5,
            color='red', linestyle='--')
        # draw isolation window and instrument reported precursor
        if children:
            ylim = scan.arrays.intensity.max()
            for child in children:
                if child.isolation_window and not child.isolation_window.is_empty():
                    self.axis.vlines(
                        [child.isolation_window.lower_bound, child.isolation_window.upper_bound],
                        0, ylim, linestyle='--', color='skyblue', lw=0.5)
                self.axis.vlines(child.precursor_information.mz, 0, ylim,
                                 linestyle='--', color='black', lw=0.5)
        if self.scan.precursor_information:
            ylim = scan.arrays.intensity.max()
            self.axis.vlines(self.scan.precursor_information.mz, 0, ylim, linestyle='-.', color='orange')
        if self.mz_span is not None:
            self._zoom_in(*self.mz_span)
        else:
            self.annotate_plot(None, None)
        self.canvas.draw()

    def on_row_click(self, event):
        selection = self.treeview.focus()
        item = self.treeview.item(selection)
        index = item['text']

        if self.reader is not None:
            scan = self.reader.get_scan_by_index(index)
            if scan.ms_level == 1:
                bunch = next(self.reader.start_from_scan(scan.id))
                if not isinstance(bunch, ScanBunch):
                    children = []
                else:
                    children = bunch.products
            else:
                children = []
            self.draw_plot(scan, children)
        else:
            self.draw_plot(None)

    def configure_display_row(self):
        self.display_row = ttk.Frame(self)
        self.display_row.grid(row=1, column=0, sticky=tk.W + tk.S + tk.E)
        self.cursor_label = ttk.Label(self.display_row, text=" " * 20)
        self.cursor_label.grid(row=0, padx=(10, 10))

        def update_label(*args, **kwargs):
            self.cursor_label['text'] = self.canvas_cursor.binding.get()

        self.canvas_cursor.binding.trace('w', update_label)

        self.ms1_averagine_combobox = ttk.Combobox(self.display_row, values=[
            "peptide",
            "glycan",
            "glycopeptide",
            "heparan sulfate",
        ])
        self.ms1_averagine_combobox.set("glycopeptide")
        self.ms1_averagine_combobox_label = ttk.Label(self.display_row, text="MS1 Averagine:")
        self.ms1_averagine_combobox_label.grid(row=0, column=1, padx=(10, 0))
        self.ms1_averagine_combobox.grid(row=0, column=2, padx=(1, 10))

        self.msn_averagine_combobox = ttk.Combobox(self.display_row, values=[
            "peptide",
            "glycan",
            "glycopeptide",
            "heparan sulfate",
        ])
        self.msn_averagine_combobox.set("peptide")
        self.msn_averagine_combobox_label = ttk.Label(self.display_row, text="MSn Averagine:")
        self.msn_averagine_combobox_label.grid(row=0, column=3, padx=(10, 0))
        self.msn_averagine_combobox.grid(row=0, column=4, padx=(1, 10))

    def configure_treeview(self):
        self.treeview = ttk.Treeview(self)
        self.treeview['columns'] = ["id", "time", 'ms_level', 'precursor_mz', 'precursor_charge', 'activation']
        self.treeview.grid(row=2, column=0, sticky=tk.S + tk.W + tk.E + tk.N)

        self.treeview_scrollbar = ttk.Scrollbar(self, orient="vertical", command=self.treeview.yview)
        self.treeview_scrollbar.grid(row=2, column=0, sticky=tk.S + tk.E + tk.N)
        self.treeview.configure(yscrollcommand=self.treeview_scrollbar.set)

        self.treeview.heading('id', text="Scan ID")
        self.treeview.heading('#0', text='Index')
        self.treeview.heading("time", text='Time (min)')
        self.treeview.heading("ms_level", text='MS Level')
        self.treeview.heading("precursor_mz", text='Precursor M/Z')
        self.treeview.heading("precursor_charge", text='Precursor Z')
        self.treeview.heading("activation", text='Activation')
        self.treeview.column("#0", width=75)
        self.treeview.column("ms_level", width=75)
        self.treeview.column("time", width=75)
        self.treeview.column("precursor_mz", width=100)
        self.treeview.column("precursor_charge", width=100)
        self.treeview.bind("<<TreeviewSelect>>", self.on_row_click)

    def clear_treeview(self):
        children = self.treeview.get_children()
        if children:
            self.treeview.delete(*children)

    def _populate_range(self, start, stop):
        print("populate range", start, stop)
        scans = []
        ended = False
        for i in range(start, stop):
            try:
                scan = self.reader[i]
            except Exception:
                ended = True
                break
            if scan.index % 5000 == 0:
                print(scan)
            i = scan.index
            values = [scan.id, "%0.4f" % scan.scan_time, scan.ms_level]
            if scan.ms_level > 1:
                values.extend([scan.precursor_information.mz, scan.precursor_information.charge,
                               str(scan.activation)])
            else:
                values.extend(['-', '-', '-'])
            scans.append(values)
        for values in scans:
            self.treeview.insert('', 'end', values=values, text=i)
        if not ended:
            self.after(100, self._populate_range, stop, stop + 500)

    def populate(self, clear=True):
        if clear:
            self.clear_treeview()
        if self.reader is not None:
            self.reader.make_iterator(grouped=False)
            for scan in self.reader:
                if scan.index % 5000 == 0:
                    print(scan)
                i = scan.index
                values = [scan.id, "%0.4f" % scan.scan_time, scan.ms_level]
                if scan.ms_level > 1:
                    values.extend([scan.precursor_information.mz, scan.precursor_information.charge,
                                   str(scan.activation)])
                else:
                    values.extend(['-', '-', '-'])
                self.treeview.insert('', 'end', values=values, text=i)
            self.reader.reset()
Example #41
0
class SIAFViewer(object):
    instruments = [NIRCAM, NIRSPEC, NIRISS, MIRI, FGS]
    instrument_filepaths = None
    FILTER_SELECTED, FILTER_ALL = 1, 2

    def __init__(self, instrument_filepaths):
        self.root = Tk()
        self.root.title("SIAF Viewer")
        self.instrument_filepaths = instrument_filepaths

        def close_app():
            self.root.quit()
            self.root.destroy()

        self.root.protocol("WM_DELETE_WINDOW", close_app)
        self._construct()
        self.redraw()

    def start(self):
        self.root.mainloop()

    def redraw(self):
        mode = self.filter_behavior.get()
        show_labels = self.show_labels.get()
        self.ax.clear()
        # print("show_labels:", show_labels)
        if mode == self.FILTER_ALL:
            for instrument, siaf in self.siaf_lookup.items():
                for item in siaf.apernames:
                    if siaf[item].AperType == TRANSFORM:
                        continue
                    siaf[item].plot(frame='Tel', ax=self.ax, label=show_labels)
        elif mode == self.FILTER_SELECTED:
            # hacky/slow way to go from selected IDs back to SIAF instances
            for item in self.instrument_tree.selection():
                # print("item:", item)
                for instrument, siaf in self.siaf_lookup.items():
                    # print('item', item, 'instrument', instrument)
                    if item in siaf.apernames:
                        siaf[item].plot(frame='Tel', ax=self.ax, label=show_labels)
                        self.ax.scatter(siaf[item].V2Ref, siaf[item].V3Ref)
        self.ax.set_xlabel('V2 [arcsec]')
        self.ax.set_ylabel('V3 [arcsec]')
        self._canvas.show()

    def apply_filter(self):
        pattern = self.filter_value.get()
        # print("Pattern: {}".format(pattern))
        # pprint(self.instrument_tree.get_children(NIRCAM))

        def traverse_items(base=''):
            # recurse down the tree structure to find all matches
            matches = []
            for item in self.instrument_tree.get_children(base):
                if pattern in item:
                    # print("pattern:", pattern, "item:", item)
                    matches.append(item)
                matches.extend(traverse_items(item))
            return matches

        if pattern not in ('', '*'):
            self.filter_behavior.set(self.FILTER_SELECTED)
            self.instrument_tree.selection_remove(self.instrument_tree.selection())
            matches = traverse_items()
            # print('matches:', matches)
            self.instrument_tree.selection_set(' '.join(matches))
            map(self.instrument_tree.see, matches)
        else:
            self.clear_filter()

    def clear_filter(self):
        self.filter_value.set('')
        self.filter_behavior.set(self.FILTER_ALL)
        self.instrument_tree.selection_remove(self.instrument_tree.selection())
        self.redraw()

    def _construct_plot(self):
        # plot panel
        self.plotframe = ttk.Frame(self.main)
        self.plotframe.grid(column=1, row=0, sticky=(N, W, E, S))

        self.figure = Figure(figsize=(10, 5), dpi=72)
        self.ax = self.figure.add_subplot(1, 1, 1)
        self.ax.set_aspect('equal')
        self.figure.subplots_adjust(left=0.09, right=0.96)

        self._canvas = FigureCanvasTkAgg(self.figure, master=self.plotframe)
        self._canvas.show()
        self._canvas.get_tk_widget().pack(side=TOP, fill=BOTH, expand=1)

        self._toolbar = NavigationToolbar2TkAgg(self._canvas, self.plotframe)
        self._toolbar.update()
        self._canvas._tkcanvas.pack(side=TOP, fill=BOTH, expand=1)

        def on_key_event(event):
            # print('you pressed %s' % event.key)
            key_press_handler(event, self._canvas, self._toolbar)

        self._canvas.mpl_connect('key_press_event', on_key_event)

    def _construct_filter(self):
        # filter / tree panel
        self.filterframe = ttk.Frame(self.main)
        self.filterframe.grid(column=0, row=0, sticky=(N, W, E, S))
        self.filterframe.columnconfigure(1, weight=1)

        self.filter_value = StringVar()
        filter_label = ttk.Label(self.filterframe, text="Select by pattern:")
        filter_label.grid(column=0, row=0, sticky=(N, W))
        self.filter_entry = ttk.Entry(self.filterframe, textvariable=self.filter_value)
        self.filter_entry.grid(column=1, row=0, sticky=(N, W, E, S))

        filter_button = ttk.Button(self.filterframe, text="Filter", command=self.apply_filter)
        filter_button.grid(column=2, row=0, sticky=(N, E))

        clear_button = ttk.Button(self.filterframe, text="Clear", command=self.clear_filter)
        clear_button.grid(column=2, row=1, sticky=(N, E))


        filter_behavior_label = ttk.Label(self.filterframe, text="Show:")
        filter_behavior_label.grid(column=0, row=1)
        self.filter_behavior = IntVar(value=self.FILTER_ALL)
        self.filter_behavior.trace("w", lambda evt, x, y: self.redraw())
        radiobuttons_frame = ttk.Frame(self.filterframe)
        radiobuttons_frame.grid(column=1, row=1)

        self.filter_behavior_selected = ttk.Radiobutton(
            radiobuttons_frame,
            text='Selected',
            value=self.FILTER_SELECTED,
            variable=self.filter_behavior
        )
        self.filter_behavior_selected.grid(column=1, row=0)
        self.filter_behavior_all = ttk.Radiobutton(
            radiobuttons_frame,
            text='All',
            value=self.FILTER_ALL,
            variable=self.filter_behavior
        )
        self.filter_behavior_all.grid(column=3, row=0)

        self.instrument_tree = ttk.Treeview(self.filterframe)
        self.instrument_tree.grid(column=0, row=2, sticky=(N, W, E, S), columnspan=3)
        self._load_instruments()
        self.filterframe.rowconfigure(2, weight=1)

        info = ttk.Label(self.filterframe, text='Hold control and click to select multiple.\nHold shift and click to select ranges.')
        info.grid(column=0, row=3, columnspan=3)

        self.show_labels = BooleanVar(value=False)
        self.show_labels_checkbox = ttk.Checkbutton(
            self.filterframe,
            text='Show labels?',
            variable=self.show_labels,
            command=self.redraw,
            onvalue=True,
            offvalue=False
        )
        self.show_labels_checkbox.grid(column=0, row=4, columnspan=3)

    def _construct(self):
        self.root.minsize(width=1024, height=500)
        # ensure resizing happens:
        self.root.columnconfigure(0, weight=1)
        self.root.rowconfigure(0, weight=1)

        self.main = ttk.Frame(self.root)
        self.main.grid(column=0, row=0, sticky=(N, W, E, S))

        self._construct_plot()
        self._construct_filter()

        # massage the gui library a bit
        for child in self.main.winfo_children():
            child.grid_configure(padx=5, pady=5)
        self.main.columnconfigure(0, weight=1)
        self.main.columnconfigure(1, weight=1)
        self.main.rowconfigure(0, weight=1)

    def _load_instrument(self, instrument):
        siaf = SIAF(
            instr=instrument,
            filename=self.instrument_filepaths[instrument]
        )
        print("Loaded {} from {}".format(instrument, siaf.filename))
        return siaf

    def _load_instruments(self):
        self.siaf_lookup = {}

        # Every instrument is a unique snowflake, so load them one by one
        self.siaf_lookup[NIRCAM] = self._load_instrument(NIRCAM)
        # NIRCam
        #  - NRCA
        #    - NRCA1 .. 5
        #  - NRCB
        #    - NRCB1 .. 5

        self.instrument_tree.insert('', 'end', iid=NIRCAM, text=NIRCAM)
        self.instrument_tree.insert(NIRCAM, 'end', iid='NRCA', text='NRCA')
        a_segments = ('NRCA1', 'NRCA2', 'NRCA3', 'NRCA4', 'NRCA5')
        for segment in a_segments:
            self.instrument_tree.insert('NRCA', 'end', iid=segment, text=segment)

        self.instrument_tree.insert(NIRCAM, 'end', iid='NRCB', text='NRCB')
        b_segments = ('NRCB1', 'NRCB2', 'NRCB3', 'NRCB4', 'NRCB5')
        for segment in b_segments:
            self.instrument_tree.insert('NRCB', 'end', iid=segment, text=segment)

        for aper in sorted(self.siaf_lookup[NIRCAM].apernames):
            if 'NRCA' in aper and not 'NRCALL' in aper:
                if aper[:5] in a_segments:
                    self.instrument_tree.insert(aper[:5], 'end', iid=aper, text=aper)
                else:
                    self.instrument_tree.insert('NRCA', 'end', iid=aper, text=aper)
            elif 'NRCB' in aper:
                if aper[:5] in b_segments:
                    self.instrument_tree.insert(aper[:5], 'end', iid=aper, text=aper)
                else:
                    self.instrument_tree.insert('NRCB', 'end', iid=aper, text=aper)
            else:
                self.instrument_tree.insert(NIRCAM, 'end', iid=aper, text=aper)

        # MIRI
        #  - MIRIM
        #  - MIRIFU
        self.siaf_lookup[MIRI] = self._load_instrument(MIRI)
        self.instrument_tree.insert('', 'end', iid=MIRI, text=MIRI)
        self.instrument_tree.insert(MIRI, 'end', iid='MIRIFU', text='MIRIFU')
        self.instrument_tree.insert(MIRI, 'end', iid='MIRIM', text='MIRIM')

        for aper in sorted(self.siaf_lookup[MIRI].apernames):
            if 'MIRIFU' in aper:
                self.instrument_tree.insert('MIRIFU', 'end', iid=aper, text=aper)
            elif 'MIRIM' in aper:
                self.instrument_tree.insert('MIRIM', 'end', iid=aper, text=aper)

        # NIRSpec
        # (special: ignore AperType == TRANSFORM)
        self.siaf_lookup[NIRSPEC] = self._load_instrument(NIRSPEC)
        self.instrument_tree.insert('', 'end', iid=NIRSPEC, text=NIRSPEC)
        for aper in sorted(self.siaf_lookup[NIRSPEC].apernames):
            if self.siaf_lookup[NIRSPEC][aper].AperType == TRANSFORM:
                continue
            self.instrument_tree.insert(NIRSPEC, 'end', iid=aper, text=aper)

        for instrkey in [NIRISS, FGS]:
            self.siaf_lookup[instrkey] = self._load_instrument(instrkey)
            self.instrument_tree.insert('', 'end', iid=instrkey, text=instrkey)
            for aper in sorted(self.siaf_lookup[instrkey].apernames):
                self.instrument_tree.insert(instrkey, 'end', iid=aper, text=aper)

        self.instrument_tree.bind('<<TreeviewSelect>>', lambda evt: self.handle_selection())

    def handle_selection(self):
        if self.filter_behavior.get() == self.FILTER_ALL:
            return
        else:
            self.redraw()
Example #42
0
root = tkinter.Tk()
#root.wm_title("Embedding in Tk")

fig = Figure(figsize=(5, 4), dpi=100)
t = np.arange(0, 3, .01)
fig.add_subplot(111).plot(t, 2 * np.sin(2 * np.pi * t))

canvas = FigureCanvasTkAgg(fig, master=root)  # A tk.DrawingArea.
canvas.draw()
canvas.get_tk_widget().pack()  #side=tkinter.TOP, fill=tkinter.BOTH, expand=1)

#toolbar = NavigationToolbar2Tk(canvas, root)
#toolbar.update()
#canvas.get_tk_widget().pack(side=tkinter.TOP, fill=tkinter.BOTH, expand=1)
'''
def on_key_press(event):
    print("you pressed {}".format(event.key))
    key_press_handler(event, canvas, toolbar)


canvas.mpl_connect("key_press_event", on_key_press)


def _quit():
    root.quit()     # stops mainloop
    root.destroy()  # this is necessary on Windows to prevent
                    # Fatal Python Error: PyEval_RestoreThread: NULL tstate


button = tkinter.Button(master=root, text="Quit", command=_quit)
class MainMenu(Frame):
    def __init__(self, parent):
        Frame.__init__(self, parent)
        self.parent = parent
        self.parent.protocol("WM_DELETE_WINDOW", self.myQuit)
        self.parent.title("RT structure generator")

        BUTTON_WIDTH = 30
        TEXT_WIDTH = 10

        self.dicomVolume = dict() # { z : np.array } REDUCED to conform to xyz boundaries
        self.transformation = None
        self.ds = None
        
        self.topContainer = Frame(self, borderwidth=10)
        self.midContainer = Frame(self, borderwidth=10)
        self.bottomContainer = Frame(self, borderwidth=10)

        self.bottomContainer.pack(anchor=S, side=BOTTOM,fill=X, expand=1)
        self.topContainer.pack(fill=X, expand=1)
        self.midContainer.pack(fill=X, expand=1)

        self.useRelativePosContainer = Frame(self.midContainer)
        self.useClosedCurveLimiterContainer = Frame(self.midContainer)
        self.posEntryContainer = Frame(self.midContainer)
        self.deltaEntryContainer = Frame(self.midContainer)
        self.angleEntryContainer = Frame(self.midContainer)
        self.DBSCANepsContainer = Frame(self.midContainer)
        self.DBSCANMinPtsContainer = Frame(self.midContainer)

        self.useRelativePosContainer.pack(fill=X)
        self.useClosedCurveLimiterContainer.pack(fill=X)
        self.posEntryContainer.pack(fill=X)
        self.deltaEntryContainer.pack(fill=X)
        self.angleEntryContainer.pack(fill=X)
        
        self.useRelativePosVar = IntVar(value=0)
        self.useClosedCurveLimiterVar = IntVar(value=1)
        self.zPosVar = DoubleVar(value=0)
        self.zDeltaVar = DoubleVar(value=0.5)
        self.angleVar = DoubleVar(value=0)
        
        self.useRelativePosCheck = Checkbutton(self.useRelativePosContainer,
                                               text="Use relative positions? ", variable=self.useRelativePosVar)
        self.useRelativePosCheck.pack(anchor=W)

        Label(self.posEntryContainer, text="Slice position (z): ").pack(anchor=W)
        Entry(self.posEntryContainer, textvariable=self.zPosVar, width=TEXT_WIDTH).pack(side=LEFT)

        Label(self.deltaEntryContainer, text="Slice thickness (z): ").pack(anchor=W)
        Entry(self.deltaEntryContainer, textvariable=self.zDeltaVar, width=TEXT_WIDTH).pack(side=LEFT)

        Label(self.angleEntryContainer, text="Tilt angle (x-axis, ±180 deg): ").pack(anchor=W)
        Entry(self.angleEntryContainer, textvariable=self.angleVar, width=TEXT_WIDTH).pack(side=LEFT)

        self.buttonLoadCSV = Button(self.bottomContainer, text="Load CSV mesh (C)",
                                    command=self.commandLoadCSVMesh, width=BUTTON_WIDTH)
        self.buttonLoadCSV.pack(anchor=S, side=LEFT)
        
        self.buttonMakePlots = Button(self.bottomContainer, text="Make plots (Enter)",
                                      command=self.commandMakePlots, width=BUTTON_WIDTH)
        self.buttonMakePlots.pack(side=LEFT)
        
        self.buttonLoadDICOM = Button(self.bottomContainer, text="Load DICOM series (D)",
                                      command=self.commandLoadDICOM, width=BUTTON_WIDTH)
        self.buttonLoadDICOM.pack(side=LEFT)

        self.buttonQuit = Button(self.bottomContainer, text="Exit (Esc)",
                                 command=self.myQuit, width=BUTTON_WIDTH)
        self.buttonQuit.pack(side=LEFT)

        self.parent.bind("c", lambda event=None: self.buttonLoadCSV.invoke())
        self.parent.bind("d", lambda event=None: self.buttonLoadDICOM.invoke())
        self.parent.bind("<Return>", lambda event=None: self.buttonMakePlots.invoke())
        self.parent.bind("<Escape>", lambda event=None: self.buttonQuit.invoke())

        df = pd.read_csv("meshCSV/zz010440HUH44_1.2.826.0.1.3680043.2.968.3.8323329.27824.1530802493.162.csv")

        #x = df['FractionMeshPointsX'].values
        #y = df['FractionMeshPointsY'].values
        #z = df['FractionMeshPointsZ'].values

        x = df['PlanningMeshPointsX'].values
        y = df['PlanningMeshPointsY'].values
        z = df['PlanningMeshPointsZ'].values

        self.x0 = np.mean(x)
        self.y0 = np.mean(y)
        self.z0 = np.mean(z)

        x = x - self.x0
        y = y - self.y0
        z = z - self.z0

        self.xyz = np.array(list(zip(x,y,z)))

        self.pack()
        self.commandMakePlotsPlaceHolder()

    def myQuit(self):
        self.parent.destroy()
        plt.close("all")
        self.quit()

    def commandLoadCSVMesh(self):
        newfile = filedialog.askopenfilename(initialdir="meshCSV/")
        df = pd.read_csv(newfile)

        x = df['FractionMeshPointsX'].values
        y = df['FractionMeshPointsY'].values
        z = df['FractionMeshPointsZ'].values

        self.x0 = np.mean(x)
        self.y0 = np.mean(y)
        self.z0 = np.mean(z)

        x = x - self.x0
        y = y - self.y0
        z = z - self.z0

        self.xyz = np.array(list(zip(x,y,z)))

    def commandLoadDICOM(self):
        newfile = filedialog.askdirectory(initialdir="DICOM/")
        #boundaries = [[50*floor(np.min(self.xyz[:,k])/50), 50*ceil(np.max(self.xyz[:,k])/50)] for k in range(2)]
        boundariesMM = [[int(np.min(self.xyz[:,k]))-50, int(np.max(self.xyz[:,k]))+50] for k in range(2)]
        
        self.ds = None
        for root, dirs, files in os.walk(newfile):
            for file in files:
                if not "CT" in file: continue

                ds = pydicom.dcmread(f"{root}/{file}")
                if not self.ds:
                    self.ds = ds
                img = ds.pixel_array + ds.RescaleIntercept
                xy0 = [float(k) for k in ds.ImagePositionPatient] # Upper left corner
                dxy = float(ds.PixelSpacing[0])

                print("xy0", xy0)
                
                boundaries = [0,0]
                for dim in range(2):
                    boundaries[dim] = [int((boundariesMM[dim][0] - xy0[dim])/dxy), int((boundariesMM[dim][1] - xy0[dim])/dxy)]

                print("boundaries", boundaries)
                    
                self.dicomVolume[int(ds.SliceLocation)] = img[boundaries[1][0]:boundaries[1][1], boundaries[0][0]:boundaries[0][1]]

        """
        zList = np.array(zList)
        zList -= self.zPosVar.get()
        zListAbs = np.absolute(zList)
        zListAbsMin = zListAbs.argmin()

        for root, dirs, files in os.walk(newfile):
            file = files[zListAbsMin]
            if file:
                print(f"Choosing file {file} with z = {zList[zListAbsMin]} (want {self.zPosVar.get()})")
                self.ds = pydicom.dcmread(f"{root}/{file}")
                break

        self.img = self.ds.pixel_array + self.ds.RescaleIntercept
        """
        
        self.commandMakePlots()

    def commandMakePlotsPlaceHolder(self):
        self.fig, self.axs = plt.subplots(1,4, figsize=(20,5))
        self.canvas = FigureCanvasTkAgg(self.fig, master=self.topContainer)
        self.canvas.draw()
        self.canvas.get_tk_widget().pack(side=TOP, fill=BOTH, expand=1)
        self.canvas._tkcanvas.pack(side=TOP, fill=BOTH, expand=1)

        def onclick(event):
            self.zPosVar.set(event.ydata)
            self.commandMakePlots()
            
        def onscroll(event):
            self.angleVar.set(self.angleVar.get() + 5 * event.step)

            # New default slice position to account of rotation
            r = Rotation.from_euler("x", self.angleVar.get(), degrees=True)
            xyz = r.apply(self.xyz)
            self.zPosVar.set(np.mean(xyz[:,2]))
            
            self.commandMakePlots()
            
        cid = self.canvas.mpl_connect('button_press_event', onclick)
        cid2 = self.canvas.mpl_connect('scroll_event', onscroll)
    
    def commandMakePlots(self):
        for ax in self.axs:
            ax.clear()
        self.makePlot(self.axs)
        self.canvas.draw()

    def makePlot(self, axs):
        xyz = self.xyz.copy()
        
        if self.angleVar.get():
            r = Rotation.from_euler("x", self.angleVar.get(), degrees=True)
            xyz = r.apply(xyz)
            
        x = xyz[:,0]
        y = xyz[:,1]
        z = xyz[:,2]

        zPos = self.zPosVar.get()
        zDelta = self.zDeltaVar.get()

        zFilter1 = zPos - zDelta/2 < z
        zFilter2 = z < zPos + zDelta/2

        xFilter = x[zFilter1 & zFilter2]
        yFilter = y[zFilter1 & zFilter2]

        # SORT by angle
        xDC = xFilter - np.mean(xFilter)
        yDC = yFilter - np.mean(yFilter)
        angles = np.zeros(np.shape(xFilter), dtype=np.float64)

        for idx in range(len(xFilter)):
            angles[idx] = atan2(yDC[idx], xDC[idx])

        angleSortIdx = np.argsort(angles)
        anglesSorted = angles[angleSortIdx]
        xDCSort = xDC[angleSortIdx]
        yDCSort = yDC[angleSortIdx]

        xSort = xDCSort + np.mean(xFilter)
        ySort = yDCSort + np.mean(yFilter)

        step = pi/45
        anglesAveraged = np.arange(-pi, pi+step, step)
        
        xAveraged = np.zeros(np.shape(anglesAveraged))
        yAveraged = np.zeros(np.shape(anglesAveraged))
        idx = 0
        
        for angle in anglesAveraged:
            lowerFilter = anglesSorted > angle - step/2
            upperFilter = anglesSorted < angle + step/2
            
            if np.sum(xDCSort[lowerFilter & upperFilter]) == 0:
                continue

            xDCSortFilter = xDCSort[lowerFilter & upperFilter]
            yDCSortFilter = yDCSort[lowerFilter & upperFilter]
            rAngleMax = np.max(np.sqrt(xDCSortFilter**2 + yDCSortFilter**2))
            
            if isnan(rAngleMax):
                continue
            
            xAveraged[idx] = rAngleMax * cos(angle)
            yAveraged[idx] = rAngleMax * sin(angle)
            idx += 1

        xAveraged = xAveraged[:idx] + np.mean(xFilter)
        yAveraged = yAveraged[:idx] + np.mean(yFilter)
        
        xlabel = "x - x0 [mm]"
        ylabel = "y - y0 [mm]"
        zlabel = "z - z0 [mm]"

        if not self.useRelativePosVar.get():
            x += self.x0
            y += self.y0
            z += self.z0
            xSort += self.x0
            ySort += self.y0
            xAveraged += self.x0
            yAveraged += self.y0
            zPos += self.z0
            
            xlabel = "x [mm]"
            ylabel = "y [mm]"
            zlabel = "z [mm]"


        xAveragedExtra = np.append(xAveraged, xAveraged[0])
        yAveragedExtra = np.append(yAveraged, yAveraged[0])

        axs[0].scatter(x,y,alpha=0.1,marker=".")
        axs[0].plot(xAveragedExtra, yAveragedExtra, 'r-')
        axs[0].set_xlabel(xlabel)
        axs[0].set_ylabel(ylabel)
        axs[0].set_title(f"All points XY, rotated {self.angleVar.get()}° about X")

        axs[1].scatter(x,z,alpha=0.1,marker=".")
        axs[1].plot(axs[1].get_xlim(), [zPos, zPos], 'r-')
        axs[1].set_xlabel(xlabel)
        axs[1].set_ylabel(zlabel)
        axs[1].set_title(f"All points XZ, rotated {self.angleVar.get()}° about X \n(click to set Z)")
    
        axs[2].scatter(xSort, ySort, marker=",", label="All points")
        axs[2].plot(xAveragedExtra, yAveragedExtra, "r-", label="Angular average")
        
        axs[2].set_title(f"z = {zPos:.1f} ± {zDelta:.1f} mm with angular average")
        axs[2].set_xlabel(xlabel)
        axs[2].set_ylabel(ylabel)

        if np.sum(self.dicomVolume):
            zList = list(self.dicomVolume.keys())
            zList2 = [k-self.zPosVar.get() for k in zList]
            zListAbs = np.absolute(zList2)
            zToUse = zList[zListAbs.argmin()]

            img = self.dicomVolume[zToUse]

            extent = np.shape(img)[0] * self.ds.PixelSpacing[0]
            xiso = self.ds.ImagePositionPatient[0]
            yiso = self.ds.ImagePositionPatient[1]
            axs[3].imshow(img, cmap="gray")#, extent=(xiso, xiso+extent, extent+yiso, yiso))
            axs[3].plot(xAveragedExtra, yAveragedExtra, "r-", label="Angular average")
Example #44
0
class tkEMGplot(tk.Frame):
    def __init__(self, master=None, channel_num=32, period=100):
        tk.Frame.__init__(self,master)
        self.fig = None
        self.canvas = None
        self.toolbar = None
        self.channel_num = channel_num
        self.period = period
        self.databuffer = np.zeros((period,32))
        self.createWidgets()
    
    def createWidgets(self):
        self.fig = Figure(figsize=(5, 4))

        self.canvas = FigureCanvasTkAgg(self.fig, master=self.master)  # A tk.DrawingArea.
        self.canvas.draw()

        # pack_toolbar=False will make it easier to use a layout manager later on.
        self.toolbar = NavigationToolbar2Tk(self.canvas, self.master, pack_toolbar=False)
        self.toolbar.update()

        self.canvas.mpl_connect(
            "key_press_event", lambda event: print(f"you pressed {event.key}"))
        self.canvas.mpl_connect("key_press_event", key_press_handler)

        self.toolbar.pack(side=tk.TOP, fill=tk.X)
        self.canvas.get_tk_widget().pack(side=tk.TOP, fill=tk.BOTH, expand=1)

        
        # self.toolbar.grid(row = 1, column = 0)
        # self.canvas.get_tk_widget().grid(row = 0, column = 0)

        
        self.testbutton = tk.Button(self.master)
        self.testbutton["text"] = "Add one data point"
        self.testbutton["command"] = self.testaddDatapoint
        self.testbutton.pack(side=tk.LEFT, fill=tk.X, expand=False)

        self.testplot()

    def testaddDatapoint(self):
        new_data = ((np.random.rand(self.channel_num)-0.5) * 2) * 2.5
        self.addDatapoint(new_data)


    def testplot(self):
        self.fig.clear()
        t = np.arange(0, self.period, 1)
        datas = []

        ## Generate data for testing
        for i in range(self.channel_num):
            data = 2 * np.sin(2 * np.pi * t)+np.random.uniform(0,1,self.period)
            datas.append(data)
            # ax.spines['top'].set_visible(False)
            # ax.spines['right'].set_visible(False)
            # #ax.spines['bottom'].set_visible(False)
            # #ax.spines['left'].set_visible(False)
        
        self.graphplot(t, np.array(datas).T)


    def graphplot(self, t, datas):
        max_d, min_d = max(map(max,datas)), min(map(min,datas))
        range_d = round(abs(max_d) + abs(min_d))
        ax = self.fig.add_subplot(1,1,1)
        for i in range(self.channel_num):
            ax.plot(t, datas[:,i]+(range_d*i), label = ["Channel:" + str(i+1)])        ## potential future problem.
        
        self.fig.axes[0].set_yticks(np.arange(0, self.channel_num*range_d, range_d))

        labels = [0]*self.channel_num
        for i in range(self.channel_num):
            labels[i] = "Channel:" + str(i+1)
        self.fig.axes[0].set_yticklabels(labels)

        self.canvas.draw()

    def addDatapoint(self, new_datas):
        newlen = 1
        if newlen <= 0:
            return

        self.fig.clear(True) 
        self.databuffer[0:self.period - newlen,:] = self.databuffer[newlen:,:]
        self.databuffer[self.period - newlen:,:] = new_datas

        fz = 250
        t = np.arange(0, self.period/fz, 1/fz)
        self.graphplot(t, self.databuffer)
def video_stop():
    timerFrameDisplay.stop()
    #~ t.stop()

objShowFrame = ShowFrame()
objShowFrame.captureDevice = cap
objShowFrame.axes = axis1
objShowFrame.hIm = hIm

#Timer for frame
timerFrameDisplay = f2.canvas.new_timer(interval=0)
timerFrameDisplay.add_callback(objShowFrame.showFrame)

#Timer for video
#~ t = RepeatedTimer(0.01, video)

#Start and Stop Buttons
b1 = Button(master, text="Start", bg='white', command=video_start).place(x=50, y=600)
b2 = Button(master, text="Stop", bg='white', command=video_stop).place(x=400, y=600)
#~ master.mainloop()



#~ kShowFrameType = KShowFrameType(0)
#~ KShowFrameType(0)

#~ canvas1.mpl_connect('button_press_event', lambda e: ShowFrame().callback(e,kShowFrameType))
canvas1.mpl_connect('button_press_event', objShowFrame.changeFrame)
#~ kShowFrameType = 0

Example #46
0
class Roi(tk.Toplevel):
    def closing(self):
        if len(self.xx) <= 2:
            self.destroy()
            self.parent.grab_set()
            return

        self.parent.widgets['regions'].configure(state='normal')
        self.parent.roi_btn_show.configure(state='normal')
        self.parent.roi_btn_edit.configure(state='normal')
        self.parent.roi_btn_del.configure(state='normal')

        if self.parent.adding_roi:
            name = None
            while not isinstance(name, str):
                name = tkinter.simpledialog.askstring('Region name',
                                                      'Input name of region',
                                                      parent=self)
            self.parent.widgets['regions']['values'] = list(
                self.parent.widgets['regions']['values']) + [name]
            self.parent.widgets['regions'].set(name)
        else:
            name = self.parent.widgets['regions'].get()

        self.parent.regions[name] = {'x': self.xx, 'y': self.yy}

        self.parent.widgets['regions'].configure(state='readonly')
        self.destroy()
        self.parent.grab_set()

    def __init__(self, parent, *args, **kwargs):
        tk.Toplevel.__init__(self, *args, **kwargs)
        self.xx = []
        self.yy = []
        self.protocol('WM_DELETE_WINDOW', self.closing)
        self.wm_title("Region of Interest")
        self.grab_set()
        self.parent = parent

        self.f = matplotlib.figure.Figure(figsize=(12, 9.5))
        self.ax = self.f.add_subplot(111)

        self.canvas = FigureCanvasTkAgg(self.f, master=self)
        self.canvas.draw()
        self.canvas.get_tk_widget().pack(side='top', fill='both', expand=1)

        try:
            video = cv2.VideoCapture(
                parent.widgets['video_filename'].get().split(", ")[0])
            ret, frame = video.read()
        except Exception:
            ret = False
        if frame is None:
            parent.parent.log('Corrupted movie.')
            self.destroy()
            return
        if not ret:
            parent.parent.log('Select a movie first.')
            self.destroy()
            return
        try:
            start = int(parent.widgets['start_frame'].get())
            end = int(parent.widgets['limit_images_to'].get())
        except BaseException:
            start = 0
            end = video.get(cv2.CAP_PROP_FRAME_COUNT) - 1
        mid = int((end - start) // 2)
        video.set(cv2.CAP_PROP_POS_FRAMES, mid)
        ret, frame = video.read()
        if frame is None:
            parent.parent.log('Corrupted movie.')
            self.destroy()
            return
        self.ax.imshow(frame)
        axes = (0, frame.shape[1], frame.shape[0], 0)
        self.ax.axis(axes)
        poly = [1]

        def onclick(event):
            x, y = event.xdata, event.ydata
            if x is not None:
                self.xx.append(x)
                self.yy.append(y)
                self.ax.plot(self.xx, self.yy, '-xb')
                if len(self.xx) >= 3:
                    if poly[0] != 1:
                        poly[0].pop(0).remove()
                    poly[0] = self.ax.plot([self.xx[0], self.xx[-1]],
                                           [self.yy[0], self.yy[-1]], '--b')
                self.ax.axis(axes)
                self.canvas.draw()

        cid = self.canvas.mpl_connect('button_press_event', onclick)
Example #47
0
class PlotFrame(Frame):
    def __init__(self, master):
        Frame.__init__(self, master)
        
        self.figure = Figure(dpi=100)
        self.canvas = FigureCanvasTkAgg(self.figure,master=self)
        self.canvas.show()
        
        self.widget = self.canvas.get_tk_widget()
        self.widget.pack(side=TOP, expand=1, fill=BOTH)
        
        self.__plots = {}
        
        self.reset()
        
        self.bind("<Configure>", self._configure)
        
        self.config(background='red')
        
        self._scaledict = {}
        
        self._panmode = False
        self._xzoommode = False
        self._panstate = None
        
        self._padding = {}
        self._boundaries_changed = {}
        
        self.canvas.mpl_connect('button_press_event', self._button_pressed)
        self.canvas.mpl_connect('button_release_event', self._button_released)
        self.canvas.mpl_connect('motion_notify_event', self._motion)
        self.canvas.mpl_connect('scroll_event', self._scroll)

    def _scroll(self, event):
        if not event.inaxes:
            return
        
        for a in event.inaxes.get_children():
            z = 0
            if type(a) == YAxis and not self._xzoommode:
                self._scaledict[event.inaxes][1] = False
                z = 1 if (event.step > 0) else -1
            elif type(a) == XAxis and self._xzoommode:
                self._scaledict[event.inaxes][0] = False
                z = 1 if (event.step > 0) else -1
            
            if z != 0:
                a.zoom(z)
                self._boundaries_changed[event.inaxes] = True
                self._padding[event.inaxes] = [0, 0, 0, 0]
        
    def _button_pressed(self, event):
        if event.dblclick or not event.inaxes:
            if event.inaxes:
                self._panmode = False
                self._xzoommode = False
                self._panstate = None
                self._scaledict[event.inaxes] = [True, True]
                self._padding[event.inaxes] = [0, 0, 0, 0]
                self._boundaries_changed[event.inaxes] = False
                event.inaxes.set_ylim(auto=True)
                event.inaxes.set_xlim(auto=True)
                self.update()
            return
        
        self._panstate = [event.inaxes, event.x, event.y, 0, 0]
        
        if event.button == 1:
            self._panmode = True
        else:
            self._xzoommode = True
        
    def _button_released(self, event):
        self._xzoommode = False
        self._panmode = False
        self._panstate = None
    
    def _motion(self, event):
        if not self._panmode:
            return
        
        panx = False
        pany = False
        
        ps = self._panstate
        
        ps[3] += event.x - ps[1]
        ps[4] += event.y - ps[2]
        
        dx = ps[3]
        dy = ps[4]
        
        if abs(dx) > 5 and abs(dx) > abs(dy):
            panx = True
        elif abs(dy) > 5 and abs(dy) > abs(dx):
            pany = True
        
        for a in ps[0].get_children():
            p = 0
            if type(a) == YAxis and pany:
                self._scaledict[ps[0]][1] = False
                p = 1 if (dy < 0) else -1
            elif type(a) == XAxis and panx:
                self._scaledict[ps[0]][0] = False
                p = 1 if (dx < 0) else -1
            if p != 0:
                ps[3] = 0
                ps[4] = 0
                a.pan(p)
                self._boundaries_changed[ps[0]] = True
                self._padding[event.inaxes] = [0, 0, 0, 0]
        
        ps[1] = event.x
        ps[2] = event.y
        
        self._panstate = ps
        
    def update(self):
        for p in self.figure.axes:
            p.relim()
            p.autoscale_view(True, self._scaledict[p][0], self._scaledict[p][1])
                
            xi = p.get_xaxis().get_data_interval()
            yi = p.get_yaxis().get_data_interval()
            
            if self._boundaries_changed[p]:
                if not self._padding[p][0] and not self._scaledict[p][0]:
                    self._padding[p][0] = p.get_xlim()[0] - xi[0]
                if not self._padding[p][1] and not self._scaledict[p][0]:
                    self._padding[p][1] = p.get_xlim()[1] - xi[1]
                if not self._padding[p][2] and not self._scaledict[p][1]:
                    self._padding[p][2] = p.get_ylim()[0] - yi[0]
                if not self._padding[p][3] and not self._scaledict[p][1]:
                    self._padding[p][3] = p.get_ylim()[1] - yi[1]
            
            if self._padding[p][0] < 0:
                p.set_xlim(left=xi[0] + self._padding[p][0])
            
            if self._padding[p][1] > 0:
                p.set_xlim(right=xi[1] + self._padding[p][1])
            
            if self._padding[p][2] < 0:
                p.set_ylim(bottom=yi[0] + self._padding[p][2])
            
            if self._padding[p][3] > 0:
                p.set_ylim(top=yi[1] + self._padding[p][3])
            
        self.canvas.draw()
        
    
    def _configure(self, *args):
        width = self.winfo_width()
        height = self.winfo_height()
        
        w = width / 100.0
        h = height / 100.0
        
        self.figure.set_size_inches(w, h)
    
    def add_graph(self, graph, xdata=[], ydata=[]):
        if not graph.position in self.__plots:
            plt = self.figure.add_subplot(int(graph.position))
            plt.set_autoscale_on(True)
            self.__plots[graph.position] = plt
            plt.grid()
            self._scaledict[plt] = [True, True]
            self._padding[plt] = [0, 0, 0, 0]
            self._boundaries_changed[plt] = False
        
        graph.line, = self.__plots[graph.position].plot(xdata,ydata, graph.cfg)
        
        self.update_legends()
        
    def update_legends(self):
        lines = {}
        ids = {}
        for g in Graph.graphs.values():
            if not lines.has_key(g.position) or not ids.has_key(g.position):
                lines[g.position] = []
                ids[g.position] = []
            ids[g.position].append(g.identifier)
            lines[g.position].append(g.line)
        
        for p in lines.keys():
            if self.__plots.has_key(p):
                self.__plots[p].legend(lines[p], ids[p], 'upper left')
    
    def delete_graph(self, graph):
        graph.line.remove()
        for p in self.__plots.keys():
            if len(self.__plots[p].lines) == 0:
                self.figure.delaxes(self.__plots[p])
                del self.__plots[p]
            
    
    def update_graph(self, graph):
        xd = graph.line.get_xdata()
        yd = graph.line.get_ydata()
        self.delete_graph(graph)
        self.add_graph(graph)
        
    def clear_graph(self, graph):
        graph.line.remove()
        self.add_graph(graph, [], [])
    
    def reset(self):
        for p in self.figure.axes:
            self.figure.delaxes(p)
        self._scaledict = {}
        self.__plots = {}
        self._padding = {}
        self._boundaries_changed = {}
        self.figure.clf()
Example #48
0
    def add_fig_to_frame(self, fig, containerFrame, dict_frames, title):
        #Given a matplotlib figure, and a tk frame, setup the figure within the container frame.
        #Additionally, add this frame to a dict with the title as a key.

        #  This method controls matplotlib events internally.
        def onpick_any_pickable_object(event):
            """This is called upon any matplotlib element that has the pickable element being clicked
            Method first determines which type  object created event[ex: legend, line]
            Depending on object, execute click behavior.
            Current Behaviors:
                -if legend: toggle visibility of all lines corresponding to legend entry.
                -if line: output X,Y coordinates, line label, timestring based on X val
                    -if toggleGoto==True: open a the filtered txt doc of node in notepad++, at timestring of point clicked
            """
            event_fig = event.artist.figure
            artistLabel = event.artist.get_label()

            print('Click Event', artistLabel)
            ##if legend click
            if ('Legend_' in artistLabel):
                print('Toggling Visibility')
                strAfterLeg = artistLabel[7:]
                legline = event.artist
                for fig_axes in event_fig.get_axes():
                    for actualLine in fig_axes.get_lines():
                        actualLineLabel = actualLine.get_label()
                        if (actualLineLabel == strAfterLeg):
                            notCurVis = not actualLine.get_visible()
                            actualLine.set_visible(notCurVis)
                            if notCurVis:
                                legline.set_alpha(1.0)
                            else:
                                legline.set_alpha(0.2)
            else:
                line = event.artist
                xdata, ydata = line.get_data()
                ind = event.ind
                print('Line X,Y:', xdata[ind], ydata[ind])
                time_str = self.seconds_to_timestring(
                    xdata[ind[0]])  #prints 'HH:MM:SS:mmm'

                #using time string, search total_time-time_str-line_num list, for line_num.
                if (self.boolTog):  #open notepad++ @ line_num using cmd line.
                    #this code works, however needs to be made to take correct node dpl file, and find the line_num

                    #find wnw instance this line belongs to
                    ourWNW = None
                    for wnw in self.wnw_list:
                        if wnw.node_name in artistLabel:
                            ourWNW = wnw
                    offset = self.offsetList[ourWNW.node_num]
                    time_str = self.seconds_to_timestring(xdata[ind[0]] +
                                                          offset)
                    textfile_path = ourWNW.node_output_dir + os.sep + 'filtered_DSABLACK.txt'
                    line_num = self.find_line_num_of_time_str_in_filtered_file(
                        time_str, textfile_path)
                    notepad_path = ''
                    if os.path.isdir(r'C:\Program Files\Notepad++'):
                        notepad_path = r'C:\Program Files\Notepad++'
                    elif (os.path.isdir(r'C:\Program Files (x86)\Notepad++')):
                        notepad_path = r'C:\Program Files (x86)\Notepad++'
                    else:
                        print('notepad++ is not installed')
                        return

                    #textfile_path= r'C:\Users\Kyle\Documents\DSAStyleLog\ColinDSALogs\127Black.txt' #<-- TO BE MADE VARIABLE
                    #line_num= 12000 #<-- TO BE MADE VARIABLE
                    cmd_start = r'start cmd /k "cd '  #then notepad_path
                    cmd_middle = r' & notepad++.exe -n'  #then line number, then textfilepath,
                    full_open_txt_cmd = ('{}{}{}{} {} & exit \"'.format(
                        cmd_start, notepad_path, cmd_middle, str(line_num),
                        textfile_path))

                    print(full_open_txt_cmd)
                    if (line_num > 0
                        ):  #if str_time was not found, line_num would be -1.
                        os.system(full_open_txt_cmd)
                    else:
                        print('time str not found in file')
            event_fig.canvas.draw()
            return  #==========end onpick method

        thisFigFrame = tk.Frame(containerFrame)
        thisCanvas = FigureCanvasTkAgg(fig, thisFigFrame)
        thisCanvas.mpl_connect('pick_event', onpick_any_pickable_object)
        thisCanvas.draw()
        thisCanvas.get_tk_widget().pack(side=tk.BOTTOM,
                                        fill=tk.BOTH,
                                        expand=True)

        toolbar = NavigationToolbar2Tk(thisCanvas, thisFigFrame)
        toolbar.update()
        thisCanvas._tkcanvas.pack(side=tk.TOP, fill=tk.BOTH, expand=True)
        thisFigFrame.grid(row=0, column=0, sticky="nsew")
        dict_frames[title] = thisFigFrame
Example #49
0
class VisLayersApp():
    def __init__(self, master, snap, ppc = 20, dpi = 96, colors='coolwarm'):
        self.title = 'FFBPlog_{}'.format(snap.sess_index)
        print('[FFBP Viewer] Initializing viewer for {} ...'.format(self.title))
        self.master = master
        self.master.title(self.title)
        self.title_ast = '*** FFBPlog_{} ***'.format(snap.sess_index)
        # =========================== Figure preparation ===========================
        self.colors = colors
        self._ppc = ppc
        self._dpi = dpi
        self.bfs = self._set_bfs()
        self.snap = snap
        self.figure = self.create_fig()
        self.panelBoard = vl.prep_figure(self.snap, self.figure)
        figSize = self.figure.get_size_inches() * self._dpi

        # ============================= Parent Windows =============================
        # ---------------------- Figure and window parameteres----------------------

        self.figWidth, self.figHeight = [int(x) for x in figSize]
        self.maxWindWidth = 900
        self.maxWindHeight = 700
        w = min(self.figWidth, self.maxWindWidth)
        h = min(self.figHeight+125, self.maxWindHeight)
        self.master.geometry('{}x{}+0+0'.format(w + 20, h))
        self.master.update()

        # --------------------------------- Canvas ---------------------------------
        self.master.rowconfigure(0, weight=1)
        self.master.columnconfigure(0, weight=1)

        # Frames
        self.canvasFrame = ttk.Frame(master, width = w + 20, height = h + 20)
        self.canvasFrame.grid(row=0, column=0, columnspan = 2, sticky='nsew')
        self.canvasFrame.rowconfigure(0, weight=1)
        self.canvasFrame.columnconfigure(0, weight=1)

        # Widgets
        self.backCanvas = tk.Canvas(self.canvasFrame, scrollregion=(0, 0, w, h))
        self.backCanvas.grid(row=0, column=0, columnspan = 2, sticky='nsew')

        self.yScroll = tk.Scrollbar(self.canvasFrame,
                                    orient=tk.VERTICAL,
                                    command=self.backCanvas.yview)
        self.xScroll = tk.Scrollbar(self.canvasFrame,
                                    orient=tk.HORIZONTAL,
                                    command=self.backCanvas.xview)
        self.yScroll.grid(row=0, column=1, columnspan = 1, sticky='ns')
        self.xScroll.grid(row=1, column=0, columnspan = 1, sticky='ew')
        self.backCanvas.config(xscrollcommand=self.xScroll.set,
                               yscrollcommand=self.yScroll.set)

        self.figureRenderer = FigureCanvasTkAgg(self.figure, self.backCanvas)
        self.mplCanvasWidget = self.figureRenderer.get_tk_widget()
        self.mplCanvasWidget.grid(sticky = 'nsew')

        # self.colprefsButton = ttk.Button(self.master,
        #                                  text = 'Color preferences',
        #                                  command = self.onColorPrefs)
        # self.colprefsButton.grid(row=2, column=1, sticky='ew')

        # Integrate mpl and tk
        self.backCanvasWind = self.backCanvas.create_window(0, 0, window=self.mplCanvasWidget, anchor = 'nw')
        self.backCanvas.config(scrollregion=self.backCanvas.bbox(tk.ALL))
        self.figureRenderer.mpl_connect('pick_event', self.onPick)


        # ================================ CONTROLS ================================
        # Controls
        self.controlsFrame = ttk.Frame(master)

        # Info
        self.infoFrame = ttk.Frame(self.controlsFrame, width = 230, height = 115)
        self.epochSubFrame = ttk.Frame(self.infoFrame,
                                       width = 111,
                                       height = 105,
                                       relief = tk.GROOVE)
        self.cellSubFrame = ttk.Frame(self.infoFrame,
                                      width=111,
                                      height=105,
                                      relief = tk.GROOVE)
        self.tinySub = ttk.Frame(self.cellSubFrame,
                                 width = 40,
                                 height = 40,
                                 relief = tk.SUNKEN)
        # Slide and combobox
        self.widgetFrame = ttk.Frame(self.controlsFrame,
                                     width = 230,
                                     height = 95)

        # Progress bar and hyperparams
        self.hyperparamFrame = ttk.Frame(self.controlsFrame,
                                         width = 230,
                                         height = 15)

        # -------------------------------- tk Vars ---------------------------------
        self.patternVar = tk.StringVar()

        # -------------------------------- Widgets ---------------------------------
        # Selectors:
        self.patternSelector = ttk.Combobox(self.widgetFrame,
                                            textvariable = self.patternVar,
                                            values = list(snap.inp_names.keys()),
                                            )
        self.patternSelector.bind('<<ComboboxSelected>>', self.onCombo)
        self.patternSelector.current(0)

        self.epochSlider = ttk.Scale(self.widgetFrame,
                                     orient = tk.HORIZONTAL,
                                     length = 200,
                                     value =len(snap.epochs) - 1,
                                     from_ = 0,
                                     to =len(snap.epochs) - 1)

        self.epochSlider.set(str(len(snap.epochs) - 1)) # Set the slider value after epochValLabel is created


        # Buttons:
        self.updateButton = ttk.Button(self.widgetFrame,
                                       text='Update',
                                       command=self.onUpdate)

        self.zoominButton = ttk.Button(self.widgetFrame,
                                       text = 'Zoom in',
                                       command = lambda: self.changeSize(1))

        self.zoomoutButton = ttk.Button(self.widgetFrame,
                                        text='Zoom out',
                                        command=lambda: self.changeSize(-1))

        # Labels:
        #   epoch info
        self.epochValLabel = tk.Label(self.epochSubFrame,
                                      text = str(self._get_epoch(int(self.epochSlider.get()))),
                                      fg = 'black',
                                      font = ('Menlo', 30),
                                      justify = tk.CENTER)

        self.epochSlider.config(command = self.onSlide)

        self.epochLabel = ttk.Label(self.epochSubFrame,
                                    text = 'epoch',
                                    font = ('Menlo', 9),
                                    justify = tk.CENTER)

        #   draw cell onto tiny canvas
        self.tinyFig = plt.figure(self.snap.sess_index+100, figsize=(40 / 96, 40 / 96), facecolor='white')
        self.tinyRenderer = FigureCanvasTkAgg(self.tinyFig, self.tinySub)
        self.tinyCanvas = self.tinyRenderer.get_tk_widget()
        self.tinyRenderer.draw()

        self.cellWeight = ttk.Label(self.cellSubFrame,
                                    text = '-',
                                    font = ('Menlo', 9),
                                    justify = tk.CENTER)

        self.cellCoords = ttk.Label(self.cellSubFrame,
                                    text = 'r: - | c: -',
                                    font = ('Menlo', 9),
                                    justify = tk.CENTER)
        # hyperparam widgets
        self.hpFrame = ttk.Frame(self.hyperparamFrame,relief=tk.FLAT)
        hp = self.snap.hyperparams[-1]
        self.hpLabel = ttk.Label(self.hpFrame,
                                 text = 'lrate: {}\nmrate: {}\nerror function: {}\nbatch size: {}\ntrain mode: {}'.format(
            hp[0], hp[1], '{}'.format(hp[2]).split()[1], hp[3], 'p-train' if hp[4] else 's-train'),
                                 font = ('Menlo', 9),
                                 justify = tk.LEFT)

        # -------------------------------- Geometry --------------------------------

        # Controls
        self.controlsFrame.grid(row=1, column=0, columnspan = 2, sticky='nsew')

        # Info
        self.infoFrame.pack(side = tk.LEFT, fill = tk.BOTH, padx=10)

        # Epoch info
        self.epochSubFrame.pack(side = tk.LEFT, padx = 2, pady = 10)
        self.epochValLabel.place(relx = 0.50, rely = 0.45, anchor = tk.CENTER)
        self.epochLabel.place(relx = 0.50, rely = 0.75, anchor = tk.CENTER)

        # Cell info
        self.cellSubFrame.pack(side = tk.RIGHT, padx = 2, pady = 10)
        self.tinySub.place(relx = 0.50, rely = 0.40, anchor = tk.CENTER)
        self.tinyCanvas.pack()
        self.cellWeight.place(relx = 0.50, rely = 0.70, anchor = tk.CENTER)
        self.cellCoords.place(relx = 0.50, rely = 0.84, anchor = tk.CENTER)

        # Selectors
        self.widgetFrame.pack(side = tk.LEFT, fill = tk.X, pady=10)
        self.patternSelector.grid(row=0, column=0, columnspan=2, sticky='nsew')
        self.epochSlider.grid(row=1, column=0, columnspan=2, sticky='nsew')
        self.zoominButton.grid(row=2, column = 1, columnspan=1, sticky='nsew')
        self.zoomoutButton.grid(row=2, column = 0, columnspan=1, sticky='nsew')
        self.updateButton.grid(row=3, column = 0, columnspan=2, sticky='nsew')

        # Hyperparams and Progress Bar
        self.hyperparamFrame.pack(side = tk.LEFT, fill = tk.BOTH, pady=10, padx=10, ipadx = 10)
        self.hpFrame.pack(fill=tk.BOTH, expand=True)
        self.hpLabel.pack(side = tk.LEFT)

        # ================================ COLORS ==================================
        mpl_color_maps = (['BrBG', 'bwr', 'coolwarm', 'PiYG',
                           'PRGn', 'PuOr','RdBu', 'RdGy',
                           'RdYlBu', 'RdYlGn', 'Spectral',
                           'seismic', 'jet', 'rainbow', 'terrain'])

        self.colorsWindow = tk.Toplevel(self.master, )
        self.colorsWindow.title('Color Preferences')
        self.colorsWindow.resizable('False','False')
        self.colorsWindow.geometry('{}x{}+0+0'.format(350, 150))
        self.colorsWindow.withdraw()

        self.colorsFrame = ttk.Frame(self.colorsWindow)
        self.colorsFrame.place(relx=0.5, rely=0.5, anchor = tk.CENTER, width = 350, height = 150)
        self.colorsFrame.columnconfigure(0, weight = 1)
        self.colorsFrame.columnconfigure(1, weight = 1)
        self.colorsFrame.columnconfigure(2, weight=1)

        self.normMode = tk.StringVar()
        self.normMode.set('cus')

        self.colMap = tk.StringVar()

        self.absRadio = ttk.Radiobutton(self.colorsFrame, variable = self.normMode, value = 'abs', text = 'Absolute')
        self.relRadio = ttk.Radiobutton(self.colorsFrame, variable = self.normMode, value = 'rel', text = 'Relative')
        self.cusRadio = ttk.Radiobutton(self.colorsFrame, variable = self.normMode, value = 'cus', text = 'Custom')

        self.colmapLabel = ttk.Label(self.colorsFrame, text='color map', font=('Helvetica', 10))
        self.nrangeLabel = ttk.Label(self.colorsFrame, text='nrange', font=('Helvetica', 10))

        self.colmapCombo = ttk.Combobox(self.colorsFrame, textvariable = self.colMap, values = mpl_color_maps)
        self.colmapCombo.set(self.colors)
        self.nrangeEntry = tk.Entry(self.colorsFrame, width = 7)
        self.nrangeEntry.insert(0, '1')

        self.applyButton = ttk.Button(self.colorsFrame, text = 'Apply', command = self.onApply)
        self.helpButton = ttk.Button(self.colorsFrame, text = '?', command = self.onHelp)


        self.absRadio.grid(row = 0, column = 0, columnspan = 1, padx = 15, pady = 10, sticky = 'w')
        self.relRadio.grid(row = 0, column = 1, columnspan = 1, padx = 15, pady = 10, sticky = 'w')
        self.cusRadio.grid(row = 0, column = 2, columnspan = 1, padx = 15, pady = 10, sticky = 'w')

        self.colmapLabel.grid(row = 1, column = 0, columnspan = 2, padx = 17, sticky = 'ws')
        self.nrangeLabel.grid(row = 1, column = 2, columnspan = 1, padx = 15, sticky = 'ws')

        self.colmapCombo.grid(row = 2, column = 0, columnspan = 2, padx = 15, sticky = 'ews')
        self.nrangeEntry.grid(row = 2, column = 2, columnspan = 1)

        self.applyButton.grid(row = 3, column = 1, columnspan = 2, padx = 15, pady = 20, sticky = 'nesw')
        self.helpButton.grid(row = 3, column = 0, columnspan = 1, padx = 15, pady = 20, sticky = 'w')

        # ============================ Initial Figure ============================
        self._label_groups = vl.annotate(self.snap, self.panelBoard, self._set_bfs())
        self._labels_on = True
        self._plotLatest()

        # ============================== PROTOCOLS ===============================
        self.master.protocol('WM_DELETE_WINDOW', self.onMasterX)
        self.colorsWindow.protocol('WM_DELETE_WINDOW', self.onColorsX)

        self.master.lift()
        self.master.minsize(460, 125)
        self.master.maxsize(self.master.winfo_width(), self.master.winfo_height())
        self._hang(0)

    def create_fig(self):
        # Create a figure
        max_width = max([l.sender[1] for l in self.snap.main.values()])
        width_cells = ((max_width + 9) * 2)
        width_pixels = width_cells * self._ppc
        width_inches = width_pixels / self._dpi

        network_size = self.snap.num_units
        height_cells = network_size + (6 * self.snap.num_layers)
        height_pixels = height_cells * self._ppc
        height_inches = height_pixels / self._dpi
        fig = plt.figure(self.snap.sess_index, figsize=(width_inches, height_inches), facecolor='w', dpi=self._dpi)
        return fig

    def onUpdate(self):
        epoch_ind = int(self.epochSlider.get())
        key = self.patternSelector.get()
        if key in self.snap.inp_names.keys():
            self.panelBoard.clear()
            ind_map = list(self.snap.inp_names.keys())
            pattern_ind = ind_map.index(key)
            vl.draw_all_layers(self.snap, self.panelBoard, epoch_ind, pattern_ind, colmap=self.colors)
            self._label_groups = vl.annotate(self.snap, self.panelBoard, self._set_bfs())
            self.figureRenderer.draw()
            self._hang(0)
        else:
            messagebox.showinfo(title='Wrong selection',
                                message='No such pattern. Please select a pattern from the list')

    def changeSize(self, direction):
        oldSize_inches = self.figure.get_size_inches()
        oldSize_pixels = [s_i * self._dpi for s_i in oldSize_inches]
        Size_cells = [s_p / self._ppc for s_p in oldSize_pixels]
        self._ppc += 10 * direction
        newSize_pixels = [s_c * self._ppc for s_c in Size_cells]
        newSize_inches = [s_p / self._dpi for s_p in newSize_pixels]
        self.figure.set_size_inches(newSize_inches)
        nW, nH = newSize_pixels[0], newSize_pixels[1]
        self.canvasFrame.config(width = nW, height = nH)
        self.mplCanvasWidget.config(width = nW, height = nH)
        self.backCanvas.itemconfigure(self.backCanvasWind, width=nW, height=nH)
        self.backCanvas.config(scrollregion=self.backCanvas.bbox(tk.ALL), width=nW, height=nH)
        self.checkPPC()
        if self._labels_on:
            vl.labels_off(self._label_groups)
            self._label_groups = vl.annotate(self.snap, self.panelBoard, self._set_bfs())
            self.figureRenderer.draw()
        self.figure.canvas.draw()
        self.figWidth = int(nW)
        self.figHeight = int(nH)

        # Adjust master window size to figure size, so that regions outside figure are always hidden
        if direction < 0 and self.figWidth < self.master.winfo_width():
            xx,yy = self.master.winfo_x(), self.master.winfo_y()
            self.master.geometry('{}x{}+{}+{}'.format(
                min(self.figWidth, self.maxWindWidth) + 20,
                min(self.figHeight + 125, self.maxWindHeight),
                xx,
                yy))
        self.master.maxsize(min(self.figWidth, self.maxWindWidth) + 20, min(self.figHeight + 125, self.maxWindHeight))

    def checkPPC(self):
        upperlim = 60
        lowerlim = 10
        if self._ppc <= lowerlim:
            self.zoomoutButton.state(['disabled'])
        elif self._ppc >= upperlim:
            self.zoominButton.state(['disabled'])
        else:
            if self.zoomoutButton.instate(['disabled']): self.zoomoutButton.state(['!disabled'])
            if self.zoominButton.instate(['disabled']): self.zoominButton.state(['!disabled'])

    def onCombo(self, val):
        self._hang(1)

    def onPick(self, event):
        thiscell = event.artist
        value = thiscell.get_cellval()
        r, c = thiscell.get_inds()
        weight = str(round(value, 4))
        rc = 'r: {} | c: {}'.format(r,c)
        self.cellCoords.config(text = rc)
        self.cellWeight.config(text = weight)
        self.tinyFig.set_facecolor(vl.v2c(value, self.colors, 4))
        self.tinyRenderer.draw()

    def onSlide(self, val):
        val = float(val)
        self.epochValLabel.config(text = str(self._get_epoch(val)))
        self._hang(1)
        hp = self.snap.hyperparams[int(val)]
        self.hpLabel.config(text = 'lrate: {}\nmrate: {}\nerror function: {}\nbatch size: {}\ntrain mode: {}'.format(
            hp[0], hp[1], '{}'.format(hp[2]).split()[1], hp[3], 'p-train' if hp[4] else 's-train'))

        # # find inputs that were presented on the given epoch and update the combobox
        # pattern_list = []
        # for k,v in self.snap.inp_names.items():
        #     for r in self.snap.inp_vects[int(val)]:
        #         if np.all(np.array(v)==r):
        #             pattern_list.append(k)
        # self.patternSelector['values'] = pattern_list
        # self.patternSelector.current(0)

    def onApply(self):
        print('Applying changes')
        print('Normalization scope: {}'.format(self.normMode.get()))
        print('Normalization range: {}'.format(self.nrangeEntry.get()))
        print('Color map: {}'.format(self.colmapCombo.get()))
        self.colorsWindow.withdraw()

    def onHelp(self):
        messagebox.showinfo('Need some explanation?',
                            'Too bad, we are still working on it. '
                            'Try playing around with the preferences '
                            'to see what\'s going on :)')

    # def onColorPrefs(self):
    #     if self.colorsWindow.state() == 'withdrawn': self.colorsWindow.state('normal')
    #     self.colorsWindow.lift()

    def onMasterX(self):
        self._sleep()

    def onColorsX(self):
        positive = messagebox.askyesno('O_o', 'Do you want to apply changes')
        if positive:
            self.onApply()
        self.colorsWindow.withdraw()

    def catch_up(self, snap):
        self.snap = snap
        self._plotLatest()
        self._hang(0)
        self.master.state('normal')
        self.master.lift()

    def _hang(self, b):
        if b:
            self.epochValLabel.config(fg='#ABABAB')
            self.master.title(self.title_ast)
        else:
            self.epochValLabel.config(fg='black')
            self.master.title(self.title)

    def _sleep(self):
        self.master.withdraw()
        self.colorsWindow.withdraw()
        self.master.quit()

    def _plotLatest(self):
        latest_epoch_ind = len(self.snap.epochs) - 1
        vl.draw_all_layers(self.snap,
                           self.panelBoard,
                           latest_epoch_ind,
                           0)
        self.epochSlider.config(to = float(latest_epoch_ind))
        self.epochSlider.set(latest_epoch_ind)
        self.figureRenderer.draw()

    def _get_epoch(self, slider_value):
        return self.snap.epochs[int(slider_value)]

    def _get_pattern(self):
        try:
            ind = self.snap.inp_names.index(self.patternVar.get())
            print('You selected pattern {}'.format(ind))
        except ValueError:
            print('No such pattern')

    def _set_bfs(self, scale = 0.4):
        return self._ppc * scale

    def destroy(self):
        self.master.withdraw()
        self.master.quit()
        self.master.destroy()
Example #50
0
class GUI():
    def __init__(self,root,song):
        # given parameters
        self.root = root
        self.song = song

        # main window
        self.root.title("Song segment player")
        self.root.iconbitmap(r'Images/icon.ico')
        self.root.configure(background='white')

        # menubar
        self.menubar = Menu(self.root)
        self.filemenu = Menu(self.menubar,tearoff=0)
        self.filemenu.add_command(label="Open",
                                  command=lambda:b.openSong(self))
        self.menubar.add_cascade(label="File",menu=self.filemenu)

        # images for buttons
        self.segmentIm = PhotoImage(file=r'Images/SegmentB.png')
        self.repSegIm = PhotoImage(file=r'Images/Repeat.png')
        self.playIm = PhotoImage(file=r'Images/PlayB.png')
        self.pauseIm = PhotoImage(file=r'Images/PauseB.png')
        self.stopIm = PhotoImage(file=r'Images/StopB.png')
        self.ffIm = PhotoImage(file=r'Images/ffB.png')
        self.rwIm = PhotoImage(file=r'Images/rwB.png')
        self.fullSpeedIm = PhotoImage(file=r'Images/FullSpeedB.png')
        self.halfSpeedIm = PhotoImage(file=r'Images/HalfSpeedB.png')
        self.sliderIm = PhotoImage(file=r'Images/SliderB.png')
        self.cursorIm = PhotoImage(file=r'Images/Cursor.png')
        self.magPlusIm = PhotoImage(file=r'Images/MagPlus.png')
        self.magMinusIm = PhotoImage(file=r'Images/MagMinus.png')

        # making buttons
        self.segmentB = Button(image=self.segmentIm,
                               command=lambda:b.playSeg(self.song))
        self.repSegB = Button(image=self.repSegIm,
                                 command=lambda:b.repeatSeg(self.song,self.repSegB))
        self.playB = Button(image=self.playIm,
                            command=lambda:b.playStream(self.song))
        self.pauseB = Button(image=self.pauseIm,
                             command=lambda:b.pauseStream(self.song))
        self.stopB = Button(image=self.stopIm,
                            command=lambda:b.stopStream(self.song))
        self.ffB = Button(image=self.ffIm,
                          command=lambda:b.ffStream(self.song))
        self.rwB = Button(image=self.rwIm,
                          command=lambda:b.rwStream(self.song))
        self.fullSpeedB = Button(image=self.fullSpeedIm)
        self.halfSpeedB = Button(image=self.halfSpeedIm)
        # making radio buttons
        self.CLICKMODE = StringVar(value="slide")
        self.sliderB = Radiobutton(
            self.root,
            image=self.sliderIm,
            variable=self.CLICKMODE,
            value='slide',
            indicatoron=0)
        self.cursorB = Radiobutton(
            self.root,
            image=self.cursorIm,
            variable=self.CLICKMODE,
            value='curse',
            indicatoron=0)
        self.magPlusB = Radiobutton(
            self.root,
            image=self.magPlusIm,
            variable=self.CLICKMODE,
            value='mag+',
            indicatoron=0)
        self.magMinusB = Radiobutton(
            self.root,
            image=self.magMinusIm,
            variable=self.CLICKMODE,
            value='mag-',
            indicatoron=0)

        # setting button parameters
        self.allButts = [self.segmentB,self.repSegB,self.playB,self.stopB,
                         self.pauseB,self.ffB,self.rwB,self.fullSpeedB,
                         self.halfSpeedB,self.sliderB,self.cursorB,
                         self.magPlusB,self.magMinusB]
        [butt.config(bg='white') for butt in self.allButts]
        # disable all buttons to start with
        [butt.config(state='disabled') for butt in self.allButts]
        self.sliderB.config(state='normal')

        # placing buttons
        rowc = 3
        self.segmentB.grid(row=0,column=2)
        self.repSegB.grid(row=0,column=3)
        self.playB.grid(row=rowc,column=3)
        self.pauseB.grid(row=rowc,column=2)
        self.stopB.grid(row=rowc,column=1)
        self.ffB.grid(row=rowc,column=4)
        self.rwB.grid(row=rowc,column=0)
        self.fullSpeedB.grid(row=0,column=4,columnspan=3)
        self.halfSpeedB.grid(row=0,column=5,columnspan=3)
        self.sliderB.grid(row=2,column=0)
        self.cursorB.grid(row=2,column=1)
        self.magPlusB.grid(row=2,column=2)
        self.magMinusB.grid(row=2,column=3)

        # display song title
        if self.song.songname:
            t = self.song.songname[0:-4]
        else:
            t = ''
        self.songTitleL = Label(self.root,text=t,bg='white')
        self.songTitleL.grid(row=0,column=0)

        # making figure canvas
        self.canvas = FigureCanvasTkAgg(self.song.fig,master=self.root)
        self.canvas.draw()
        self.canvas.get_tk_widget().grid(row=rowc-2,column=0,columnspan=5)

        # connecting canvas to monitor events
        self.cidpress = self.canvas.mpl_connect(
            'button_press_event',
            lambda event:e.on_press(event,self.song,self.CLICKMODE))
        self.cidrelease = self.canvas.mpl_connect(
            'button_release_event',
            lambda event:e.on_release(event,self.song))
        self.cidmotion = self.canvas.mpl_connect(
            'motion_notify_event',
            lambda event:e.on_motion(event,self.song))

        self.root.bind('<space>', lambda event:b.playPauseStream(self.song))
        self.root.bind('<Return>', lambda event:b.playSeg(self.song))

        # set cursor updating
        self.root.after(10000,lambda: e.updateCursor(self))

        # insert menu bar
        self.root.config(menu=self.menubar)

        # closing behaviour
        self.root.protocol("WM_DELETE_WINDOW",self.on_closing)



    def on_closing(self):
        self.canvas.mpl_disconnect(self.cidpress)
        self.canvas.mpl_disconnect(self.cidrelease)
        self.canvas.mpl_disconnect(self.cidmotion)
        self.root.destroy()
        self.song.wf.close()
        self.song.stream.close()
        self.song.p.terminate()
        [os.remove(s) for s in self.song.createdFilepaths]

    def updateCursor(self):
        if self.song.wf:
            pos = self.song.wf.tell()/self.song.RATE
            self.song.cursor[0].set_x(pos)
            self.canvas.draw()
        self.root.after(250,self.updateCursor)
# window
fen = Tk()
fen.title('Hello')
# create the grid
SIZE = 40
grid = np.zeros((SIZE, SIZE))
# grid[4, 4] = 3
U, V = np.gradient(-grid)
fig = plt.figure('hehehe')
im = plt.imshow(grid, cmap='Greys', interpolation='none')
# plt.hold(True)
ve = plt.quiver(-V, U, color='red', scale=2)

# Canvas
fig_can = FigureCanvasTkAgg(fig, master=fen)
fig_can.mpl_connect('button_press_event', onclick)
fig_can.get_tk_widget().grid(row=0, column=0, rowspan=3)

# Label
info_max = Label(fen, text='Max: 0')
info_max.grid(row=0, column=1)
info_min = Label(fen, text='Min: 0 ')
info_min.grid(row=1, column=1)
# Tick
gaussian_interpolation = IntVar()
check_interpolation = Checkbutton(
    fen, text='Interpolation', variable=gaussian_interpolation,
    command=update_interpolation)
check_interpolation.grid(row=2, column=1)

# Button
Example #52
0
def Load_CSV(disable_widgets, enable_widgets):

    global array, canvas
    for widget in disable_widgets:
        widget.config(state="disabled")
    for widget in enable_widgets:
        widget.config(state="normal")

    file_type = (option_menu_title.get())[-4:]

    if file_type == '.csv':
        CSV_name = option_menu_title.get()
        CSV_path = join('Data', CSV_name)
        root.title(('PPP: {0}').format(CSV_name))
        file = open(CSV_path)
        csv_reader = csv.reader(file)
        lines = 0  #count lines in the chosen csv
        for row in csv_reader:
            lines += 1
        ref.lines = lines
        array = np.zeros((lines, 2))
        ref.array_length = lines
        #make empty array
        file = open(
            CSV_path
        )  #for some reason i need to repeate this bit otherwise it wont work WHO KNOWS
        reader = csv.reader(file)

        for index, row in enumerate(reader):  #populate array
            array[index, 0] = float(row[0])
            array[index, 1] = float(row[1])

    elif file_type == '.txt':
        TXT_name = option_menu_title.get()
        TXT_path = join('Data', TXT_name)
        text_file = open(TXT_path, 'r')
        reader = text_file.readlines()

        array = np.zeros((len(reader), 2))

        for index, line in enumerate(reader):
            # print(index)
            # print(line[:(line.find('\t'))])
            # print(line[(line.find('\t')):])
            # print('')
            x, y = float(line[:(line.find('\t'))]), float(
                line[(line.find('\t')):])
            array[index, 0] = float(x)
            array[index, 1] = float(y)

        ref.lines = len(reader)  #fix this to be the number of lines
    fig = pl.Figure(figsize=(16, 9))
    plot1 = fig.add_subplot(111)
    plot1.plot(array[:, 0], array[:, 1])
    canvas = FigureCanvasTkAgg(fig, master=root)
    canvas.draw()
    toolbar = NavigationToolbar2Tk(canvas, root)
    toolbar.update()
    canvas.get_tk_widget().place(x=0, y=7)

    over_view = pl.figure()
    pl.xlabel('ADC')
    pl.ylabel('Entries')
    pl.title('SiPM Output')
    pl.plot(array[:, 0], array[:, 1])

    pl.xlim(min(array[:, 0]), max(array[:, 0]) / 2)
    pl.rcParams['figure.figsize'] = 16, 9
    pl.savefig('Saved/fig0.png')

    pl.close(over_view)

    def callback(event):
        x = int(event.xdata)
        y = int(event.ydata)
        most_recent_coords.set(('Current Coords:\n' + str(x) + ', ' + str(y)))
        ref.lastest_coords = (x, y)

    canvas.mpl_connect('button_press_event', callback)
                y_pts.append(y)
                
                # add horizontal line and point at mouse position
                dyn.append(ax.hlines(y_pts, -1850, -100))
                dyn.append(ax.scatter(x_pts, y_pts, c = 'black', s = 10))

                # when a second point is added, connect horizontal lines with vertical lines and display vertical distance
                if len(x_pts) >= 2:
                    dyn.append(ax.vlines(x = (x_pts[0]+x_pts[1])/2, ymin = y_pts[0], ymax = y_pts[1]))
                    props = dict(boxstyle='round', facecolor='grey', alpha=0.5)
                    peak_current = y_pts[1]-y_pts[0]
                    dyn.append(ax.text(0.05, 0.95, '{:.3f} nA'.format(peak_current),
                                        transform=ax.transAxes, fontsize=14,verticalalignment='top', bbox=props))
        canvas.draw()

canvas.mpl_connect('button_press_event', onpick)

#################################################################################
# Manage Keyboard inpput

def on_key_press(event):

    #Matplotlib Toolbar keybindings:
    key_press_handler(event, canvas, toolbar)


canvas.get_tk_widget().bind("<Left>", previous_file)
canvas.get_tk_widget().bind("<Right>", next_file)
canvas.get_tk_widget().bind("<Delete>", delete)
canvas.mpl_connect("key_press_event", on_key_press)
class DataPanelGUI(object):

    ##
    # @param [in] dataFigSize (w, h) in inches for the data plots figure assuming dpi=72
    def __init__(self, master, cd, dataFigSize=(13, 12.5)):
        self.mode = 0
        self.master = master
        self.cd = cd
        self.nAdcCh = self.cd.nAdcCh
        self.nSdmCh = self.cd.nCh
        self.adcSdmCycRatio = self.cd.adcSdmCycRatio

        self.master.wm_title("Topmetal-S 1mm version x19 array data")
        # appropriate quitting
        self.master.wm_protocol("WM_DELETE_WINDOW", self.quit)
        self.autoSaveData = False
        self.sampleID = 0

        ######## Control frame #########
        self.nVolts = self.cd.nVolts
        self.nCh = self.cd.nCh

        self.controlFrame = tk.Frame(self.master)
        self.controlFrame.pack(side=tk.LEFT)
        button1 = tk.Button(master=self.controlFrame,
                            text='Save data',
                            command=self.save_data0)
        button1.pack(side=tk.TOP, fill=tk.X)

        button = tk.Button(master=self.controlFrame,
                           text='Re-sample',
                           command=self.re_sample)
        button.pack(side=tk.BOTTOM, fill=tk.X)
        button2 = tk.Button(master=self.controlFrame,
                            text='Auto-update',
                            command=self.auto_update)
        button2.pack(side=tk.TOP, fill=tk.X)

        # frame for selecting a sensor to operate on
        self.sensorsFrame = tk.Frame(self.controlFrame)
        self.sensorsFrame.pack(side=tk.TOP)
        # sensor location approximated on a grid (row, col)
        self.sensorLocOnGrid = {
            0: [4, 2],
            1: [2, 2],
            2: [3, 1],
            3: [5, 1],
            4: [6, 2],
            5: [5, 3],
            6: [3, 3],
            7: [0, 2],
            8: [1, 1],
            9: [2, 0],
            10: [4, 0],
            11: [6, 0],
            12: [7, 1],
            13: [8, 2],
            14: [7, 3],
            15: [6, 4],
            16: [4, 4],
            17: [2, 4],
            18: [1, 3]
        }
        self.sensorSelVar = tk.IntVar()
        self.sensorSelRadioButtons = [
            tk.Radiobutton(self.sensorsFrame,
                           text="{:d}".format(i),
                           variable=self.sensorSelVar,
                           value=i,
                           command=self.select_current_sensor)
            for i in xrange(self.nCh)
        ]
        for i in xrange(len(self.sensorSelRadioButtons)):
            b = self.sensorSelRadioButtons[i]
            b.grid(row=self.sensorLocOnGrid[i][0],
                   column=self.sensorLocOnGrid[i][1])

        # frame for controls
        self.voltagesFrame = tk.Frame(self.controlFrame)
        self.voltagesFrame.pack(side=tk.BOTTOM)

        # GUI widgets
        self.voltsNameLabels = [
            tk.Label(self.voltagesFrame, text=self.cd.voltsNames[i])
            for i in xrange(self.nVolts)
        ]
        self.voltsILabels = [
            tk.Label(self.voltagesFrame, font="Courier 10", text="0.0")
            for i in xrange(self.nVolts)
        ]

        self.voltsOutputLabels = [
            tk.Label(self.voltagesFrame, font="Courier 10", text="0.0")
            for i in xrange(self.nVolts)
        ]

        self.voltsSetVars = [tk.DoubleVar() for i in xrange(self.nVolts)]
        for i in xrange(self.nVolts):
            self.voltsSetVars[i].set(self.cd.inputVs[i])
        self.voltsSetEntries = [
            tk.Spinbox(self.voltagesFrame,
                       width=8,
                       justify=tk.RIGHT,
                       textvariable=self.voltsSetVars[i],
                       from_=0.0,
                       to=3.3,
                       increment=0.001,
                       format_="%6.4f",
                       command=self.set_voltage_update)
            for i in xrange(self.nVolts)
        ]
        for v in self.voltsSetEntries:
            v.bind('<Return>', self.set_voltage_update)

        self.voltsSetCodeVars = [tk.IntVar() for i in xrange(self.nVolts)]
        for i in xrange(self.nVolts):
            self.voltsSetCodeVars[i].set(self.cd.inputVcodes[i])
        self.voltsSetCodeEntries = [
            tk.Spinbox(self.voltagesFrame,
                       width=8,
                       justify=tk.RIGHT,
                       textvariable=self.voltsSetCodeVars[i],
                       from_=0,
                       to=65535,
                       increment=1,
                       command=self.set_voltage_dac_code_update)
            for i in xrange(self.nVolts)
        ]
        for v in self.voltsSetCodeEntries:
            v.bind('<Return>', self.set_voltage_dac_code_update)

        # caption
        tk.Label(self.voltagesFrame,
                 text="Name",
                 width=8,
                 fg="white",
                 bg="black").grid(row=0, column=0, sticky=tk.W + tk.E)
        tk.Label(self.voltagesFrame,
                 text="Voltage [V]",
                 width=10,
                 fg="white",
                 bg="black").grid(row=0, column=1, sticky=tk.W + tk.E)
        tk.Label(self.voltagesFrame,
                 text="DAC code",
                 width=10,
                 fg="white",
                 bg="black").grid(row=0, column=2, sticky=tk.W + tk.E)
        tk.Label(self.voltagesFrame,
                 text="Measured [V]",
                 fg="white",
                 bg="black").grid(row=0, column=3, sticky=tk.W + tk.E)

        # placing widgets
        for i in xrange(self.nVolts):
            self.voltsNameLabels[i].grid(row=i + 1, column=0)
            self.voltsSetEntries[i].grid(row=i + 1, column=1)
            self.voltsSetCodeEntries[i].grid(row=i + 1, column=2)
            self.voltsOutputLabels[i].grid(row=i + 1, column=3)

        self.update_values_display()
        ######## End of contral Frame ########

        # frame for plotting
        self.dataPlotsFrame = tk.Frame(self.master)
        self.dataPlotsFrame.pack(side=tk.TOP, fill=tk.BOTH, expand=True)
        self.dataPlotsFrame.bind("<Configure>", self.on_resize)
        self.dataPlotsFigure = Figure(figsize=dataFigSize, dpi=72)
        self.dataPlotsFigure.subplots_adjust(left=0.1,
                                             right=0.98,
                                             top=0.98,
                                             bottom=0.05,
                                             hspace=0,
                                             wspace=0)
        # x-axis is shared
        #         dataPlotsSubplotN = self.dataPlotsFigure.add_subplot(self.nCh, 1, self.nCh, xlabel='t [us]', ylabel='[V]')
        dataPlotsSubplotN = self.dataPlotsFigure.add_subplot(1,
                                                             1,
                                                             1,
                                                             xlabel='t [us]',
                                                             ylabel='[V]')
        self.dataPlotsSubplots = []
        #         self.dataPlotsSubplots = [self.dataPlotsFigure.add_subplot(self.nCh, 1, i+1, sharex=dataPlotsSubplotN)
        #                                   for i in xrange(self.nCh-1)]
        #         for a in self.dataPlotsSubplots:
        #             artist.setp(a.get_xticklabels(), visible=False)
        self.dataPlotsSubplots.append(dataPlotsSubplotN)
        self.dataPlotsCanvas = FigureCanvasTkAgg(self.dataPlotsFigure,
                                                 master=self.dataPlotsFrame)
        self.dataPlotsCanvas.show()
        self.dataPlotsCanvas.get_tk_widget().pack(side=tk.TOP,
                                                  fill=tk.BOTH,
                                                  expand=True)
        self.dataPlotsToolbar = NavigationToolbar2TkAgg(
            self.dataPlotsCanvas, self.dataPlotsFrame)
        self.dataPlotsToolbar.update()
        self.dataPlotsCanvas._tkcanvas.pack(side=tk.TOP,
                                            fill=tk.BOTH,
                                            expand=True)
        self.dataPlotsCanvas.mpl_connect('key_press_event', self.on_key_event)
        #
        self.plot_data()

    def on_key_event(self, event):
        print('You pressed {:s}'.format(event.key))
        key_press_handler(event, self.dataPlotsCanvas, self.dataPlotsToolbar)

    def on_resize(self, event):
        # print(event.width, event.height)
        return

    def quit(self):
        with self.cd.cv:
            self.cd.quit = True
            self.cd.cv.notify()
        self.master.quit()  # stops mainloop
        self.master.destroy()  # this is necessary on Windows to prevent
        # Fatal Python Error: PyEval_RestoreThread: NULL tstate

    def get_and_plot_data(self):
        # reset data fifo
        print("in get_and_plot_data")
        if online: self.cd.dataSocket.sendall(self.cd.cmd.send_pulse(1 << 2))
        time.sleep(0.1)

        for i in range(len(self.cd.adcData)):
            for j in range(len(self.cd.adcData[i])):
                self.cd.adcData0[i][j] = self.cd.adcData[i][j]

        if online:
            buf = self.cd.cmd.acquire_from_datafifo(self.cd.dataSocket,
                                                    self.cd.nWords,
                                                    self.cd.sampleBuf)
            self.cd.sigproc.demux_fifodata(buf, self.cd.adcData,
                                           self.cd.sdmData)
        self.plot_data()

        if self.autoSaveData:
            self.cd.sigproc.save_data(self.cd.dataFName, self.cd.adcData,
                                      self.cd.sdmData)

    def plot_data(self):
        print("going to plot sensor", self.cd.currentSensor)
        for a in self.dataPlotsSubplots:
            a.cla()
            self.dataPlotsFigure.texts = []
#             for txt in self.dataPlotsFigure.texts:
#                 txt.set_visible(False)
        a = self.dataPlotsSubplots[-1]
        #         a.set_xlabel(u't [us]')
        a.set_xlabel(u't [ms]')
        self.cd.adcDt = 0.2 * 0.001
        a.set_ylabel('[V]')
        nSamples = len(self.cd.adcData[0])
        x = [self.cd.adcDt * i for i in xrange(nSamples)]

        a.locator_params(axis='y', tight=True, nbins=4)
        a.yaxis.set_major_formatter(FormatStrFormatter('%7.4f'))
        a.set_xlim([0.0, self.cd.adcDt * nSamples])

        a.step(x,
               array.array('f', self.cd.adcData0[self.cd.currentSensor]),
               where='post',
               color='lightcoral')
        a.step(x,
               array.array('f', self.cd.adcData[self.cd.currentSensor]),
               where='post')
        dd1 = max(self.cd.adcData[self.cd.currentSensor]) - min(
            self.cd.adcData[self.cd.currentSensor])
        l1 = self.dataPlotsFigure.text(0.2,
                                       0.92,
                                       'New:{0:.3f}'.format(0.5 * dd1),
                                       ha='center',
                                       va='center',
                                       transform=a.transAxes)
        l1.set_color('blue')

        dd0 = max(self.cd.adcData0[self.cd.currentSensor]) - min(
            self.cd.adcData0[self.cd.currentSensor])
        l0 = self.dataPlotsFigure.text(0.2,
                                       0.90,
                                       'Old:{0:.3f}'.format(0.5 * dd0),
                                       ha='center',
                                       va='center',
                                       transform=a.transAxes)
        l0.set_color('lightcoral')
        l2 = self.dataPlotsFigure.text(0.2,
                                       0.88,
                                       'Old:{0:.3f}'.format(0.5 * (dd1 - dd0)),
                                       ha='center',
                                       va='center',
                                       transform=a.transAxes)
        if dd1 - dd0 > 0:
            l2.set_color('green')
        else:
            l2.set_color('black')
        #         a.set_ylim([0.97,1.03])

        self.dataPlotsCanvas.show()
        self.dataPlotsToolbar.update()

    def re_sample(self):
        self.mode = 0
        self.get_and_plot_data()

    def auto_update(self):
        self.mode = 1
        while self.mode == 1:
            try:
                time.sleep(1)
                self.get_and_plot_data()
            except:
                break

    def plot_data2(self):
        # self.dataPlotsFigure.clf(keep_observers=True)
        for a in self.dataPlotsSubplots:
            a.cla()
        for i in xrange(len(self.dataPlotsSubplots) - 1):
            a = self.dataPlotsSubplots[i]
            artist.setp(a.get_xticklabels(), visible=False)
            a.set_ylabel("#{:d}".format(i), rotation=0)
        a = self.dataPlotsSubplots[-1]
        a.set_xlabel(u't [us]')
        a.set_ylabel('[V]')
        nSamples = len(self.cd.adcData[0])
        x = [self.cd.adcDt * i for i in xrange(nSamples)]
        #         print(x if len(x)<10 else x[:10])
        for i in xrange(len(self.dataPlotsSubplots)):
            a = self.dataPlotsSubplots[i]
            a.locator_params(axis='y', tight=True, nbins=4)
            a.yaxis.set_major_formatter(FormatStrFormatter('%7.4f'))
            a.set_xlim([0.0, self.cd.adcDt * nSamples])
            a.step(x, self.cd.adcData[i], where='post')
        self.dataPlotsCanvas.show()
        self.dataPlotsToolbar.update()
        return

    def demux_fifodata(self,
                       fData,
                       adcData=None,
                       sdmData=None,
                       adcVoffset=1.024,
                       adcLSB=62.5e-6):
        wWidth = 512
        bytesPerSample = wWidth / 8
        if type(fData[0]) == str:
            fD = bytearray(fData)
        else:
            fD = fData
        if len(fD) % bytesPerSample != 0:
            print("empty fD")
            return []
        nSamples = len(fD) / bytesPerSample
        if adcData == None:
            adcData = [[0 for i in xrange(nSamples)]
                       for j in xrange(self.nAdcCh)]
        if sdmData == None:
            sdmData = [[0 for i in xrange(nSamples * self.adcSdmCycRatio)]
                       for j in xrange(self.nSdmCh * 2)]
        for i in xrange(nSamples):
            for j in xrange(self.nAdcCh):
                idx0 = bytesPerSample - 1 - j * 2
                v = (fD[i * bytesPerSample + idx0 - 1] << 8
                     | fD[i * bytesPerSample + idx0])
                # convert to signed int
                v = (v ^ 0x8000) - 0x8000
                # convert to actual volts

                adcData[j][i] = v * adcLSB + adcVoffset
            b0 = self.nAdcCh * 2
            for j in xrange(self.adcSdmCycRatio * self.nSdmCh * 2):
                bi = bytesPerSample - 1 - b0 - int(j / 8)
                bs = j % 8
                ss = int(j / (self.nSdmCh * 2))
                ch = j % (self.nSdmCh * 2)
                sdmData[ch][i * self.adcSdmCycRatio +
                            ss] = (fD[i * bytesPerSample + bi] >> bs) & 0x1
        #
        return adcData

    def save_data0(self):
        self.cd.sigproc.save_data([
            "sample_" + str(self.sampleID) + '_' + x + '.dat'
            for x in ['adc', 'sdm']
        ], self.cd.adcData, self.cd.sdmData)
        self.sampleID += 1

    def save_data(self, fNames):
        with open(fNames[0], 'w') as fp:
            fp.write("# 5Msps ADC\n")
            nSamples = len(self.cd.adcData[0])
            for i in xrange(nSamples):
                for j in xrange(len(self.cd.adcData)):
                    fp.write(" {:9.6f}".format(self.cd.adcData[j][i]))
                fp.write("\n")
        with open(fNames[1], 'w') as fp:
            fp.write("# 25Msps SDM\n")
            nSamples = len(self.cd.sdmData[0])
            for i in xrange(nSamples):
                for j in xrange(len(self.cd.sdmData)):
                    fp.write(" {:1d}".format(self.cd.sdmData[j][i]))
                fp.write("\n")


#     def quit(self):
#         with self.cd.cv:
#             self.cd.quit = True
#             self.cd.cv.notify()
#         self.master.destroy()

    def update_values_display(self):
        for i in xrange(self.nVolts):
            self.voltsILabels[i].configure(
                text="{:7.3f}".format(self.cd.inputIs[i]))
            self.voltsOutputLabels[i].configure(
                text="{:7.3f}".format(self.cd.voltsOutput[i]))
        self.master.after(int(1000 * self.cd.tI), self.update_values_display)

    def select_current_sensor(self, *args):
        with self.cd.cv:
            self.cd.currentSensor = self.sensorSelVar.get()
            print("sensor", self.cd.currentSensor)
            #             self.cd.currentSensor = self.cd.currentSensor
            # load Vcodes for the specific sensor
            for i in xrange(self.nVolts):
                self.voltsSetCodeVars[i].set(
                    self.cd.sensorVcodes[self.cd.currentSensor][i])
        self.set_voltage_dac_code_update()

    def set_voltage_update(self, *args):
        with self.cd.cv:
            for i in xrange(self.nVolts):
                self.cd.inputVs[i] = self.voltsSetVars[i].get()
                self.cd.inputVcodes[i] = self.cd.tms1mmReg.dac_volt2code(
                    self.cd.inputVs[i])
                self.voltsSetCodeVars[i].set(self.cd.inputVcodes[i])
                # update info for the array
                self.cd.sensorVcodes[
                    self.cd.currentSensor][i] = self.cd.inputVcodes[i]
            self.cd.vUpdated = True
            print(self.cd.inputVs)
            print(self.cd.inputVcodes)
        return True

    def set_voltage_dac_code_update(self, *args):
        with self.cd.cv:
            for i in xrange(self.nVolts):
                self.cd.inputVcodes[i] = self.voltsSetCodeVars[i].get()
                self.cd.inputVs[i] = self.cd.tms1mmReg.dac_code2volt(
                    self.cd.inputVcodes[i])
                self.voltsSetVars[i].set(round(self.cd.inputVs[i], 4))
                # update info for the array
                self.cd.sensorVcodes[
                    self.cd.currentSensor][i] = self.cd.inputVcodes[i]
            self.cd.vUpdated = True
            print(self.cd.inputVcodes)
        return True
class StripChartWdg(tkinter.Frame):
    """A widget to changing values in real time as a strip chart
    
    Usage Hints:
    - For each variable quantity to display:
      - Call addLine once to specify the quantity
      - Call addPoint for each new data point you wish to display

    - For each constant line (e.g. limit) to display call addConstantLine
    
    - To make sure a plot includes one or two y values (e.g. 0 or a range of values) call showY

    - To manually scale a Y axis call setYLimits (by default all y axes are autoscaled).
    
    - All supplied times are POSIX timestamps (e.g. as supplied by time.time()).
        You may choose the kind of time displayed on the time axis (e.g. UTC or local time) using cnvTimeFunc
        and the format of that time using dateFormat.
    
    Known Issues:
    matplotlib's defaults present a number of challenges for making a nice strip chart display.
    Some issues and manual solutions are discussed in the main file's document string.
        
    Potentially Useful Attributes:
    - canvas: the matplotlib FigureCanvas
    - figure: the matplotlib Figure
    - subplotArr: list of subplots, from top to bottom; each is a matplotlib Subplot object,
        which is basically an Axes object but specialized to live in a rectangular grid
    - xaxis: the x axis shared by all subplots
    """
    def __init__(self,
        master,
        timeRange = 3600,
        numSubplots = 1,
        width = 8,
        height = 2,
        showGrid = True,
        dateFormat = "%H:%M:%S",
        updateInterval = None,
        cnvTimeFunc = None,
    ):
        """Construct a StripChartWdg with the specified time range
        
        Inputs:
        - master: Tk parent widget
        - timeRange: range of time displayed (seconds)
        - width: width of graph in inches
        - height: height of graph in inches
        - numSubplots: the number of subplots
        - showGrid: if True a grid is shown
        - dateFormat: format for major axis labels, using time.strftime format
        - updateInterval: now often the time axis is updated (seconds); if None a value is calculated
        - cnvTimeFunc: a function that takes a POSIX timestamp (e.g. time.time()) and returns matplotlib days;
            typically an instance of TimeConverter; defaults to TimeConverter(useUTC=False)
        """
        tkinter.Frame.__init__(self, master)
        
        self._timeRange = timeRange
        self._isVisible = self.winfo_ismapped()
        self._isFirst = True
        if updateInterval is None:
            updateInterval = max(0.1, min(5.0, timeRange / 2000.0))
        self.updateInterval = float(updateInterval)
#         print "updateInterval=", self.updateInterval

        if cnvTimeFunc is None:
            cnvTimeFunc = TimeConverter(useUTC=False)
        self._cnvTimeFunc = cnvTimeFunc

        # how many time axis updates occur before purging old data
        self._maxPurgeCounter = max(1, int(0.5 + (5.0 / self.updateInterval)))
        self._purgeCounter = 0

        self.figure = matplotlib.figure.Figure(figsize=(width, height), frameon=True)
        self.canvas = FigureCanvasTkAgg(self.figure, self)
        self.canvas.get_tk_widget().grid(row=0, column=0, sticky="news")
        self.canvas.mpl_connect('draw_event', self._handleDrawEvent)
        self.grid_rowconfigure(0, weight=1)
        self.grid_columnconfigure(0, weight=1)
        bottomSubplot = self.figure.add_subplot(numSubplots, 1, numSubplots)
        self.subplotArr = [self.figure.add_subplot(numSubplots, 1, n+1, sharex=bottomSubplot) \
            for n in range(numSubplots-1)] + [bottomSubplot]
        if showGrid:
            for subplot in self.subplotArr:
                subplot.grid(True)

        self.xaxis = bottomSubplot.xaxis
        bottomSubplot.xaxis_date()
        self.xaxis.set_major_formatter(matplotlib.dates.DateFormatter(dateFormat))

        # dictionary of constant line name: (matplotlib Line2D, matplotlib Subplot)
        self._constLineDict = dict()

        for subplot in self.subplotArr:
            subplot._scwLines = [] # a list of contained _Line objects;
                # different than the standard lines property in that:
                # - lines contains Line2D objects
                # - lines contains constant lines as well as data lines
            subplot._scwBackground = None # background for animation
            subplot.label_outer() # disable axis labels on all but the bottom subplot
            subplot.set_ylim(auto=True) # set auto scaling for the y axis
        
        self.bind("<Map>", self._handleMap)
        self.bind("<Unmap>", self._handleUnmap)
        self._timeAxisTimer = Timer()
        self._updateTimeAxis()

    def addConstantLine(self, y, subplotInd=0, **kargs):
        """Add a new constant to plot
        
        Inputs:
        - y: value of constant line
        - subplotInd: index of subplot
        - All other keyword arguments are sent to the matplotlib Line2D constructor
          to control the appearance of the data. See addLine for more information.
        """
        subplot = self.subplotArr[subplotInd]
        line2d = subplot.axhline(y, **kargs)
        yMin, yMax = subplot.get_ylim()
        if subplot.get_autoscaley_on() and numpy.isfinite(y) and not (yMin <= y <= yMax):
            subplot.relim()
            subplot.autoscale_view(scalex=False, scaley=True)
        return line2d

    def addLine(self, subplotInd=0, **kargs):
        """Add a new quantity to plot
        
        Inputs:
        - subplotInd: index of subplot
        - All other keyword arguments are sent to the matplotlib Line2D constructor
          to control the appearance of the data. Useful arguments include:
          - label: name of line (displayed in a Legend)
          - color: color of line
          - linestyle: style of line (defaults to a solid line); "" for no line, "- -" for dashed, etc.
          - marker: marker shape, e.g. "+"
          Please do not attempt to control other sorts of line properties, such as its data.
          Arguments to avoid include: animated, data, xdata, ydata, zdata, figure.
        """
        subplot = self.subplotArr[subplotInd]
        return _Line(
            subplot = subplot,
            cnvTimeFunc = self._cnvTimeFunc,
            wdg = self,
        **kargs)
    
    def clear(self):
        """Clear data in all non-constant lines
        """
        for subplot in self.subplotArr:
            for line in subplot._scwLines:
                line.clear()

    def getDoAutoscale(self, subplotInd=0):
        return self.subplotArr[subplotInd].get_autoscaley_on()
    
    def removeLine(self, line):
        """Remove an existing line added by addLine or addConstantLine
        
        Raise an exception if the line is not found
        """
        if isinstance(line, _Line):
            # a _Line object needs to be removed from _scwLines as well as the subplot
            line2d = line.line2d
            subplot = line.subplot
            subplot._scwLines.remove(line)
        else:
            # a constant line is just a matplotlib Line2D instance
            line2d = line
            subplot = line.axes

        subplot.lines.remove(line2d)
        if subplot.get_autoscaley_on():
            subplot.relim()
            subplot.autoscale_view(scalex=False, scaley=True)
        self.canvas.draw()

    def setDoAutoscale(self, doAutoscale, subplotInd=0):
        """Turn autoscaling on or off for the specified subplot
        
        You can also turn off autoscaling by calling setYLimits.
        """
        doAutoscale = bool(doAutoscale)
        subplot = self.subplotArr[subplotInd]
        subplot.set_ylim(auto=doAutoscale)
        if doAutoscale:
            subplot.relim()
            subplot.autoscale_view(scalex=False, scaley=True)
    
    def setYLimits(self, minY, maxY, subplotInd=0):
        """Set y limits for the specified subplot and disable autoscaling.
        
        Note: if you want to autoscale with a minimum range, use showY.
        """
        self.subplotArr[subplotInd].set_ylim(minY, maxY, auto=False)
    
    def showY(self, y0, y1=None, subplotInd=0):
        """Specify one or two values to always show in the y range.
        
        Inputs:
        - subplotInd: index of subplot
        - y0: first y value to show
        - y1: second y value to show; None to omit

        Warning: setYLimits overrides this method (but the values are remembered in case you turn
        autoscaling back on).
        """
        subplot = self.subplotArr[subplotInd]
        yMin, yMax = subplot.get_ylim()
        
        if y1 is not None:
            yList = [y0, y1]
        else:
            yList = [y0]
        doRescale = False
        for y in yList:
            subplot.axhline(y, linestyle=" ")
            if subplot.get_autoscaley_on() and numpy.isfinite(y) and not (yMin <= y <= yMax):
                doRescale = True
        if doRescale:
            subplot.relim()
            subplot.autoscale_view(scalex=False, scaley=True)

    def _handleDrawEvent(self, event=None):
        """Handle draw event
        """
#         print "handleDrawEvent"
        for subplot in self.subplotArr:
            subplot._scwBackground = self.canvas.copy_from_bbox(subplot.bbox)
            for line in subplot._scwLines:
                subplot.draw_artist(line.line2d)
            self.canvas.blit(subplot.bbox)
    
    def _handleMap(self, evt):
        """Handle map event (widget made visible)
        """
        self._isVisible = True
        self._handleDrawEvent()
        self._updateTimeAxis()
    
    def _handleUnmap(self, evt):
        """Handle unmap event (widget made not visible)
        """
        self._isVisible = False
    
    def _updateTimeAxis(self):
        """Update the time axis; calls itself
        """
        tMax = time.time() + self.updateInterval
        tMin = tMax - self._timeRange
        minMplDays = self._cnvTimeFunc(tMin)
        maxMplDays = self._cnvTimeFunc(tMax)
        
        self._purgeCounter = (self._purgeCounter + 1) % self._maxPurgeCounter
        doPurge = self._purgeCounter == 0

        if doPurge:
            for subplot in self.subplotArr:
                for line in subplot._scwLines:
                    line._purgeOldData(minMplDays)
        
        if self._isVisible or self._isFirst:
            for subplot in self.subplotArr:
                subplot.set_xlim(minMplDays, maxMplDays)
                if doPurge:
                    if subplot.get_autoscaley_on():
                        # since data is being purged the y limits may have changed
                        subplot.relim()
                        subplot.autoscale_view(scalex=False, scaley=True)
            self._isFirst = False
            self.canvas.draw()
        self._timeAxisTimer.start(self.updateInterval, self._updateTimeAxis)
class matplotlibSwitchGraphs:
    def __init__(self, master):
        self.master = master
        self.frame = Frame(self.master)
        self.fig, self.ax = config_plot()
        self.graphIndex = 0
        self.canvas = FigureCanvasTkAgg(self.fig, self.master)
        self.config_window()
        self.draw_graph('janvier')
        self.frame.pack(expand=YES, fill=BOTH)

    def config_window(self):
        self.canvas.mpl_connect("key_press_event", self.on_key_press)
        toolbar = NavigationToolbar2Tk(self.canvas, self.master)
        toolbar.update()
        self.canvas.get_tk_widget().pack(side=TOP, fill=BOTH, expand=1)
        self.button = Button(self.master, text="Quit", command=self._quit)
        self.button.pack(side=BOTTOM)
        self.button_back = Button(self.master,
                                  text="Graphique précédent",
                                  command=self.back_graph)
        self.button_back.pack(side=BOTTOM)
        self.button_next = Button(self.master,
                                  text="Graphique suivant",
                                  command=self.next_graph)
        self.button_next.pack(side=BOTTOM)

    def draw_graph(self, month):

        if (month == 'année'):
            df_temp = pd.DataFrame(columns=['Température'])
            df_temp_error = pd.DataFrame(columns=['Température'])
            for column in df:
                for value in df[column]:
                    df_temp = df_temp.append({'Température': value},
                                             ignore_index=True)

            for column in df_error:
                for value in df_error[column]:
                    df_temp_error = df_temp_error.append(
                        {'Température': value}, ignore_index=True)

            df_temp.dropna()
            df_temp_error.dropna()

            self.ax.clear()
            self.ax.plot(df_temp['Température'])
            self.ax.plot(df_temp_error['Température'])
            self.ax.set(title='Année')
            self.canvas.draw()
        else:
            for df, index in enumerate(array_df):
                clear_data(df[month])
                self.ax.clear()
                self.ax.plot(df[month], label=array_csv[index])

            self.ax.plot(df[month], label='Jeux de données propre')
            self.ax.legend()
            self.ax.set(title=month)
            self.canvas.draw()

    def on_key_press(event):
        key_press_handler(event, self.canvas, toolbar)

    def _quit(self):
        self.master.quit()

    def next_graph(self):
        if self.graphIndex == 0:
            self.draw_graph('février')
            self.graphIndex = 1
        elif self.graphIndex == 1:
            self.draw_graph('mars')
            self.graphIndex = 2
        elif self.graphIndex == 2:
            self.draw_graph('avril')
            self.graphIndex = 3
        elif self.graphIndex == 3:
            self.draw_graph('mai')
            self.graphIndex = 4
        elif self.graphIndex == 4:
            self.draw_graph('juin')
            self.graphIndex = 5
        elif self.graphIndex == 5:
            self.draw_graph('juillet')
            self.graphIndex = 6
        elif self.graphIndex == 6:
            self.draw_graph('août')
            self.graphIndex = 7
        elif self.graphIndex == 7:
            self.draw_graph('septembre')
            self.graphIndex = 8
        elif self.graphIndex == 8:
            self.draw_graph('octobre')
            self.graphIndex = 9
        elif self.graphIndex == 9:
            self.draw_graph('novembre')
            self.graphIndex = 10
        elif self.graphIndex == 10:
            self.draw_graph('décembre')
            self.graphIndex = 11
        elif self.graphIndex == 11:
            self.draw_graph('janvier')
            self.graphIndex = 12
        elif self.graphIndex == 12:
            self.draw_graph('année')
            self.graphIndex = 0

    def back_graph(self):
        if self.graphIndex == 0:
            self.draw_graph('décembre')
            self.graphIndex = 11
        elif self.graphIndex == 11:
            self.draw_graph('novembre')
            self.graphIndex = 10
        elif self.graphIndex == 10:
            self.draw_graph('octobre')
            self.graphIndex = 9
        elif self.graphIndex == 9:
            self.draw_graph('septembre')
            self.graphIndex = 8
        elif self.graphIndex == 8:
            self.draw_graph('août')
            self.graphIndex = 7
        elif self.graphIndex == 7:
            self.draw_graph('juillet')
            self.graphIndex = 6
        elif self.graphIndex == 6:
            self.draw_graph('juin')
            self.graphIndex = 5
        elif self.graphIndex == 5:
            self.draw_graph('mai')
            self.graphIndex = 4
        elif self.graphIndex == 4:
            self.draw_graph('avril')
            self.graphIndex = 3
        elif self.graphIndex == 3:
            self.draw_graph('mars')
            self.graphIndex = 2
        elif self.graphIndex == 2:
            self.draw_graph('février')
            self.graphIndex = 1
        elif self.graphIndex == 1:
            self.draw_graph('janvier')
            self.graphIndex = 12
        elif self.graphIndex == 12:
            self.draw_graph('année')
            self.graphIndex = 0
Example #57
0
class tk_int_plot(object):
    def __init__(self):
        self.root = Tk.Tk()
        self.root.wm_title("Fatigue strength curves for direct stress ranges")


        ## PLOT INITIALIZATION ##
        self.f = plt.Figure(figsize=(10,6), dpi=100)
        dictt = {'pad':0,'w_pad':0,'h_pad':0}
        self.f.set_tight_layout(dictt)
        #self.f.subplots_adjust(left=0.1, right=0.98, top=0.97, bottom=0.1) # plot-borders
        
                        

        ## PLOT INPUT ##
        self.N = np.logspace(4.0,9.0,num=1000)
        self.C = [160,140,125,112,100,90,80,71,63,56,50,45,40,36]
        self.C_org = self.C
        self.general_plot(self.N,self.C)


        # a tk.DrawingArea
        self.canvas = FigureCanvasTkAgg(self.f, master=self.root)
        self.canvas.show()
        #self.canvas.get_tk_widget().pack(side=Tk.TOP, fill=Tk.BOTH, expand=1) # used with pack

        # #self.toolbar = NavigationToolbar2TkAgg( self.canvas, self.root ) # used with pack
        toolbar_frame = Tk.Frame(self.root)
        toolbar_frame.grid(row=1,column=0,columnspan=2)
        self.toolbar = NavigationToolbar2TkAgg( self.canvas, toolbar_frame )
        #self.toolbar.update() # used with pack
        self.canvas._tkcanvas.grid(row=0, column=0)#pack(side=Tk.TOP, fill=Tk.BOTH, expand=1)


        ## BUTTONS ##
        # Detail catagory optionMenu
        self.label = Tk.Label(self.root, text= 'Detail Catagory: ').grid(row=2, column=1) #self.label.pack(side=Tk.LEFT)
        optionList = self.C
        self.optionList = Tk.StringVar()
        self.optionList.set(optionList[0])
        self.om = Tk.OptionMenu(self.root,self.optionList,*optionList).grid(row=2, column=2) #self.om.pack(side=Tk.TOP)
        # N cycles Entry
        self.label_n = Tk.Label(self.root, text= 'No. of Cycles: ').grid(row=3, column=1) #self.label.pack(side=Tk.LEFT)
        self.entrytext_n = Tk.StringVar(0,'2e6')
        self.entrybutton = Tk.Entry(master=self.root, textvariable=self.entrytext_n).grid(row=3, column=2) #self.button.pack(side=Tk.TOP)
        # Stress range Entry
        self.label_s = Tk.Label(self.root, text= 'Δσ_R: ').grid(row=4, column=1) #self.label.pack(side=Tk.LEFT)
        self.entrytext_s = Tk.StringVar(0,'160')
        self.entrybutton = Tk.Entry(master=self.root, textvariable=self.entrytext_s).grid(row=4, column=2) #self.button.pack(side=Tk.TOP)
        # Replot button (cycles)
        button = Tk.Button(master=self.root, text='Replot', command=self._replot_n).grid(row=3, column=3) #button.pack(side=Tk.BOTTOM)
        # Replot button (stress)
        button = Tk.Button(master=self.root, text='Replot', command=self._replot_s).grid(row=4, column=3) #button.pack(side=Tk.BOTTOM)
        # Quit button
        button = Tk.Button(master=self.root, text='Quit', command=self._quit).grid(row=5, column=3) #button.pack(side=Tk.BOTTOM)
        # Plot save button
        button = Tk.Button(master=self.root, text='Save Plot', command=self._save_plot).grid(row=6, column=3) #button.pack(side=Tk.BOTTOM)
        # Rainflow_count button (range,freq,accu_freq)
        button = Tk.Button(master=self.root, text='Load rainflow count', command=self._load_rainflow_count).grid(row=7, column=3) #button.pack(side=Tk.BOTTOM)
        # Reset
        button = Tk.Button(master=self.root, text='Reset', command=self._plot_reset).grid(row=8, column=3) #button.pack(side=Tk.BOTTOM)
        #self.root.rowconfigure(index=1, weight=1)

        # Key logger initiated - NK
        self.canvas.mpl_connect('key_press_event', self.on_key_event)
        
        Tk.mainloop()
        # If you put root.destroy() here, it will cause an error if
        # the window is closed with the window manager.



        ## Picked data plot ##
    def general_plot(self,N,C):
        self.gca = self.f.gca()
        self.a = self.f.add_subplot(111)
        self.gca.set_yscale('log')
        self.a.set_xlabel('Endurance, number of cycles N')
        self.a.set_ylabel('Direct stress range $\Delta \sigma_R$ [N/mm$^2$]')
        self.gca.set_xticks([1E4, 1E5, 1E6, 1E7, 1E8, 1E9], minor=False)
        ####self.gca.set_xticks([2E6, 5E6], minor=True)
        #self.gca.set_xticklabels(("1E4", "2E6", "5E6", "1E8"))
        self.gca.xaxis.grid(True, which='major')
        self.gca.xaxis.grid(True, which='minor')
        self.gca.yaxis.grid(True, which='major')
        self.gca.yaxis.grid(True, which='minor')
        ####self.gca.xaxis.grid(True, which='minor')
        
        # Second y-axis setup
        #self.ax2 = self.a.twinx()


        for j in range(len(C)-1):
            self.a.semilogx( N , [self.stress_range(N[i],C[j]) for i in range(len(N))] , 'k-')#,label='$\Delta \sigma_R$')
            self.a.annotate('%s' % (str(self.C[j])), xy=(1e9,self.stress_range(1e9,C[j])),  xycoords='data',xytext=(-40,0), textcoords='offset points', fontsize=7, bbox=dict(boxstyle="round", fc="1.0"))
        self.a.semilogx( N , [self.stress_range(N[i],C[-1]) for i in range(len(N))] , 'r--', label='$\Delta \sigma_R(\Delta \sigma_C$ = ' + str(C[-1]) + ')' )
        self.a.annotate('%s' % (str(self.C[-1])), xy=(1e9,self.stress_range(1e9,C[-1])),  xycoords='data',xytext=(-40,0), textcoords='offset points', fontsize=7, bbox=dict(boxstyle="round", fc="1.0"))

        ## Picked data plot , N cycles##
    def N_plot(self,N,fig_clear=1):
        self.f.clf() # clear figure
        # Update datail category
        self.C_temp = round(float(self.optionList.get()),3)
        if self.C_temp in self.C:
            self.C.pop(self.C.index(self.C_temp))
        self.C.append(self.C_temp)
        # Run general_plot
        self.general_plot(self.N,self.C)
        # Calc. stress range (N)
        self.N_req = N
        self.N_req_stress = self.stress_range(self.N_req,self.C[-1])
        print 'N=',self.N_req, ', dS_R=',self.N_req_stress
        # Update calculated stress range
        self.entrytext_s.set(round(self.N_req_stress,2))
            

    ## Picked data plot , Stress range##
    def S_plot(self,S,fig_clear=1):
        self.f.clf() # clear figure
        # Update datail category
        self.C_temp = round(float(self.optionList.get()),3)
        if self.C_temp in self.C:
            self.C.pop(self.C.index(self.C_temp))
        self.C.append(self.C_temp)
        # Run general_plot
        self.general_plot(self.N,self.C)
        # Calc. N (stress range)
        self.N_req_stress = S
        self.N_req = self.N_cycles(self.N_req_stress,self.C[-1])
        print 'N=',self.N_req, ', dS_R=',self.N_req_stress
        # Update calculated N cycles
        self.entrytext_n.set(self.format_e(self.N_req))
        

    def marked_lines_plot(self):
        self.a.semilogx( [1e4,self.N_req,self.N_req], [self.N_req_stress,self.N_req_stress,1e1] , 'k--',linewidth=2.0)
        self.a.annotate(r'$ N=$'+self.format_e(self.N_req) + '\n' + '$\Delta \sigma_R=$' + str(round(self.N_req_stress,1)), xy=(self.N_req,self.N_req_stress),  xycoords='data',xytext=(+25,+15+(max(self.C)-self.C[-1])), textcoords='offset points', fontsize=10, arrowprops=dict(arrowstyle="->", connectionstyle="arc3,rad=.2"), bbox=dict(boxstyle="round4,pad=0.6", fc="1.0"))
        self.a.set_title('Detail category ' + str(self.C[-1]) + ' of EN1993-1-9')
        self.a.legend(loc='upper center')



        # Determine fatigue stress range based on N, (dS_C, m1 and m2)
    def stress_range(self,N,dS_C=160,m1=3,m2=5):
        dS_D = (2./5)**(1./m1)*dS_C
        dS_L = (5./100)**(1./m2)*dS_D
        
        if N < 5E6:
            dS_R = ((dS_C**m1)*2E6/N)**(1./m1)
        elif N < 1E8:
            dS_R = ((dS_D**m2)*5E6/N)**(1./m2)
        else:
            dS_R = dS_L
        return dS_R

        # Determine N cycles basted on fatigue stress range, (dS_C, m1 and m2)
    def N_cycles(self,dS_R,dS_C=160,m1=3,m2=5):
        dS_D = (2./5)**(1./m1)*dS_C
        dS_L = (5./100)**(1./m2)*dS_D
        
        
        N = ((dS_C**m1)*2E6/dS_R**m1)
        if N > 5E6:
            N = ((dS_D**m2)*5E6/dS_R**m2)
        if N > 1E8:
            N = 1E10
        return N

    def format_e(self,n):
        n = round(n,2)
        a = '%E' % n
        return a.split('E')[0][0:4].rstrip('0').rstrip('.') + 'E' + a.split('E')[1]

    def on_key_event(self, event):
        print('you pressed %s'%event.key)
        key_press_handler(event, self.canvas, self.toolbar)    

    def _quit(self):
        self.root.quit()     # stops mainloop
        self.root.destroy()  # this is necessary on Windows to prevent
                             # Fatal Python Error: PyEval_RestoreThread: NULL tstate
    
    def _replot_n(self):
        N=float(self.entrytext_n.get())
        if type(float(N)) == float:
            self.N_plot(N)
        # Plot marker lines for N cycles
        self.marked_lines_plot()
        if N == 5e6: # plot both for N = 5e6 and N = 1e8
            # Calc. stress range (N=1e8)
            self.N_req = 1e8
            self.N_req_stress = self.stress_range(self.N_req,self.C[-1])
            self.marked_lines_plot()
        # Update figure
        self.canvas.show()

    def _replot_s(self):
        S=float(self.entrytext_s.get())
        if type(float(S)) == float:
            self.S_plot(S)
        # Plot marker lines for N cycles
        self.marked_lines_plot()
        # Update figure
        self.canvas.show()
        
    def _plot_reset(self):
        #self._quit()
        #run = tk_int_plot()
        self.f.clf()
        self.canvas.show()
        print "cleared"
        self.N = np.logspace(4.0,9.0,num=1000)
        self.C = [160,140,125,112,100,90,80,71,63,56,50,45,40,36]
        self.C_org = self.C
        self.general_plot(self.N,self.C)
        # Update figure
        self.canvas.show()
        
        

    def _save_plot(self):
        import decimal
        N_temp = decimal.Decimal(str(round(self.N_req)))
        try:
            self.f.savefig("SN_curve_DC%s_N%s_d_sR%s_fname_%s.png" %(str(self.C_temp),str(N_temp.normalize()),str(round(self.N_req_stress,1)),str(self.filename[-self.filename[::-1].find('/'):])) ,dpi=600,transparent=False,bbox_inches='tight',pad_inches=0) 
        except NameError:
            self.f.savefig("SN_curve_DC%s_N%s_d_sR%s.png" %(str(self.C_temp),str(N_temp.normalize()),str(round(self.N_req_stress,1))) ,dpi=600,transparent=False,bbox_inches='tight',pad_inches=0) 
    
    def _load_rainflow_count(self):
        self.filename = tkFileDialog.askopenfilename(initialdir = "L:\\FEA\\Documentation\\Fatigue\\SquareProfiles\\rainflow" , filetypes = (("Template files", "*.rfo") , ("HTML files", "*.html;*.htm") , ("All files", "*.*") ))
        print self.filename
        data = []
        with open(self.filename,'r') as fin:
            reader=csv.reader(fin,delimiter='\t',skipinitialspace=True)
            for row in reader:
                if len(row) > 0:
                    temp=row[0].split()
                else:
                    temp = ['']
                data.append(temp)
        
        self.data_numbers = data[:]
        row_length = []
        for i in range(len(data)-2,-1,-1):
            for j in range(len(data[i])):
                try:
                    self.data_numbers[i][j] = float(data[i][j])
                except: 
                    pass#print "No number for i,j = (%d,%d)" %(i,j)
        line_start = 13-1#int(raw_input('Line start: '))-1
        line_end   = 63#int(raw_input('Line end: '))
        self.A = 5375
        #self.A = 5625
        #self.A = 9063
        self.gamma_M = 1.2*1.15
        self.rfo = np.reshape(self.data_numbers[line_start:line_end],(line_end-line_start,3))
        self.Fat_plot()
        
    def Fat_plot(self):
        self.N_req = 2e6
        self.C = [round(56/self.gamma_M,3)]
        self.N_req_stress = self.stress_range(self.N_req,dS_C=56/self.gamma_M)
        self.N_knee = 5e6
        self.dS_knee = self.stress_range(self.N_knee,dS_C=56/self.gamma_M)
        self.optionList.set(round(float(self.N_req_stress),3))
        self.N_plot(self.N_knee)
        self.marked_lines_plot()
        
        self.cross_section_stress = []
        self.m = []
        self.allowed_cycles = []
        self.PM = []       
        for i in range(len(self.rfo)):
            self.cross_section_stress.append( self.rfo[i][0]*1000/self.A )
            if self.cross_section_stress[i] > self.dS_knee:
                self.m.append( 3 )
            else:
                self.m.append( 5 )
            if self.cross_section_stress[i] > 0:
                self.allowed_cycles.append( self.N_knee*(self.dS_knee/self.cross_section_stress[i])**(self.m[i]) )
            else:
                self.allowed_cycles.append( 1e100 )
            self.PM.append( self.rfo[i,1]/self.allowed_cycles[i] )
        print "PMsum =", sum(self.PM)
        pp( self.PM )
        pp(self.m)
        pp(self.cross_section_stress)
        pp(self.allowed_cycles)
        
        #self.marked_lines_plot()
        # Second y-axis setup + coloring
        self.ax2 = self.a.twinx()
        self.ax2.set_ylabel('Accu. PMsum' , color='blue')
        for tl in self.ax2.get_yticklabels():
            tl.set_color('blue')

        for i in range(len(self.rfo)):
            if self.rfo[i,1] > 1e4 and self.rfo[i,1] < 1e9:
                self.ax2.semilogx(self.rfo[i,1],np.cumsum(self.PM)[i],'bs')
        self.ax2.legend([str(self.filename[-self.filename[::-1].find('/'):])],loc='right')    
        for i in range(len(self.rfo)):
            if self.rfo[i,1] > 1e4 and self.rfo[i,1] < 1e9 and self.rfo[i,0]*1000/self.A > 10:
                self.gca.semilogx(self.rfo[i,1],self.rfo[i,0]*1000/self.A,'k.')
        self.canvas.show()
Example #58
0
class Window(Frame):
    def __init__(self, master):
        Frame.__init__(self, master)
        self.master = master
        self.master.title("Decline Curve Analysis | NeuDax")
        self.pack(fill=BOTH, expand=1, padx=20)

        self.summary_parameters = pd.DataFrame(columns=[
            'API_NUMBER', 'qi', 'di', 'b', 'sqrt_error', 'skipped_days',
            'TimeStamp'
        ])

        self.read_data()

        row = 0

        label_API = Label(self, text="Well API Number:")
        label_API.grid(row=row, column=0, sticky=E)
        self.API_value = StringVar()
        self.API = ttk.Combobox(self,
                                textvariable=self.API_value,
                                state='readonly')
        self.API['values'] = self.list_of_API_numbers
        self.API.current(0)
        self.API.grid(row=row, column=1, columnspan=2, sticky=W + E)

        button_prev_well = ttk.Button(self,
                                      text="<<< Previous Well",
                                      command=lambda: self.go_to_prev_well())
        button_prev_well.grid(row=row, column=3, sticky=W + E)
        button_next_well = ttk.Button(self,
                                      text="      Next Well >>>",
                                      command=lambda: self.go_to_next_well())
        button_next_well.grid(row=row, column=4, sticky=W + E)

        label_typ_plot = Label(self, text="Type of Plot:")
        label_typ_plot.grid(row=row, column=5, sticky=E)
        self.typ_plot_value = StringVar()
        self.typ_plot = ttk.Combobox(self,
                                     textvariable=self.typ_plot_value,
                                     state='readonly')
        self.typ_plot['values'] = [
            'Linear Plot', 'Semi-Log Plot', 'Log-Log Plot', 'Rate vs. Cum'
        ]
        self.typ_plot.current(0)
        self.typ_plot.grid(row=row, column=6, sticky=W + E)
        row += 1

        label_guide_uncertainty = Label(self,
                                        text="Uncertianty Guide Plots (%)")
        label_guide_uncertainty.grid(row=row, column=0, sticky=E)
        self.guide_uncertainty_percent = tk.Entry(self)
        self.guide_uncertainty_percent.grid(row=row, column=1, sticky=W + E)
        self.guide_uncertainty_percent.delete(0, END)
        self.guide_uncertainty_percent.insert(0, "0.2")
        self.guide_uncertainty_plot_var = BooleanVar()
        self.guide_uncertainty_plot = Checkbutton(
            self,
            text="Plot Guide Lines",
            variable=self.guide_uncertainty_plot_var,
            anchor=W,
            command=lambda: self.plot())
        self.guide_uncertainty_plot.grid(row=row, column=2, sticky=W + E)
        row += 1

        label_skip_days = Label(self, text="Skip Data Until Day:")
        label_skip_days.grid(row=row, column=0, sticky=E)
        self.skip_days = tk.Entry(self)
        self.skip_days.grid(row=row, column=1, sticky=W + E)
        row += 1

        button_load = ttk.Button(self,
                                 text="Step 1) Load Data and Reset Values",
                                 command=lambda: self.load_data())
        button_load.grid(row=row, column=1, columnspan=2, sticky=W + E)
        row += 1

        label_lower_limit_t = Label(self, text="Time Interval (Days):")
        label_lower_limit_t.grid(row=row, column=0, sticky=E)
        self.lower_limit_t = tk.Entry(self)
        self.lower_limit_t.grid(row=row, column=1, sticky=W + E)
        self.upper_limit_t = tk.Entry(self)
        self.upper_limit_t.grid(row=row, column=2, sticky=W + E)
        row += 1

        label_lower_limit_qi = Label(self, text="Limit for qi:")
        label_lower_limit_qi.grid(row=row, column=0, sticky=E)
        self.lower_limit_qi = tk.Entry(self)
        self.lower_limit_qi.grid(row=row, column=1, sticky=W + E)
        self.upper_limit_qi = tk.Entry(self)
        self.upper_limit_qi.grid(row=row, column=2, sticky=W + E)

        row += 1

        label_lower_limit_di = Label(self, text="Limit for di:")
        label_lower_limit_di.grid(row=row, column=0, sticky=E)
        self.lower_limit_di = tk.Entry(self)
        self.lower_limit_di.grid(row=row, column=1, sticky=W + E)
        self.upper_limit_di = tk.Entry(self)
        self.upper_limit_di.grid(row=row, column=2, sticky=W + E)

        row += 1

        label_lower_limit_b = Label(self, text="Limit for b:")
        label_lower_limit_b.grid(row=row, column=0, sticky=E)
        self.lower_limit_b = tk.Entry(self)
        self.lower_limit_b.grid(row=row, column=1, sticky=W + E)
        self.upper_limit_b = tk.Entry(self)
        self.upper_limit_b.grid(row=row, column=2, sticky=W + E)

        row += 1

        label_method = Label(self, text="Method:")
        label_method.grid(row=row, column=0, sticky=E)
        self.method_value = StringVar()
        self.method = ttk.Combobox(self,
                                   textvariable=self.method_value,
                                   state='readonly')
        self.method['values'] = ['trf', 'dogbox']
        self.method.current(0)
        self.method.grid(row=row, column=1, sticky=W + E)
        self.fit_on_cum_var = IntVar()
        self.fit_on_cum = Checkbutton(self,
                                      text="Fit on Cumulative",
                                      variable=self.fit_on_cum_var,
                                      anchor=W)
        self.fit_on_cum.grid(row=row, column=2, sticky=W + E)
        row += 1

        label_loss = Label(self, text="Loss Function:")
        label_loss.grid(row=row, column=0, sticky=E)
        self.loss_value = StringVar()
        self.loss = ttk.Combobox(self,
                                 textvariable=self.loss_value,
                                 state='readonly')
        self.loss['values'] = [
            'linear', 'soft_l1', 'huber', 'cauchy', 'arctan'
        ]
        self.loss.current(0)
        self.loss.grid(row=row, column=1, sticky=W + E)
        self.auto_fit_var = BooleanVar()
        self.auto_fit = Checkbutton(self,
                                    text="Auto Fit",
                                    variable=self.auto_fit_var,
                                    anchor=W)
        self.auto_fit.grid(row=row, column=2, sticky=W + E)
        row += 1

        button_fit_hyp = ttk.Button(self,
                                    text="Step 2) Fit Hyperbolic",
                                    command=lambda: self.fit())
        button_fit_hyp.grid(row=row, column=1, columnspan=2, sticky=W + E)
        row += 1

        label_qi = Label(self, text="Initial Rate (qi):")
        label_qi.grid(row=row, column=0, sticky=E)
        self.par_qi = tk.Entry(self)
        self.par_qi.grid(row=row, column=1, sticky=W + E)

        label_qi = Label(self, text="Previous Parameters:")
        label_qi.grid(row=row, column=2, sticky=W + E)
        row += 1

        label_di = Label(self, text="Initial Decline Rate (di):")
        label_di.grid(row=row, column=0, sticky=E)
        self.par_di = tk.Entry(self)
        self.par_di.grid(row=row, column=1, sticky=W + E)

        self.prev_par_value = StringVar()
        self.prev_par = ttk.Combobox(self,
                                     textvariable=self.prev_par_value,
                                     state='readonly')
        self.prev_par.grid(row=row, column=2, sticky=W + E)
        row += 1

        label_b = Label(self, text="Curvature (b):")
        label_b.grid(row=row, column=0, sticky=E)
        self.par_b = tk.Entry(self)
        self.par_b.grid(row=row, column=1, sticky=W + E)

        button_prev_par = ttk.Button(self,
                                     text="Load Previous Parameters",
                                     command=lambda: self.load_prev_par())
        button_prev_par.grid(row=row, column=2, sticky=W + E)
        row += 1

        self.label_error1 = Label(self, text='Root Mean Squared Error:')
        self.label_error1.grid(row=row, column=1, sticky=E)

        row += 3

        button_plot = ttk.Button(self,
                                 text="Step 3) Manual Modification",
                                 command=lambda: self.plot())
        button_plot.grid(row=row, column=1, columnspan=2, sticky=W + E)
        row += 1

        button_save = ttk.Button(self,
                                 text="Step 4) Save",
                                 command=lambda: self.save())
        button_save.grid(row=row, column=1, columnspan=2, sticky=W + E)
        row += 1

        button_exit = ttk.Button(self,
                                 text="Exit",
                                 command=lambda: self.quit())
        button_exit.grid(row=row, column=1, columnspan=2, sticky=W + E)
        row += 1

        self.fr = tk.Frame(self)
        self.fr.grid(row=1,
                     column=3,
                     rowspan=26,
                     columnspan=4,
                     sticky=N + E + W + S)
        row += 1

        self.f, self.ax = plt.subplots()
        self.canvas = FigureCanvasTkAgg(self.f, master=self.fr)
        self.canvas.show()
        self.canvas.get_tk_widget().pack(fill=tk.BOTH, expand=1)
        self.toolbar = NavigationToolbar2TkAgg(self.canvas, self.fr)
        self.toolbar.update()
        self.canvas._tkcanvas.pack(fill=tk.BOTH, expand=1)
        self.canvas.mpl_connect('button_press_event', self.selecting_point)

        self.load_data()

        self.API.bind("<<ComboboxSelected>>", lambda _: self.load_data())
        self.prev_par.bind("<<ComboboxSelected>>",
                           lambda _: self.load_prev_par())
        self.typ_plot.bind("<<ComboboxSelected>>", lambda _: self.plot())

    def read_data(self):
        #input_file_path =  filedialog.askopenfilename(title = "Select file to open",filetypes = (("csv files","*.csv"),("all files","*.*")))
        input_file_path = 'Small_Dataset_of_Good_APIs_2.csv'
        self.production_data = pd.read_csv(input_file_path)
        temp_list_of_APIs = self.production_data['API_NUMBER'].drop_duplicates(
        )
        self.list_of_API_numbers = temp_list_of_APIs.tolist()

    def load_data(self):

        try:
            self.skipped_days = float(self.skip_days.get())
        except:
            self.skipped_days = 0

        selected_production_data = pd.DataFrame()
        selected_production_data = self.production_data.loc[
            self.production_data['API_NUMBER'] == float(self.API.get()),
            ['OIL_PROD_DAYS', 'OIL_PRODUCTION_BBL']]
        selected_production_data = selected_production_data.dropna()
        selected_production_data = selected_production_data.loc[
            selected_production_data['OIL_PRODUCTION_BBL'] > 0]
        selected_production_data['RATE_PROD'] = selected_production_data[
            'OIL_PRODUCTION_BBL'] / selected_production_data['OIL_PROD_DAYS']
        selected_production_data['CUM_DAYS'] = selected_production_data[
            'OIL_PROD_DAYS'].cumsum()
        selected_production_data['CUM_PROD'] = selected_production_data.loc[
            selected_production_data['CUM_DAYS'] > self.skipped_days,
            'OIL_PRODUCTION_BBL'].cumsum()
        self.t = selected_production_data.loc[
            selected_production_data['CUM_DAYS'] > self.skipped_days,
            'CUM_DAYS'] - self.skipped_days
        self.q = selected_production_data.loc[
            selected_production_data['CUM_DAYS'] > self.skipped_days,
            'RATE_PROD']
        self.q_cum = selected_production_data['CUM_PROD'].dropna()

        print('t', self.t)
        print('q', self.q)
        print('cum', self.q_cum)

        self.selected_t = np.array([])
        self.selected_q = np.array([])
        self.selected_q_cum = np.array([])
        self.valid_t = np.array(self.t)
        self.valid_q = np.array(self.q)
        self.valid_q_cum = np.array(self.q_cum)

        self.par_qi.delete(0, END)
        self.par_qi.insert(0, "0.0")
        self.par_di.delete(0, END)
        self.par_di.insert(0, "1.0")
        self.par_b.delete(0, END)
        self.par_b.insert(0, "0.5")
        self.lower_limit_t.delete(0, END)
        self.lower_limit_t.insert(0, "0")
        self.upper_limit_t.delete(0, END)
        self.upper_limit_t.insert(0, str(self.t.max()))
        self.lower_limit_qi.delete(0, END)
        self.lower_limit_qi.insert(0, "0.0")
        self.upper_limit_qi.delete(0, END)
        self.upper_limit_qi.insert(0, "50000.0")
        self.lower_limit_di.delete(0, END)
        self.lower_limit_di.insert(0, "0.0")
        self.upper_limit_di.delete(0, END)
        self.upper_limit_di.insert(0, "1.0")
        self.lower_limit_b.delete(0, END)
        self.lower_limit_b.insert(0, "0.001")
        self.upper_limit_b.delete(0, END)
        self.upper_limit_b.insert(0, "2.0")
        self.prev_par.set('')

        if self.auto_fit_var.get():
            self.fit()
        else:
            self.plot()

        self.load_prev_timestamps()

    def load_prev_timestamps(self):
        # Loading previous analysis and parameters (if exists)
        previous_parameters = pd.DataFrame()
        previous_parameters = self.summary_parameters.loc[
            self.summary_parameters['API_NUMBER'] == self.API.get(), :]
        temp_list_of_prev_par = []
        temp_list_of_prev_par = previous_parameters[
            'TimeStamp'].drop_duplicates()
        self.list_of_prev_par = temp_list_of_prev_par.tolist()
        self.prev_par['values'] = self.list_of_prev_par

    def load_prev_par(self):
        previous_parameters = pd.DataFrame()
        previous_parameters = self.summary_parameters.loc[
            (self.summary_parameters['API_NUMBER'] == self.API.get()) &
            (self.summary_parameters['TimeStamp'] == self.prev_par.get()), :]

        self.skip_days.delete(0, END)
        self.skip_days.insert(0, previous_parameters['skipped_days'].values[0])

        self.load_data()

        self.par_qi.delete(0, END)
        self.par_qi.insert(0, previous_parameters['qi'].values[0])
        self.par_di.delete(0, END)
        self.par_di.insert(0, previous_parameters['di'].values[0])
        self.par_b.delete(0, END)
        self.par_b.insert(0, previous_parameters['b'].values[0])

        self.plot()

    def save(self):

        self.summary_parameters = self.summary_parameters.append(
            {
                'API_NUMBER': self.API.get(),
                'qi': self.par_qi.get(),
                'di': self.par_di.get(),
                'b': self.par_b.get(),
                'sqrt_error': self.sqrt_error,
                'skipped_days': self.skipped_days,
                'TimeStamp': self.now_code2()
            },
            ignore_index=True)
        now_code = self.now_code()
        par_filepath = './save/saved_parameters_' + str(now_code) + '.csv'
        self.summary_parameters.to_csv(par_filepath, index=False)

        self.load_prev_timestamps()

    def now_code(self):
        now = datetime.datetime.now()
        now_code = now.year * 10000000000 + now.month * 100000000 + now.day * 1000000 + now.hour * 10000 + now.minute * 100 + now.second
        return now_code

    def now_code2(self):
        now = datetime.datetime.now()
        now_code = str(now.year) + '/' + str(now.month) + '/' + str(
            now.day) + ' ' + str(now.hour) + ':' + str(now.minute) + ':' + str(
                now.second)
        return now_code

    def plot(self):
        self.popt = [
            float(self.par_qi.get()),
            float(self.par_di.get()),
            float(self.par_b.get())
        ]
        self.t_model = np.arange(int(np.max(self.t)))
        # This q_model will be plotted as model interpolation
        self.q_model = self.func_hyp(self.t_model, *self.popt)

        # We increase and decrease "b" factor by 10% as guiding plots
        self.q_model_qi_low = self.func_hyp(
            self.t_model,
            self.popt[0] * (1 - float(self.guide_uncertainty_percent.get())),
            self.popt[1], self.popt[2])
        self.q_model_qi_up = self.func_hyp(
            self.t_model,
            self.popt[0] * (1 + float(self.guide_uncertainty_percent.get())),
            self.popt[1], self.popt[2])
        self.q_model_di_low = self.func_hyp(
            self.t_model, self.popt[0],
            self.popt[1] * (1 - float(self.guide_uncertainty_percent.get())),
            self.popt[2])
        self.q_model_di_up = self.func_hyp(
            self.t_model, self.popt[0],
            self.popt[1] * (1 + float(self.guide_uncertainty_percent.get())),
            self.popt[2])
        self.q_model_b_low = self.func_hyp(
            self.t_model, self.popt[0], self.popt[1],
            self.popt[2] * (1 - float(self.guide_uncertainty_percent.get())))
        self.q_model_b_up = self.func_hyp(
            self.t_model, self.popt[0], self.popt[1],
            self.popt[2] * (1 + float(self.guide_uncertainty_percent.get())))

        # This q_model2 will be used for error calculation
        self.q_model2 = self.func_hyp(self.t, *self.popt)

        # Here, we compute cum model
        #self.q_cum_model = self.q_model.cumsum()
        self.q_cum_model = self.func_cum_hyp(self.t_model, *self.popt)

        # We increase and decrease "b" factor by 10% as guiding plots (for cumulative plots)
        self.q_cum_model_qi_low = self.func_cum_hyp(
            self.t_model,
            self.popt[0] * (1 - float(self.guide_uncertainty_percent.get())),
            self.popt[1], self.popt[2])
        self.q_cum_model_qi_up = self.func_cum_hyp(
            self.t_model,
            self.popt[0] * (1 + float(self.guide_uncertainty_percent.get())),
            self.popt[1], self.popt[2])
        self.q_cum_model_di_low = self.func_cum_hyp(
            self.t_model, self.popt[0],
            self.popt[1] * (1 - float(self.guide_uncertainty_percent.get())),
            self.popt[2])
        self.q_cum_model_di_up = self.func_cum_hyp(
            self.t_model, self.popt[0],
            self.popt[1] * (1 + float(self.guide_uncertainty_percent.get())),
            self.popt[2])
        self.q_cum_model_b_low = self.func_cum_hyp(
            self.t_model, self.popt[0], self.popt[1],
            self.popt[2] * (1 - float(self.guide_uncertainty_percent.get())))
        self.q_cum_model_b_up = self.func_cum_hyp(
            self.t_model, self.popt[0], self.popt[1],
            self.popt[2] * (1 + float(self.guide_uncertainty_percent.get())))

        t_lim = np.array([
            float(self.lower_limit_t.get()),
            float(self.lower_limit_t.get()), 0.0
        ])
        q_lim = np.array(
            [0.0, float(self.par_qi.get()),
             float(self.par_qi.get())])

        self.f.clear()

        if self.typ_plot.get() == "Rate vs. Cum":
            self.ax = plt.semilogy(self.q_cum, self.q, 'g.')
            self.ax = plt.semilogy(self.q_cum_model, self.q_model, 'k-')
            self.ax = plt.semilogy(self.selected_q_cum, self.selected_q, 'kx')
            plt.gca().set_xlabel('Cumulative Rate (Bbl)')
            plt.gca().set_ylabel('Rate (Bbl)')

        else:
            if self.typ_plot.get() == "Linear Plot":
                self.ax = plt.plot(self.t, self.q, 'b.', label='Rate Data')
                self.ax = plt.plot(self.selected_t, self.selected_q, 'kx')
                self.ax = plt.plot(t_lim, q_lim, 'g-')
                self.ax = plt.plot(self.t_model,
                                   self.q_model,
                                   'r-',
                                   linewidth=2,
                                   label='Rate Model')
                if self.guide_uncertainty_plot_var.get():
                    self.ax = plt.plot(self.t_model,
                                       self.q_model_b_low,
                                       'r:',
                                       linewidth=1)
                    self.ax = plt.plot(self.t_model,
                                       self.q_model_b_up,
                                       'r-.',
                                       linewidth=1)
                    self.ax = plt.plot(self.t_model,
                                       self.q_model_qi_low,
                                       'b:',
                                       linewidth=1)
                    self.ax = plt.plot(self.t_model,
                                       self.q_model_qi_up,
                                       'b-.',
                                       linewidth=1)
                    self.ax = plt.plot(self.t_model,
                                       self.q_model_di_low,
                                       'g:',
                                       linewidth=1)
                    self.ax = plt.plot(self.t_model,
                                       self.q_model_di_up,
                                       'g-.',
                                       linewidth=1)

            elif self.typ_plot.get() == "Semi-Log Plot":
                self.ax = plt.semilogy(self.t, self.q, 'b.')
                self.ax = plt.semilogy(self.selected_t, self.selected_q, 'kx')
                self.ax = plt.semilogy(t_lim, q_lim, 'g-')
                self.ax = plt.semilogy(self.t_model,
                                       self.q_model,
                                       'r-',
                                       linewidth=2)
                if self.guide_uncertainty_plot_var.get():
                    self.ax = plt.semilogy(self.t_model,
                                           self.q_model_b_low,
                                           'r:',
                                           linewidth=1)
                    self.ax = plt.semilogy(self.t_model,
                                           self.q_model_b_up,
                                           'r-.',
                                           linewidth=1)
                    self.ax = plt.semilogy(self.t_model,
                                           self.q_model_qi_low,
                                           'b:',
                                           linewidth=1)
                    self.ax = plt.semilogy(self.t_model,
                                           self.q_model_qi_up,
                                           'b-.',
                                           linewidth=1)
                    self.ax = plt.semilogy(self.t_model,
                                           self.q_model_di_low,
                                           'g:',
                                           linewidth=1)
                    self.ax = plt.semilogy(self.t_model,
                                           self.q_model_di_up,
                                           'g-.',
                                           linewidth=1)
            elif self.typ_plot.get() == "Log-Log Plot":
                self.ax = plt.loglog(self.t, self.q, 'b.')
                self.ax = plt.semilogy(self.selected_t, self.selected_q, 'kx')
                self.ax = plt.loglog(t_lim, q_lim, 'g-')
                self.ax = plt.loglog(self.t_model,
                                     self.q_model,
                                     'r-',
                                     linewidth=2)
                if self.guide_uncertainty_plot_var.get():
                    self.ax = plt.loglog(self.t_model,
                                         self.q_model_b_low,
                                         'r:',
                                         linewidth=1)
                    self.ax = plt.loglog(self.t_model,
                                         self.q_model_b_up,
                                         'r-.',
                                         linewidth=1)
                    self.ax = plt.loglog(self.t_model,
                                         self.q_model_qi_low,
                                         'b:',
                                         linewidth=1)
                    self.ax = plt.loglog(self.t_model,
                                         self.q_model_qi_up,
                                         'b-.',
                                         linewidth=1)
                    self.ax = plt.loglog(self.t_model,
                                         self.q_model_di_low,
                                         'g:',
                                         linewidth=1)
                    self.ax = plt.loglog(self.t_model,
                                         self.q_model_di_up,
                                         'g-.',
                                         linewidth=1)

            plt.gca().set_xlabel('Time (Days)')
            plt.gca().set_ylabel('Rate (Bbl)')
            plt.gca().set_title(self.API.get() + " | qi:" + self.par_qi.get() +
                                " | di:" + self.par_di.get() + " | b:" +
                                self.par_b.get() + " | " + self.now_code2(),
                                fontsize=8)

            self.ax2 = plt.gca().twinx()
            self.ax2 = plt.plot(self.t, self.q_cum, 'c+', label='Cum Data')
            self.ax2 = plt.plot(self.t_model,
                                self.q_cum_model,
                                'm-',
                                linewidth=2,
                                label='Cum Model')

            if self.guide_uncertainty_plot_var.get():
                self.ax2 = plt.plot(self.t_model,
                                    self.q_cum_model_b_low,
                                    'r:',
                                    linewidth=1)
                self.ax2 = plt.plot(self.t_model,
                                    self.q_cum_model_b_up,
                                    'r-.',
                                    linewidth=1)
                self.ax2 = plt.plot(self.t_model,
                                    self.q_cum_model_qi_low,
                                    'b:',
                                    linewidth=1)
                self.ax2 = plt.plot(self.t_model,
                                    self.q_cum_model_qi_up,
                                    'b-.',
                                    linewidth=1)
                self.ax2 = plt.plot(self.t_model,
                                    self.q_cum_model_di_low,
                                    'g:',
                                    linewidth=1)
                self.ax2 = plt.plot(self.t_model,
                                    self.q_cum_model_di_up,
                                    'g-.',
                                    linewidth=1)

        self.f.tight_layout()
        self.canvas.draw()

        self.sqrt_error = self.error()
        self.label_error2 = Label(self, text='                        ')
        self.label_error2.grid(row=14, column=2, sticky=W)
        self.label_error2 = Label(self, text=str(round(self.sqrt_error, 5)))
        self.label_error2.grid(row=14, column=2, sticky=W)

        self.forecast()

    def error(self):
        diff = (self.q_model2 - self.q)**2
        return (diff.mean())**0.5

    def func_hyp(self, t, qi, di, b):
        return qi / ((1 + di * b * t)**(1 / b))

    def func_cum_hyp(self, t, qi, di, b):
        return (qi / ((1 - b) * di)) * (1 - (1 + b * di * t)**(1 - 1 / b))

    def func_duong(self, t, qi, a, m):
        return qi * t**(-m) * np.exp((a) / (1 - m) * (t**(1 - m)) - 1)

    def fit(self):

        t = self.valid_t[(self.valid_t < float(self.upper_limit_t.get()))]
        q = self.valid_q[(self.valid_t < float(self.upper_limit_t.get()))]

        t_cum = self.t.loc[(self.t > float(self.lower_limit_t.get()))
                           & (self.t < float(self.upper_limit_t.get()))]
        q_cum = self.q_cum.loc[(self.t > float(self.lower_limit_t.get()))
                               & (self.t < float(self.upper_limit_t.get()))]

        lo_qi = float(self.lower_limit_qi.get())
        up_qi = float(self.upper_limit_qi.get())
        lo_di = float(self.lower_limit_di.get())
        up_di = float(self.upper_limit_di.get())
        lo_b = float(self.lower_limit_b.get())
        up_b = float(self.upper_limit_b.get())
        method = self.method.get()
        loss = self.loss.get()

        if self.fit_on_cum_var.get() == 0:
            self.popt, self.pcov = curve_fit(f=self.func_hyp,
                                             xdata=t,
                                             ydata=q,
                                             check_finite=True,
                                             method=method,
                                             loss=loss,
                                             bounds=([lo_qi, lo_di, lo_b],
                                                     [up_qi, up_di, up_b]))

        elif self.fit_on_cum_var.get() == 1:
            self.popt, self.pcov = curve_fit(f=self.func_cum_hyp,
                                             xdata=t_cum,
                                             ydata=q_cum,
                                             check_finite=True,
                                             method=method,
                                             loss=loss,
                                             bounds=([lo_qi, lo_di, lo_b],
                                                     [up_qi, up_di, up_b]))

        self.popt = np.round(self.popt, decimals=5)

        self.q_model = self.func_hyp(self.t, *self.popt)
        self.par_qi.delete(0, END)
        self.par_qi.insert(0, self.popt[0])
        self.par_di.delete(0, END)
        self.par_di.insert(0, self.popt[1])
        self.par_b.delete(0, END)
        self.par_b.insert(0, self.popt[2])
        self.plot()

    def forecast(self):
        days = np.array([90.0, 180.0, 365.0])
        qi = float(self.par_qi.get())
        di = float(self.par_di.get())
        b = float(self.par_b.get())
        self.production_forecast = np.round(self.func_cum_hyp(days, qi, di, b),
                                            decimals=0)
        EUR = np.round(self.EUR(), decimals=0)
        production_statement = "IP90:" + str(
            self.production_forecast[0]) + " | IP180:" + str(
                self.production_forecast[1]) + " | IP365:" + str(
                    self.production_forecast[2]) + " | EUR:" + str(EUR)

        self.label_forecast = Label(
            self, text="                                                    ")
        self.label_forecast.grid(row=15, column=1, columnspan=2, sticky=E + W)
        self.label_forecast = Label(self, text=production_statement)
        self.label_forecast.grid(row=15, column=1, columnspan=2, sticky=E + W)

    def go_to_next_well(self):
        try:
            current_well_index = self.API.current()
            self.API.current(current_well_index + 1)
            self.reset_skip_days()
            self.load_data()
        except:
            return

    def go_to_prev_well(self):
        try:
            current_well_index = self.API.current()
            self.API.current(current_well_index - 1)
            self.reset_skip_days()
            self.load_data()
        except:
            return

    def reset_skip_days(self):
        self.skip_days.delete(0, END)
        self.skip_days.insert(0, "0.0")

    def selecting_point(self, event):
        try:
            self.find_nearest(event.xdata)
            self.plot()
        except:
            return

    def find_nearest(self, value):
        vector_t = np.copy(self.valid_t)
        vector_q = np.copy(self.valid_q)
        vector_q_cum = np.copy(self.valid_q_cum)
        idx = (np.abs(vector_t - value)).argmin()
        self.selected_t = np.append(self.selected_t, vector_t[idx])
        self.selected_q = np.append(self.selected_q, vector_q[idx])
        self.selected_q_cum = np.append(self.selected_q_cum, vector_q_cum[idx])
        self.valid_t = np.delete(self.valid_t, idx)
        self.valid_q = np.delete(self.valid_q, idx)
        self.valid_q_cum = np.delete(self.valid_q_cum, idx)

    def EUR(self):
        qi = float(self.par_qi.get())
        di = float(self.par_di.get())
        b = float(self.par_b.get())
        q_lowest_for_EUR = 1.0
        for t in range(1000000):
            if self.func_hyp(t, qi, di, b) <= q_lowest_for_EUR:
                return self.func_cum_hyp(t, qi, di, b)

    def quit(self):
        global root
        root.destroy()
        root.quit()
Example #59
0
class ViewerApp():
    def __init__(self, master, RNdata, ppc = 20, dpi = 96, colors='coolwarm'):

        self.master = master
        self.master.title('Network Visualization')
        # =========================== Figure preparation ===========================
        self.colors = colors
        self._ppc = ppc
        self._dpi = dpi
        self.bfs = self._set_bfs()
        self.RNdata = RNdata
        self.figure = self.create_fig()
        board = vis.prep_figure(self.RNdata, self.figure)
        self.panelBoard = board[0]
        self.boardWidth = board[1]
        self.boardHeight = board[2]
        figSize = self.figure.get_size_inches() * self._dpi

        # ============================= Parent Windows =============================
        # ---------------------- Figure and window parameteres----------------------

        figWidth, figHeight = [int(x) for x in figSize]
        maxWindWidth = 900
        maxWindHeight = 600
        w = min(figWidth, maxWindWidth)
        h = min(figHeight, maxWindHeight)
        master.geometry(
            '{}x{}+0+0'.format(
                w+20,
                h))

        # --------------------------------- Canvas ---------------------------------
        self.master.rowconfigure(0, weight=1)
        self.master.columnconfigure(0, weight=1)

        # Frames
        self.canvasFrame = ttk.Frame(master, width = w+20, height = h+20)
        self.canvasFrame.grid(row=0, column=0, columnspan = 2, sticky='nsew')
        self.canvasFrame.rowconfigure(0, weight=1)
        self.canvasFrame.columnconfigure(0, weight=1)

        # Widgets
        self.backCanvas = tk.Canvas(self.canvasFrame, scrollregion=(0, 0, w, h))
        self.backCanvas.grid(row=0, column=0, columnspan = 2, sticky='nsew')

        self.yScroll = tk.Scrollbar(self.canvasFrame,
                                    orient=tk.VERTICAL,
                                    command=self.backCanvas.yview)
        self.xScroll = tk.Scrollbar(self.canvasFrame,
                                    orient=tk.HORIZONTAL,
                                    command=self.backCanvas.xview)
        self.yScroll.grid(row=0, column=1, columnspan = 1, sticky='ns')
        self.xScroll.grid(row=1, column=0, columnspan = 1, sticky='ew')
        self.backCanvas.config(xscrollcommand=self.xScroll.set,
                               yscrollcommand=self.yScroll.set)

        self.figureRenderer = FigureCanvasTkAgg(self.figure, self.backCanvas)
        self.mplCanvasWidget = self.figureRenderer.get_tk_widget()
        self.mplCanvasWidget.grid(sticky = 'nsew')

        self.liftControlsButton = ttk.Button(self.master,
                                             text = 'Lift controls',
                                             command=self.onLiftControls)
        self.liftControlsButton.grid(row=2, column=0, sticky='ew')

        self.colprefsButton = ttk.Button(self.master,
                                         text = 'Color preferences',
                                         command = self.onColorPrefs)
        self.colprefsButton.grid(row=2, column=1, sticky='ew')

        # Integrate mpl and tk
        self.backCanvasWind = self.backCanvas.create_window(0, 0, window=self.mplCanvasWidget, anchor = 'nw')
        self.backCanvas.config(scrollregion=self.backCanvas.bbox(tk.ALL))
        self.figureRenderer.mpl_connect('pick_event', self.onPick)


        # ================================ CONTROLS ================================
        # --------------------------- Window parameteres ---------------------------
        controlsWidth = 230
        controlsHeight = 340
        self.controlsWindow = tk.Toplevel(master)
        self.controlsWindow.title('Controls')
        self.controlsWindow.lift(master)
        self.controlsWindow.resizable('False','False')
        self.controlsWindow.geometry(
            '{}x{}+0+0'.format(
                controlsWidth,
                controlsHeight
            )
        )
        # --------------------------------- Frames ---------------------------------

        # Info
        self.infoFrame = ttk.Frame(self.controlsWindow, width = 230, height = 115)
        self.epochSubFrame = ttk.Frame(self.infoFrame,
                                       width = 111,
                                       height = 105,
                                       relief = tk.GROOVE)
        self.cellSubFrame = ttk.Frame(self.infoFrame,
                                      width=111,
                                      height=105,
                                      relief = tk.GROOVE)
        self.tinySub = ttk.Frame(self.cellSubFrame,
                                 width = 40,
                                 height = 40,
                                 relief = tk.SUNKEN)
        # Slide and combobox
        self.selectorFrame = ttk.Frame(self.controlsWindow,
                                       width = 230,
                                       height = 95)
        # Buttons
        self.buttonFrame = ttk.Frame(self.controlsWindow)
        self.continueFrame = ttk.Frame(self.controlsWindow)

        # Progress bar
        self.progressFrame = ttk.Frame(self.controlsWindow,
                                       width = 230,
                                       height = 20)

        # -------------------------------- tk Vars ---------------------------------
        self.patternVar = tk.StringVar()

        # -------------------------------- Widgets ---------------------------------

        # Selectors:
        self.epochSlider = ttk.Scale(self.selectorFrame,
                                     orient = tk.HORIZONTAL,
                                     length = 200,
                                     value = self.RNdata.num_epochs - 1,
                                     from_ = 0,
                                     to = self.RNdata.num_epochs - 1)

        self.epochSlider.set(str(self.RNdata.num_epochs))

        self.patternSelector = ttk.Combobox(self.selectorFrame,
                                            textvariable = self.patternVar,
                                            values = RNdata.main[int(self.epochSlider.get())]['strings'])
        self.patternSelector.current(0)


        # Buttons
        self.updateButton = ttk.Button(self.buttonFrame,
                                       text='Update',
                                       command=self.onUpdate)

        self.labelsButton = ttk.Button(self.buttonFrame,
                                       text='Hide labels',
                                       command=self.onLabels)

        self.zoominButton = ttk.Button(self.buttonFrame,
                                       text = 'Zoom in',
                                       command = lambda: self.changeSize(1))

        self.zoomoutButton = ttk.Button(self.buttonFrame,
                                        text='Zoom out',
                                        command=lambda: self.changeSize(-1))

        self.continueButton = ttk.Button(self.continueFrame,
                                         text='Continue',
                                         command=self.onContinue)
        # Labels:
        #   epoch info
        self.epochValLabel = ttk.Label(self.epochSubFrame,
                                       text = str(self._get_epoch(int(self.epochSlider.get()))),
                                       font = ('Menlo', 30),
                                       justify = tk.CENTER)
        self.epochSlider.config(command = self.onSlide)

        self.epochLabel = ttk.Label(self.epochSubFrame,
                                    text = 'epoch',
                                    font = ('Menlo', 11),
                                    justify = tk.CENTER)

        #   draw cell onto tiny canvas
        self.tinyFig = plt.figure(3, figsize=(40 / 96, 40 / 96), facecolor='white')
        self.tinyRenderer = FigureCanvasTkAgg(self.tinyFig, self.tinySub)
        self.tinyCanvas = self.tinyRenderer.get_tk_widget()
        self.tinyRenderer.draw()

        self.cellWeight = ttk.Label(self.cellSubFrame,
                                    text = '-',
                                    font = ('Menlo', 11),
                                    justify = tk.CENTER)

        self.cellCoords = ttk.Label(self.cellSubFrame,
                                    text = 'r: - | c: -',
                                    font = ('Menlo', 11),
                                    justify = tk.CENTER)

        # Progress bar:
        self.progBar = ttk.Progressbar(self.progressFrame,
                                       orient = tk.HORIZONTAL,
                                       length = 200)

        # -------------------------------- Geometry --------------------------------

        # Info
        self.infoFrame.pack(side = tk.TOP, fill = tk.BOTH)

        # Epoch info
        self.epochSubFrame.pack(side = tk.LEFT, padx = 2, pady = 10)
        self.epochValLabel.place(relx = 0.50, rely = 0.45, anchor = tk.CENTER)
        self.epochLabel.place(relx = 0.50, rely = 0.75, anchor = tk.CENTER)

        # Cell info
        self.cellSubFrame.pack(side = tk.RIGHT, padx = 2, pady = 10)
        self.tinySub.place(relx = 0.50, rely = 0.40, anchor = tk.CENTER)
        self.tinyCanvas.pack()
        self.cellWeight.place(relx = 0.50, rely = 0.70, anchor = tk.CENTER)
        self.cellCoords.place(relx = 0.50, rely = 0.84, anchor = tk.CENTER)

        # Selectors
        self.selectorFrame.pack(fill = tk.BOTH)
        self.patternSelector.pack(fill = tk.Y, expand = True, pady=5)
        self.epochSlider.pack(fill = tk.Y, expand = True, pady=5)
        #
        # Buttons
        self.buttonFrame.pack(fill = tk.BOTH, expand = True)
        self.buttonFrame.columnconfigure(0,weight=1)
        self.buttonFrame.columnconfigure(1, weight=1)
        self.labelsButton.grid(row=0, column = 0, columnspan=2, sticky='ew', padx=10)
        self.zoominButton.grid(row=1, column = 1, columnspan=1, sticky='ew', padx=10)
        self.zoomoutButton.grid(row=1, column = 0, columnspan=1, sticky='ew', padx=10)
        self.updateButton.grid(row=2, column=0, columnspan=2, sticky='ew', padx=10)

        self.continueFrame.pack(fill=tk.X)
        self.continueButton.pack(fill = tk.X, padx = 10)

        # Progress Bar
        self.progressFrame.pack(fill = tk.BOTH, expand = True)
        self.progBar.place(relx = 0.5, rely = 0.5, anchor = tk.CENTER)
        self.progBar.config(mode='indeterminate')

        # ================================ COLORS ==================================
        mpl_color_maps = (['BrBG', 'bwr', 'coolwarm', 'PiYG',
                           'PRGn', 'PuOr','RdBu', 'RdGy',
                           'RdYlBu', 'RdYlGn', 'Spectral',
                           'seismic', 'jet', 'rainbow', 'terrain'])

        self.colorsWindow = tk.Toplevel(self.master, )
        self.colorsWindow.title('Color Preferences')
        self.colorsWindow.resizable('False','False')
        self.colorsWindow.geometry('{}x{}+0+0'.format(350, 150))
        self.colorsWindow.withdraw()

        self.colorsFrame = ttk.Frame(self.colorsWindow)
        self.colorsFrame.place(relx=0.5, rely=0.5, anchor = tk.CENTER, width = 350, height = 150)
        self.colorsFrame.columnconfigure(0, weight = 1)
        self.colorsFrame.columnconfigure(1, weight = 1)
        self.colorsFrame.columnconfigure(2, weight=1)

        self.normMode = tk.StringVar()
        self.normMode.set('cus')

        self.colMap = tk.StringVar()

        self.absRadio = ttk.Radiobutton(self.colorsFrame, variable = self.normMode, value = 'abs', text = 'Absolute')
        self.relRadio = ttk.Radiobutton(self.colorsFrame, variable = self.normMode, value = 'rel', text = 'Relative')
        self.cusRadio = ttk.Radiobutton(self.colorsFrame, variable = self.normMode, value = 'cus', text = 'Custom')

        self.colmapLabel = ttk.Label(self.colorsFrame, text='color map', font=('Helvetica', 10))
        self.nrangeLabel = ttk.Label(self.colorsFrame, text='nrange', font=('Helvetica', 10))

        self.colmapCombo = ttk.Combobox(self.colorsFrame, textvariable = self.colMap, values = mpl_color_maps)
        self.colmapCombo.set(self.colors)
        self.nrangeEntry = tk.Entry(self.colorsFrame, width = 7)
        self.nrangeEntry.insert(0, '1')

        self.applyButton = ttk.Button(self.colorsFrame, text = 'Apply', command = self.onApply)
        self.helpButton = ttk.Button(self.colorsFrame, text = '?', command = self.onHelp)


        self.absRadio.grid(row = 0, column = 0, columnspan = 1, padx = 15, pady = 10, sticky = 'w')
        self.relRadio.grid(row = 0, column = 1, columnspan = 1, padx = 15, pady = 10, sticky = 'w')
        self.cusRadio.grid(row = 0, column = 2, columnspan = 1, padx = 15, pady = 10, sticky = 'w')

        self.colmapLabel.grid(row = 1, column = 0, columnspan = 2, padx = 17, sticky = 'ws')
        self.nrangeLabel.grid(row = 1, column = 2, columnspan = 1, padx = 15, sticky = 'ws')

        self.colmapCombo.grid(row = 2, column = 0, columnspan = 2, padx = 15, sticky = 'ews')
        self.nrangeEntry.grid(row = 2, column = 2, columnspan = 1)

        self.applyButton.grid(row = 3, column = 1, columnspan = 2, padx = 15, pady = 20, sticky = 'nesw')
        self.helpButton.grid(row = 3, column = 0, columnspan = 1, padx = 15, pady = 20, sticky = 'w')

        # ============================ Initial Figure ============================
        self._label_groups = vis.annotate(self.panelBoard,
                                          self.boardHeight,
                                          self.RNdata.data_dim,
                                          self.RNdata.hid_size,
                                          self._set_bfs())
        self._labels_on = True
        self._plotLatest()

        # ============================== PROTOCOLS ===============================
        self.master.protocol('WM_DELETE_WINDOW', self.onMasterX)
        self.controlsWindow.protocol('WM_DELETE_WINDOW', self.onControlsX)
        self.colorsWindow.protocol('WM_DELETE_WINDOW', self.onColorsX)

        self.master.mainloop()

    def create_fig(self):
        # Create a figure
        max_width = self.RNdata.hid_size + self.RNdata.data_dim * 2
        width_cells = max_width + 5
        width_pixels = width_cells * self._ppc
        width_inches = width_pixels / self._dpi

        num_steps = self.RNdata.max_len
        height_cells = 2 * num_steps + 2
        height_pixels = height_cells * self._ppc
        height_inches = height_pixels / self._dpi
        fig = plt.figure(1, figsize=(width_inches, height_inches), facecolor='w', dpi=self._dpi)
        return fig

    def onUpdate(self):
        epoch_ind = int(self.epochSlider.get())
        snap = self.RNdata.main[epoch_ind]
        key = self.patternSelector.get()
        if key in snap['strings']:
            pattern_ind = snap['strings'].index(key)
            self.progBar.start()
            self.panelBoard.clear()
            inp_seq, hid_seq, init_hid, out_seq, targ_seq = get_vecs(snap, pattern_ind, self.RNdata.max_len)
            vis.draw_epoch(self.panelBoard, self.boardHeight, inp_seq, hid_seq, init_hid, out_seq, targ_seq, self.colors, 1)
            self._label_groups = vis.annotate(self.panelBoard,
                                              self.boardHeight,
                                              self.RNdata.data_dim,
                                              self.RNdata.hid_size,
                                              self._set_bfs())
            self.figureRenderer.draw()
            self.progBar.stop()
        else:
            messagebox.showinfo(title='Wrong selection',
                                message='No such pattern. Please select a pattern from the list')

    def onContinue(self):
        self._sleep()

    def changeSize(self, direction):
        oldSize_inches = self.figure.get_size_inches()
        oldSize_pixels = [s_i * self._dpi for s_i in oldSize_inches]
        Size_cells = [s_p / self._ppc for s_p in oldSize_pixels]
        self._ppc += 10 * direction
        newSize_pixels = [s_c * self._ppc for s_c in Size_cells]
        newSize_inches = [s_p / self._dpi for s_p in newSize_pixels]
        self.figure.set_size_inches(newSize_inches)
        nW, nH = newSize_pixels[0], newSize_pixels[1]
        self.canvasFrame.config(width = nW, height = nH)
        self.mplCanvasWidget.config(width = nW, height = nH)
        self.backCanvas.itemconfigure(self.backCanvasWind, width=nW, height=nH)
        self.backCanvas.config(scrollregion=self.backCanvas.bbox(tk.ALL), width=nW, height=nH)
        self.checkPPC()
        vis.deannotate(self._label_groups)
        self._label_groups = vis.annotate(self.panelBoard,
                                          self.boardHeight,
                                          self.RNdata.data_dim,
                                          self.RNdata.hid_size,
                                          self._set_bfs())
        self.figure.canvas.draw()

    def checkPPC(self):
        upperlim = 60
        lowerlim = 10
        if self._ppc <= lowerlim:
            self.zoomoutButton.state(['disabled'])
        elif self._ppc >= upperlim:
            self.zoominButton.state(['disabled'])
        else:
            if self.zoomoutButton.instate(['disabled']): self.zoomoutButton.state(['!disabled'])
            if self.zoominButton.instate(['disabled']): self.zoominButton.state(['!disabled'])

    def onPick(self, event):
        thiscell = event.artist
        value = thiscell.get_cellval()
        r, c = thiscell.get_inds()
        weight = str(round(value, 4))
        rc = 'r: {} | c: {}'.format(r,c)
        self.cellCoords.config(text = rc)
        self.cellWeight.config(text = weight)
        self.tinyFig.set_facecolor(vis.v2c(value, self.colors, 1))
        self.tinyRenderer.draw()

    def onSlide(self, val):
        val = float(val)
        self.epochValLabel.config(text = str(self._get_epoch(val)))
        self.patternSelector['values'] = self.RNdata[int(val)]['strings']
        self.patternSelector.current(0)

    def onApply(self):
        print('Applying changes')
        print('Normalization scope: {}'.format(self.normMode.get()))
        print('Normalization range: {}'.format(self.nrangeEntry.get()))
        print('Color map: {}'.format(self.colmapCombo.get()))
        self.colorsWindow.withdraw()

    def onHelp(self):
        messagebox.showinfo('Need some explanation?',
                            'Too bad, we are still working on it. '
                            'Try playing around with the preferences '
                            'to see what\'s going on :)')

    def onLiftControls(self):
        if self.controlsWindow.state() == 'withdrawn': self.controlsWindow.state('normal')
        self.controlsWindow.lift()

    def onColorPrefs(self):
        if self.colorsWindow.state() == 'withdrawn': self.colorsWindow.state('normal')
        self.colorsWindow.lift()

    def onMasterX(self):
        self._sleep()

    def onControlsX(self):
        self.controlsWindow.withdraw()

    def onColorsX(self):
        positive = messagebox.askyesno('O_o', 'Do you want to apply changes')
        if positive:
            self.onApply()
        self.colorsWindow.withdraw()

    def catch_up(self, snap):
        self.RNdata = snap
        self._plotLatest()
        self.master.state('normal')
        self.controlsWindow.state('normal')
        self.master.mainloop()

    def _sleep(self):
        self.master.withdraw()
        self.controlsWindow.withdraw()
        self.colorsWindow.withdraw()
        self.master.quit()

    def _plotLatest(self):
        latest_epoch_ind = self.RNdata.num_epochs - 1
        latest_snap = self.RNdata[latest_epoch_ind]
        inp_seq, hid_seq, prevhid_seq, out_seq, targ_seq = get_vecs(latest_snap, 0, self.RNdata.max_len)
        vis.draw_epoch(self.panelBoard, self.boardHeight, inp_seq, hid_seq, prevhid_seq, out_seq, targ_seq, self.colors, 1)
        self.epochSlider.config(to = float(latest_epoch_ind))
        self.figureRenderer.draw()

    def _get_epoch(self, slider_value):
        return self.RNdata[int(slider_value)]['ep_num']

    def _get_pattern(self):
        try:
            ind = self.RNdata.inp_names.index(self.patternVar.get())
            print('You selected pattern {}'.format(ind))
        except ValueError:
            print('No such pattern')

    def _set_bfs(self, scale = 0.4):
        return self._ppc * scale

    def onLabels(self):
        pass
    # z
    plt.plot3D(zx, zy, zz)

    plt.plot(int(x_width.get()), int(y_width.get()), y_len, 'ro')

    canvas.draw()



def on_key_press(event):
    print("you pressed {}".format(event.key))
    key_press_handler(event, canvas, toolbar)


canvas.mpl_connect("key_press_event", on_key_press)


def _quit():
    root.quit()
    root.destroy()


def _draw():

    cartesian()



x_label = tkinter.Label(master=root, text="X", font="times 15")
x_width = tkinter.Entry(master=root)