Example #1
1
class Plot(wx.Panel):
  def __init__(self, parent, dpi=None, **kwargs):
    wx.Panel.__init__(self, parent, **kwargs)
    self.figure = mpl.figure.Figure(dpi=dpi, figsize=(2, 2))
    self.canvas = Canvas(self, wx.ID_ANY, self.figure)

    self.check = wx.CheckBox(self, wx.ID_ANY, "Show contour")
    self.Bind(wx.EVT_CHECKBOX, self.OnChange, self.check)

    self.distMod = SinModulator(self, 'Amplitude modulator', cycles=(2,100), phase=(0, 999))
    self.Bind(EVT_UPDATE_EVENT, self.OnChange, self.distMod)

    sizerV = wx.BoxSizer(wx.VERTICAL)
    sizerV.Add(self.distMod)
    sizerV.Add(self.check, 0, wx.EXPAND)

    sizerH = wx.BoxSizer(wx.HORIZONTAL)
    sizerH.Add(self.canvas, 0, wx.SHAPED | wx.EXPAND)
    sizerH.Add(sizerV)

    self.SetSizer(sizerH)
    
    self.width, self.height = 256, 256

  def CalcPixel(self, i, j):
    x = 2.0 * i / self.width - 1.0
    y = 2.0 * j / self.height - 1.0
    dist = np.sqrt(x**2 + y**2) 
    angle = np.arctan2(y, x)

    data = self.distMod

    if data.active:
      phase = data.phase * 2.0 * np.pi 
      newAngle = angle * data.cycles + phase
      distDiff = np.cos(newAngle) * dist / data.cycles
    else:
      distDiff = 0.0

    return 1.0 - (dist + distDiff) 

  def Draw(self):
    self.figure.clear()
    subplot = self.figure.add_subplot(111)

    x = np.arange(0.0, self.width, 1.0)
    y = np.arange(0.0, self.height, 1.0)
    I, J = np.meshgrid(x, y)
    C = np.clip(self.CalcPixel(I, J), 0.0, 1.0)

    if self.check.IsChecked():
      self.CS = subplot.contour(I, J, C)
      subplot.clabel(self.CS, inline=0.1, fontsize=8)

    im = subplot.imshow(C, cmap=cm.gray)
    im.set_interpolation('bilinear')

  def OnChange(self, _):
    self.Draw()
    self.canvas.draw()
Example #2
0
class CanvasPanel(wx.Panel):
    def __init__(self, parent):
        wx.Panel.__init__(self, parent)
        self.figure = Figure()
        self.axes = self.figure.add_subplot(111)
        self.canvas = FigureCanvas(self, -1, self.figure)
        self.toolbar = Toolbar(self.canvas) #matplotlib toolbar
        self.toolbar.Realize()
        self.sizer = wx.BoxSizer(wx.VERTICAL)
        #self.sizer.Add(self.canvas, 1, wx.LEFT | wx.TOP | wx.GROW)
        self.sizer.Add(self.canvas, 1, wx.EXPAND | wx.ALL)
        # Best to allow the toolbar to resize!
        self.sizer.Add(self.toolbar, 0, wx.GROW)
        self.SetSizer(self.sizer)
        self.Fit()

    def GetToolBar(self):
        # You will need to override GetToolBar if you are using an
        # unmanaged toolbar in your frame
        return self.toolbar

    def draw(self):
        t = arange(0.0, 3.0, 0.01)
        s = sin(2 * pi * t)
        self.axes.plot(t, s)

    def OnPaint(self, event):
        self.canvas.draw()
Example #3
0
class WattrGraphPanel( WattrGUI.GraphPanel ):

    subplot = 0
    plots = {}

    def __init__(self, parent, fgsize=None, dpi=None):
        super(WattrGraphPanel, self).__init__(parent)
        self.figure = Figure(fgsize, dpi)
        #Transparent figure face color
        self.figure.set_facecolor((0,0,0,0,))
        self.canvas = FigureCanvasWxAgg(self, -1, self.figure)
        # Now put all into a sizer
        sizer = self.GetSizer()
        # This way of adding to sizer allows resizing
        sizer.Add(self.canvas, 1, wx.LEFT|wx.TOP|wx.GROW)
        # Best to allow the toolbar to resize!
        self.toolbar = NavigationToolbar2Wx(self.canvas)
        self.toolbar.Realize()
        sizer.Add(self.toolbar, 0, wx.GROW)
        self.Fit()

    def add_plot(self, x=1, y=1):
        self.subplot += 1
        plot = self.figure.add_subplot(x, y, self.subplot)
        plot.ticklabel_format(axis='y', style='plain', useOffset=False)
        plot.ticklabel_format(axis='x', style='plain', useOffset=False)
        self.plots[self.subplot] = plot
        return plot
    
    def draw(self):
        self.canvas.draw()
Example #4
0
class RealTimePlot(wx.Frame):
 
 def __init__(self,data):
  wx.Frame.__init__(self, None, -1, "Real time data plot")        
  self.redraw_timer = wx.Timer(self)
  self.Bind(wx.EVT_TIMER, self.on_redraw_timer, self.redraw_timer)        
  self.redraw_timer.Start(100)
  self.data=data          
  self.init_plot()
   
 def init_plot(self): 
  self.data.next()
  self.panel = wx.Panel(self)
  self.fig = Figure((6.0, 3.0))
  self.canvas = FigureCanvasWxAgg(self.panel, -1, self.fig)  
  self.axes = self.fig.add_subplot(111)           
  self.plot_data, = self.axes.plot(self.data.get_curr()[0],self.data.get_curr()[1])
  self.vbox = wx.BoxSizer(wx.VERTICAL)
  self.vbox.Add(self.canvas, 1, flag=wx.LEFT | wx.TOP | wx.GROW)              
  self.panel.SetSizer(self.vbox)
  self.vbox.Fit(self)
    
            
 def draw_plot(self):
  x=self.data.get_curr()[0]
  y=self.data.get_curr()[1]
  self.plot_data.set_data(x,y)
  self.axes.set_xlim((x[0],x[-1]))
  self.axes.set_ylim((min(y),max(y)))
  self.canvas.draw()
   
 def on_redraw_timer(self,event):
  self.data.next()
  self.draw_plot()  
Example #5
0
class GraphPanel(wx.Panel):
    def __init__(self, parent, streamValuesHistory):
        wx.Panel.__init__(self, parent)
        self._streamValuesHistory = streamValuesHistory

        self.figure = Figure()
        self.figure.patch.set_facecolor('black')
        self.axes = self.figure.add_axes([0.1, 0.025, 0.9, 0.95])

        self.canvas = FigureCanvas(self, -1, self.figure)
        self.sizer = wx.BoxSizer(wx.VERTICAL)
        self.sizer.Add(self.canvas, 1, wx.LEFT | wx.TOP | wx.GROW)
        self.SetSizer(self.sizer)
        self.Fit()
        
        self._colors = [(0.0, 1.0, 0.0), (1.0, 0.0, 0.0), (1.0, 1.0, 0.0), (0.0, 1.0, 1.0), (0.0, 0.0, 1.0), (1.0, 0.0, 1.0)]

    def UpdateGraphs(self):
        self.axes.clear()
        self.axes.patch.set_facecolor((0, 0, 0))
        self.axes.grid(b=True, color=(0, 0.1, 0), which='major', linestyle='-', linewidth=1)
        self.axes.yaxis.set_tick_params(labelcolor=(0.6, 0.6, 0.6))
        self.axes.set_axisbelow(True) 

        """Draw data."""
        iColor = 0
        for streamValues in self._streamValuesHistory.itervalues():
            valuesNumber = int(self.axes.get_window_extent().width)
            X = range(0, valuesNumber)
            Y = [streamValues[-min(valuesNumber, len(streamValues))]] * (valuesNumber - len(streamValues)) + streamValues[-valuesNumber:]
            self.axes.plot( X, Y, color=self._colors[iColor%len(self._colors)], linewidth=1)
            iColor+=1
            
        self.canvas.draw()
Example #6
0
class CanvasPanel(wx.Panel):
    def __init__(self, parent):
        wx.Panel.__init__(self, parent)
        self.figure = Figure(facecolor="black")
        self.axes = self.figure.add_axes((0, 0, 1, 1))
        self.canvas = FigureCanvas(self, -1, self.figure)
        self.sizer = wx.BoxSizer(wx.VERTICAL)
        self.sizer.Add(self.canvas, 1, wx.LEFT | wx.TOP | wx.GROW)
        self.SetSizer(self.sizer)
        self.Fit()

        self.axes.set_axis_bgcolor('black')
        self.delta = 0
        
        t = arange(0.0, 3.0, 0.01)
        s = sin(2 * pi * (t))
        self.datatoplot, = self.axes.plot(t, s, 'w', linewidth=3.0)
        self.axes.set_ylim((-10,10))
        self.axes.grid(True, color="w")
        
    def draw(self):
        self.delta = (self.delta + 0.05) % 1
        t = arange(0.0, 3.0, 0.01)
        s = sin(2 * pi * (t-self.delta))
        self.datatoplot.set_ydata(s)
        
        wx.CallLater(10, self.draw)
        self.canvas.draw()
        self.canvas.Refresh()
class PlotPanel2(wx.Panel):
	def __init__(self, parent, **kwargs):
		wx.Panel.__init__(self, parent, **kwargs)
		self.figure = mpl.figure.Figure()
		self.axes = self.figure.add_subplot(111)
		self.canvas = FigureCanvas(self, -1, self.figure)
		self.sizer = wx.BoxSizer(wx.HORIZONTAL)
		self.sizer.Add(self.canvas, 1, wx.ALL | wx.EXPAND | wx.ALIGN_CENTER)
		self.SetSizer(self.sizer)
		self.Fit()

	def Draw(self):
		global XSlice, YSlice, SSlice, DataSlice
		self.axes.cla()
		XSlice = np.linspace(coord1.x,coord2.x,200)
		YSlice = np.linspace(coord1.y,coord2.y,200)
		self.localdx = XSlice[1] - XSlice[0]
		self.localdy = YSlice[1] - YSlice[0]
		self.localds = np.sqrt(self.localdx**2 + self.localdy**2)
		SSlice = [self.localds*x for x in range(200)]
		DataSlice = []
		for x,y in zip(XSlice,YSlice):
			DataSlice.append(DataFit(x,y))
		self.axes.plot(SSlice,DataSlice)
		self.canvas.draw()
Example #8
0
    def __init__(self,parent):
        self.data_t = [0]
        self.data_y = [0]
        self.data_y2 = [0]

        self.dpi = 100
        self.fig = Figure((3.0, 3.0), dpi=self.dpi)

        self.axes = self.fig.add_subplot(111)
        pylab.setp(self.axes.get_xticklabels(), fontsize=10)
        pylab.setp(self.axes.get_yticklabels(), fontsize=10)

        # plot the data as a line series, and save the reference 
        # to the plotted line series
        #
        self.plot_data = self.axes.plot(
            self.data_t,self.data_y,'y',
            self.data_t,self.data_y2,'c',
            )

        ymin = -30
        ymax = 30
        self.axes.set_ybound(lower=ymin, upper=ymax)
        self.axes.set_xlim(0, 20)
        self.axes.grid(True)

        FigCanvas.__init__(self, parent, -1, self.fig)
        self.drawing = False
Example #9
0
    def init_graph(self):
        '''initalizing the graph setup inside the panel
        '''
        self.fig = Figure(figsize=(8, 6), dpi=40)
        self.fig2 = Figure(figsize=(8, 6), dpi=40)
        
        # setting the axes fo the figure graph
        self.axes = self.fig.add_subplot(1, 1, 1)
        self.axes.set_axis_bgcolor('black')
        self.axes.set_title('XXX', size=20)
        self.axes.grid(True, color='white', linewidth=2)
        pylab.setp(self.axes.get_xticklabels(), fontsize=21)
        pylab.setp(self.axes.get_yticklabels(), fontsize=21)
        
        self.axes2 = self.fig2.add_subplot(1, 1, 1) 
        self.axes2.set_axis_bgcolor('black')
        self.axes2.set_title('XXX', size=20)
        self.axes2.grid(True, color='white', linewidth=2)
        pylab.setp(self.axes2.get_xticklabels(), fontsize=21)
        pylab.setp(self.axes2.get_yticklabels(), fontsize=21)

        
        # creates the tamb graph plot inside the first panel
        self.tamb_canvas = FigCanvas(self.tamb_panel_1, -1, self.fig)
        #createst the tobj graph plot inside the second panel
        self.tobj_canvas = FigCanvas(self.tobj_panel_2, -1, self.fig2)
        
        mylog10.debug(repr(self.tamb_canvas) )
        mylog10.debug(repr(self.tobj_canvas) )
Example #10
0
class CanvasFrame(wx.Frame):
    def __init__(self):
        wx.Frame.__init__(self,None,-1,
                         'CanvasFrame',size=(550,350))
        self.SetBackgroundColour(wx.NamedColor("WHITE"))
        self.figure = Figure()
        self.axes = self.figure.add_subplot(111)
        t = arange(0.0,3.0,0.01)
        s = sin(2*pi*t)
        self.axes.plot(t,s)
        self.canvas = FigureCanvas(self, -1, self.figure)
        self.sizer = wx.BoxSizer(wx.VERTICAL)
        self.sizer.Add(self.canvas, 1, wx.LEFT | wx.TOP | wx.GROW)
        self.SetSizer(self.sizer)
        self.Fit()
        self.add_toolbar()  # comment this out for no toolbar
    def add_toolbar(self):
        self.toolbar = NavigationToolbar2Wx(self.canvas)
        self.toolbar.Realize()
        if wx.Platform == '__WXMAC__':
            self.SetToolBar(self.toolbar)
        else:
            tw, th = self.toolbar.GetSizeTuple()
            fw, fh = self.canvas.GetSizeTuple()
            self.toolbar.SetSize(wx.Size(fw, th))
            self.sizer.Add(self.toolbar, 0, wx.LEFT | wx.EXPAND)
        self.toolbar.update()
    def OnPaint(self, event):
        self.canvas.draw()
Example #11
0
    def end_pan_all(self, x, y, axesList):
        """
        End panning for multiple subplots.  Use this function
        to correctly reset limits for all axes.
        """

        if not self.enabled: return
        i = 0
        xmin, xmax = 0, 0
        for axes in axesList:
            if not is_log_x(axes):
                # TBF: matplotlib's Axes' panx method is broken, so we do it
                #      here for them.
                axes.xaxis.pan(-self.panx)
                if i==0:    # we want to keep all plots on a common x-axis
                    xmin, xmax = axes.viewLim.intervalx().get_bounds()
                axes.set_xlim(xmin, xmax)
                axes._send_xlim_event()

            if not is_log_y(axes):
                axes.pany(-self.pany)
                axes._send_ylim_event()

            i += 1

        self.panx = 0
        self.pany = 0

        FigureCanvasWxAgg.draw(self.getView())
Example #12
0
    def rightButtonUp(self, evt, x, y):
        """
        Completely overrides base class functionality.
        """
        view = self.getView()

        if self.selectedAxes is None:
            axes, xdata, ydata = self.find_axes(view, x, y)
        else:
            axes = self.selectedAxes
            xdata, ydata = get_data(axes, x, y)

        self.setActiveSubplot(axes)

        if self.zoomEnabled and self.rightClickUnzoom:
            xmin = xmax = None
            for axes in self.find_all_axes(view, x, y): # unzoom all axes
                self.limits.restore(axes)
                if not self.limits.can_unzoom(axes):
                    # rescale manually - wxmpl will try to autoscale
                    if xmin is None or xmax is None: # make sure x-axis matches
                        xmin, xmax = axes.viewLim.intervalx().get_bounds()
                    axes.set_xlim(xmin, xmax)
                    axes._send_xlim_event()
            view.crosshairs.clear()
            view.draw()
            view.crosshairs.set(x, y)

        if self.IsInfoMode() and axes is not None:
            self.DisplayAllSubplots()
            FigureCanvasWxAgg.draw(view)

        if self.IsPanMode() and axes is not None:
            self.panTool.end_pan_all(x, y, self.find_all_axes(view, x, y))
Example #13
0
    def pan(self, x, y, axes):
        """
        Modifies the desired axes limits to make it appear to the user that the
        axes are panning as he/she moves the mouse.
        """
        if not self.enabled: return

        if not is_log_x(axes):
            xtick = axes.get_xaxis()._get_tick(major=False)._size
            movex = (self.getX() - x) / xtick / 10
            # TBF: matplotlib's Axes' panx method is broken, so we do it here
            #      in the next two lines for them.
            axes.xaxis.pan(movex)
            axes._send_xlim_event()
            self.panx += movex
        if not is_log_y(axes):
            ytick = axes.get_yaxis()._get_tick(major=False)._size
            movey = (self.getY() - y) / ytick / 10
            axes.pany(movey)
            self.pany += movey

        self.setX(x)
        self.setY(y)

        FigureCanvasWxAgg.draw(self.getView())
Example #14
0
    def panAll(self, x, y, axesList):
        """
        Pans across multiple subplots simultaneously.  Use this
        function rather than pan to avoid lag on the x-axis.
        """
        if not self.enabled:    return

        i=0
        movex, movey = 0, 0
        xmin, xmax = 0, 0
        for axes in axesList:
            if not is_log_x(axes):
                xtick = axes.get_xaxis()._get_tick(major=False)._size
                movex = (self.getX() - x) / xtick / 10
                # TBF: matplotlib's Axes' panx method is broken, so we do it here
                axes.xaxis.pan(movex)
                if i==0:    # we want to keep all plots on a common x-axis
                    xmin, xmax = axes.viewLim.intervalx().get_bounds()
                axes.set_xlim(xmin, xmax)
                axes._send_xlim_event()
            if not is_log_y(axes):
                ytick = axes.get_yaxis()._get_tick(major=False)._size
                movey = (self.getY() - y) / ytick / 10
                axes.pany(movey)
            i += 1

        self.panx += movex
        self.pany += movey
        self.setX(x)
        self.setY(y)

        FigureCanvasWxAgg.draw(self.getView())
class PlotPanel(wx.Panel):
    def __init__(self, parent):
        wx.Panel.__init__(self, parent)
        self.parent = parent
        self.fig = Figure()
        self.axes = self.fig.add_subplot(111)
        self.canvas = FigureCanvas(self, -1, self.fig)
        self.sizer = wx.BoxSizer(wx.VERTICAL)
        self.sizer.Add(self.canvas, 1, wx.GROW)
        self.SetSizer(self.sizer)
        self.Fit()

        self.reset()
    @property
    def size(self):
        return self.parent.plot_size.v
    def new_plot(self, name, c):
        self.plots[name] = self.axes.plot(np.zeros(self.size), c)[0] 
        self.axes.set_ylim([-1, 255])
    def new_line(self, name, val, c):
        self.lines[name] = self.axes.plot(np.repeat(val, self.size), c+'--')[0]
    def update_line(self, name, val):
        self.lines[name].set_ydata(np.repeat(val, self.size))
        self.canvas.draw()
    def reset(self):
        self.plots = {}
        self.lines = {}
        saelf.aces.clear()
    def update_plot(self, name, data):
        if len(data) != self.size:
            data = np.append(data, np.repeat(None, self.size-len(data)))
        self.plots[name].set_ydata(data)
        self.canvas.draw()
Example #16
0
    def rightButtonUp(self, evt, x, y):
        """
        Completely overrides base class functionality.
        """
        view = self.getView()

        if self.selectedAxes is None:
            axes, xdata, ydata = wxmpl.find_axes(view, x, y)
        else:
            axes = self.selectedAxes
            xdata, ydata = get_data(axes, x, y)

        self.setActiveSubplot(axes)

        if (axes is not None and self.zoomEnabled and self.rightClickUnzoom
        and self.limits.restore(axes)):
            view.crosshairs.clear()
            view.draw()
            view.crosshairs.set(x, y)

        if self.IsInfoMode() and axes is not None:
            self.DisplayAllSubplots()
            FigureCanvasWxAgg.draw(view)

        if self.IsPanMode() and axes is not None:
            self.panTool.end_pan(x, y, axes)
Example #17
0
class PlotPanel( wx.Panel ):
    def __init__(self, parent, dpi = None, color=None, *args, **kwargs):
        from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg
        wx.Panel.__init__(self, parent, wx.ID_ANY, *args, **kwargs)
        self.parent = parent
        self.figure = mpl.figure.Figure( None, dpi )
        self.canvas = FigureCanvasWxAgg(self, -1, self.figure)

        self._resizeflag = False

        self._SetSize()

        self.Bind(wx.EVT_IDLE, self._onIdle)
        self.Bind(wx.EVT_SIZE, self._SetSize)

    def _SetSize(self, event=None):
        pixels = self.GetSize()
        self.SetSize(pixels)
        self.canvas.SetSize(pixels)
        self.figure.set_size_inches( float(pixels[0])/self.figure.get_dpi(),
                                     float(pixels[1])/self.figure.get_dpi() )

    def _onIdle(self,event):
        self.canvas.draw()
        if self._resizeflag:
            self._SetSize()
            self._resizeflag = False

    def draw(self):
        pass # To be overriden by children
    def make(self):
        pass # To be overriden by children
Example #18
0
class CanvasFrame(wx.Frame):
    def __init__(self):
        wx.Frame.__init__(self, None, -1,
                          'CanvasFrame', size=(550, 350))

        self.figure = Figure(figsize=(5, 4), dpi=100)
        self.axes = self.figure.add_subplot(111)
        t = arange(0.0, 3.0, 0.01)
        s = sin(2 * pi * t)

        self.axes.plot(t, s)

        self.canvas = FigureCanvas(self, -1, self.figure)

        self.sizer = wx.BoxSizer(wx.VERTICAL)
        self.sizer.Add(self.canvas, 1, wx.TOP | wx.LEFT | wx.EXPAND)
        # Capture the paint message
        self.Bind(wx.EVT_PAINT, self.OnPaint)

        self.toolbar = MyNavigationToolbar(self.canvas, True)
        self.toolbar.Realize()
        # By adding toolbar in sizer, we are able to put it at the bottom
        # of the frame - so appearance is closer to GTK version.
        self.sizer.Add(self.toolbar, 0, wx.LEFT | wx.EXPAND)

        # update the axes menu on the toolbar
        self.toolbar.update()
        self.SetSizer(self.sizer)
        self.Fit()

    def OnPaint(self, event):
        self.canvas.draw()
        event.Skip()
Example #19
0
class CanvasPanel(wx.Panel):
    def __init__(self, parent):
        wx.Panel.__init__(self, parent)
        self.figure = Figure()
        self.axes = self.figure.add_subplot(111)
        self.canvas = FigureCanvas(self, -1, self.figure)
        self.sizer = wx.BoxSizer(wx.VERTICAL)
        self.sizer.Add(self.canvas, 1, wx.LEFT | wx.TOP | wx.GROW)
        self.SetSizer(self.sizer)
        self.Fit()

    def show_data(self,fbfile,fields=['cond','imu_a']):
        if fbfile.data is None:
            return
        
        self.figure.clear()
        
        axs=[]
        for axi,varname in enumerate(fields):
            if axi==0:
                sharex=None
            else:
                sharex=axs[0]

            ax=self.figure.add_subplot(len(fields),1,axi+1,sharex=sharex)
            axs.append(ax)
            ax.plot_date( fbfile.data['dn_py'],
                          fbfile.data[varname],
                          'g-')
            
        self.figure.autofmt_xdate()

        # Not sure how to trigger it to actually draw things.
        self.canvas.draw()
        self.Fit()
Example #20
0
class ChartCanvas():
    """
    Container for the matplotlib (or any other) chart object
    """
    def __init__(self, container, config):
        # Create the matplotlib figure and attach it to a canvas
        self.figure = Figure(
            (config.chart_width, config.chart_height),
            dpi=config.chart_dpi)
        self.canvas = FigureCanvasWxAgg(container, -1, self.figure)
        self.chart = self.figure.add_subplot(111)

    def layout(self):
        return self.canvas

    def draw(self, data, _):
        """
        Redraw figure
        """
        logging.debug('Redrawing time series')

        self.chart.clear()
        # self.axes.grid(self.cb_grid.IsChecked())

        self.chart.plot(data['dates'], data['values'])
        self.figure.autofmt_xdate()
        self.canvas.draw()
Example #21
0
class DemoPanel2(wx.Panel):
    def __init__(self, *args, **kwds):
        # begin wxGlade: DemoPanel2.__init__
        kwds["style"] = wx.TAB_TRAVERSAL
        wx.Panel.__init__(self, *args, **kwds)

        self.__set_properties()
        self.__do_layout()
        # end wxGlade
        self.figure = Figure(figsize=(6,4), dpi=80)
        self.axes = self.figure.add_subplot(111)
        self.canvas = FigureCanvas(self, wx.ID_ANY, self.figure)
        self.axes.set_autoscale_on(False)
        self.axes.axis([-20,20,0,0.7])
        self.axes.set_title('Histogram')

        #self.particles = [None] 
        #self.axes.hist(self.particles, 25, label = "Histogram") #hist return 3 elements tuple
        #self.axes.legend()
        self.canvas.draw()
        #self.bg = self.canvas.copy_from_bbox(self.axes.bbox)
        

    def __set_properties(self):
        # begin wxGlade: DemoPanel2.__set_properties
        pass
        # end wxGlade

    def __do_layout(self):
        # begin wxGlade: DemoPanel2.__do_layout
        pass
Example #22
0
class CanvasPanel(wx.Panel):
    def __init__(self, parent, id=wx.ID_ANY):
        wx.Panel.__init__(self, parent, id=id)

        self.SetBackgroundColour(wx.NamedColour("WHITE"))

        self.figure = Figure()
        self.canvas = FigureCanvas(self, -1, self.figure)
        self.canvas.Bind(wx.EVT_ENTER_WINDOW, self.OnEnterWindow)

        self.sizer = wx.BoxSizer(wx.VERTICAL)
        self.sizer.Add(self.canvas, 1, wx.LEFT | wx.TOP | wx.GROW)
        self.SetSizer(self.sizer)
        self.Fit()

        self.Bind(wx.EVT_PAINT, self.OnPaint)

    def OnEnterWindow(self, event):
        "http://matplotlib.sourceforge.net/examples/user_interfaces/wxcursor_demo.html"
        self.canvas.SetCursor(wx.StockCursor(wx.CURSOR_CROSS))

    def OnPaint(self, event):
        logging.debug("%s: OnPaint!!!" % self.__class__.__name__)
        self.canvas.draw()

    def SendFigurePosEvent(self, t0, t1):
        # issue event
        logging.debug("EVENT sent!!")
        evt = FigurePosEvent(t0, t1, id=self.GetId())
        self.GetEventHandler().ProcessEvent(evt)

    def OnFigurePosEvent(self, event):
        #        logging.debug("EVENT received!!")
        self.zoom(event.t0, event.t1, send_event=False)
Example #23
0
class EdgesCumulBarGraph(wx.Panel):
    ''' This panel holds edges cumulative bar graph. '''
    
    def __init__(self, parent):
        ''' parent is a fram instance. '''
        
        wx.Panel.__init__(self, parent = parent, id = -1)        
        self.figure = Figure(dpi = DPI, figsize = (8, 4)) 
        self.canvas = FigureCanvas(self, -1, self.figure)
        self.axes = self.figure.add_subplot(111)
        # Labels
        self.axes.set_title("Cumulative Number of Major Edges per Interval")
        self.axes.set_ylabel("Cumulative number of edges")
        self.axes.set_xlabel("Intervals (%)")        
        # Sizers
        bSizer = wx.BoxSizer(wx.HORIZONTAL)
        bSizer.Add(self.canvas, 1, wx.EXPAND)
        self.SetSizer(bSizer)
        
        
    def DefineBarGraph(self, left, height):
        ''' Create bar graph. '''
        
        self.axes.bar(left = left, height = height, width = 5, bottom = 0, color = "b")
        
    
    def DrawBarGraph(self):
        ''' Draw the bar graph. '''
        
        self.canvas.draw()
Example #24
0
class GraphPanel(wx.Panel):
    def __init__(self,parent):
        wx.Panel.__init__(self,parent)
        self.SetBackgroundColour('#FFFFFF')
        self.quote = wx.StaticText(self,label = "GRAPH PANEL", pos = (200,10))
        self.figure = Figure(dpi=100,figsize=(5,8))
        self.axes = self.figure.add_subplot(111)
        self.axes.axis([0,1,0,60])
        self.axes.set_ylabel('time (s)')
        green = self.axes.axhline(y=-1,color='g',lw=4)
        blue = self.axes.axhline(y=-1,color='b',lw=4)
        red = self.axes.axhline(y=-1,color='r',lw=4)
        self.axes.legend((green,blue,red),("Tone","Level Press","Reward"),loc="upper right")
        self.canvas = FigureCanvas(self, -1, self.figure)
        wx.EVT_PAINT(self, self.OnPaint)

    def OnPaint(self, event):
        self.canvas.draw()
        event.Skip()

    def OnSetFocus(self, event):
        #self.color = '#0099f7'
        self.color = 'yellow'
        self.Refresh()

    def OnKillFocus(self, event):
        self.color = '#b3b3b3'
        self.Refresh()
Example #25
0
    def _create_canvas(self, parent):
        
        panel = QtGui.QWidget()
        
        def mousemoved(event):           
            if event.xdata is not None:
                x, y = event.xdata, event.ydata
                name = "Axes"
            else:
                x, y = event.x, event.y
                name = "Figure"
                
            panel.info.setText("%s: %g, %g" % (name, x, y))
            
        panel.mousemoved = mousemoved
        vbox = QtGui.QVBoxLayout()
        panel.setLayout(vbox)
        
        mpl_control = FigureCanvas(self.value) #❷
        vbox.addWidget(mpl_control)
        if hasattr(self.value, "canvas_events"):
            for event_name, callback in self.value.canvas_events:
                mpl_control.mpl_connect(event_name, callback)

        mpl_control.mpl_connect("motion_notify_event", mousemoved)  

        if self.factory.toolbar: #❸
            toolbar = Toolbar(mpl_control, panel)
            vbox.addWidget(toolbar)       

        panel.info = QtGui.QLabel(panel)
        vbox.addWidget(panel.info)
        return panel    
Example #26
0
class CanvasFrame(wx.Frame):
    def __init__(self, parent, title):
        wx.Frame.__init__(self, parent, -1, title, size=(550, 350))
        self.SetBackgroundColour(wx.NamedColor("WHITE"))
        self.figure = Figure()
        self.axes = self.figure.add_subplot(111)
        self.change_plot(0)
        self.canvas = FigureCanvas(self, -1, self.figure)
        self.sizer = wx.BoxSizer(wx.VERTICAL)
        self.add_buttonbar()
        self.sizer.Add(self.canvas, 1, wx.LEFT | wx.TOP | wx.GROW)
        self.add_toolbar()  # comment this out for no toolbar
        menuBar = wx.MenuBar()
        menu = wx.Menu()
        menu.Append(wx.ID_EXIT, "E&xit\tAlt-X", "Exit this simple sample")
        menuBar.Append(menu, "&File")
        if IS_GTK or IS_WIN:
            menu = wx.Menu()
            for i, (mt, func) in enumerate(functions):
                bm = mathtext_to_wxbitmap(mt)
                item = wx.MenuItem(menu, 1000 + i, "")
                item.SetBitmap(bm)
                menu.AppendItem(item)
                self.Bind(wx.EVT_MENU, self.OnChangePlot, item)
            menuBar.Append(menu, "&Functions")
        self.SetMenuBar(menuBar)
        self.SetSizer(self.sizer)
        self.Fit()
    def add_buttonbar(self):
        self.button_bar = wx.Panel(self)
        self.button_bar_sizer = wx.BoxSizer(wx.HORIZONTAL)
        self.sizer.Add(self.button_bar, 0, wx.LEFT | wx.TOP | wx.GROW)
        for i, (mt, func) in enumerate(functions):
            bm = mathtext_to_wxbitmap(mt)
            button = wx.BitmapButton(self.button_bar, 1000 + i, bm)
            self.button_bar_sizer.Add(button, 1, wx.GROW)
            self.Bind(wx.EVT_BUTTON, self.OnChangePlot, button)
        self.button_bar.SetSizer(self.button_bar_sizer)
    def add_toolbar(self):
        """Copied verbatim from embedding_wx2.py"""
        self.toolbar = NavigationToolbar2Wx(self.canvas)
        self.toolbar.Realize()
        if IS_MAC:
            self.SetToolBar(self.toolbar)
        else:
            tw, th = self.toolbar.GetSizeTuple()
            fw, fh = self.canvas.GetSizeTuple()
            self.toolbar.SetSize(wx.Size(fw, th))
            self.sizer.Add(self.toolbar, 0, wx.LEFT | wx.EXPAND)
        self.toolbar.update()
    def OnPaint(self, event):
        self.canvas.draw()
    def OnChangePlot(self, event):
        self.change_plot(event.GetId() - 1000)
    def change_plot(self, plot_number):
        t = arange(1.0,3.0,0.01)
        s = functions[plot_number][1](t)
        self.axes.clear()
        self.axes.plot(t, s)
        self.Refresh()
Example #27
0
class CapacityPanel(MyPanel):
    def __init__(self, *args, **kwargs):
        MyPanel.__init__(self, *args, **kwargs)        
        self.vbox = wx.BoxSizer(wx.VERTICAL)
        fig = Figure(facecolor=self.face_col)
        
        self.ax = fig.add_subplot(111)

        self.canvas = FigureCanvas(self, -1, fig)
        self.vbox.Add(self.canvas, flag = wx.EXPAND | wx.ALL)
        self.SetSizerAndFit(self.vbox)

        pub.subscribe(self.redraw, "assignments_calced")

    def redraw(self, message):
        """Create a histogram"""
        e_caps = self.model.excessCap()
        e_caps = [x * 100 for x in e_caps]

        self.ax.clear()
        n, bins, patches = self.ax.hist(e_caps, normed=False, bins=10, color="cornflowerblue", 
                    rwidth=.8, linewidth=0)
        self.ax.set_xlabel("Excess Capacity (%)")
        self.ax.set_ylabel("No. of Courses")
        self.ax.set_title("Distribution of Excess Capacity")
        
        num_courses = float(len(e_caps))
        s_labels = [ 100 * p.get_height()/num_courses for p in patches]
        s_labels = [ "%.0f%%" % p for p in s_labels]
        
        self.labelBars(patches, s_labels, self.ax)
        self.canvas.draw()
Example #28
0
class BarsFrame(wx.Frame):

    def __init__(self):
        wx.Frame.__init__(self, None)
        self.data = [5, 6, 9, 14]
        self.create_main_panel()
        self.draw_figure()

    def create_main_panel(self):
        self.panel = wx.Panel(self)
        self.fig = Figure((5.0, 4.0))
        self.canvas = FigCanvas(self.panel, -1, self.fig)
        self.axes = self.fig.add_subplot(111)
        self.vbox = wx.BoxSizer(wx.VERTICAL)
        self.vbox.Add(self.canvas)
        self.panel.SetSizer(self.vbox)
        self.vbox.Fit(self)

    def draw_figure(self):
        x = range(len(self.data))
        self.axes.clear()
        self.axes.bar(left=x, height=self.data)
        self.canvas.draw()

    def on_exit(self, event):
        self.Destroy()
Example #29
0
class PageThree(wx.Panel):
	def __init__(self, parent):
		wx.Panel.__init__(self, parent)
	
		self.figure = Figure(dpi=50)
		
		self.canvas = FigureCanvasWxAgg(self, -1, self.figure)
		self.toolbar = NavigationToolbar2Wx(self.canvas)
		self.toolbar.Realize()
		
		self.plotLast = wx.Button(self,-1,label="Plot Last")
		self.Bind(wx.EVT_BUTTON, self.plotLastButtonClick, self.plotLast)

		topSizer = wx.BoxSizer(wx.HORIZONTAL)
		sizer = wx.BoxSizer(wx.VERTICAL)
		topSizer.Add(self.plotLast, 0, wxFIXED_MINSIZE)
		topSizer.Add(self.canvas, 1, wx.LEFT | wx.TOP | wx.GROW)
		sizer.Add(topSizer,1,wx.GROW)
		sizer.Add(self.toolbar, 0, wx.GROW)
		self.SetSizer(sizer)
		self.Fit()
		
	def plotLastButtonClick(self, evt):
		gh.plotGraph(self.figure)
		self.canvas.draw()
Example #30
0
    def __init__(self, parent, *args, **kwargs):
        """wx.Panel with a matplotlib figure

        Parameters
        ----------
        figsize : tuple
            Figure dimensions (width, height) in inches
        dpi : int
            Dots per inch.
        facecolor : mpl color
            The figure patch facecolor; defaults to rc ``figure.facecolor``
        edgecolor : mpl color
            The figure patch edge color; defaults to rc ``figure.edgecolor``
        linewidth : scalar
            The figure patch edge linewidth; the default linewidth of the frame
        frameon : bool
            If ``False``, suppress drawing the figure frame
        subplotpars :
            A :class:`SubplotParams` instance, defaults to rc
        tight_layout : bool | dict
            If ``False`` use ``subplotpars``; if ``True`` adjust subplot
            parameters using :meth:`tight_layout` with default padding.
            When providing a dict containing the keys `pad`, `w_pad`, `h_pad`
            and `rect`, the default :meth:`tight_layout` paddings will be
            overridden. Defaults to rc ``figure.autolayout``.
        """
        self.figure = Figure(*args, **kwargs)
        FigureCanvasWxAgg.__init__(self, parent, wx.ID_ANY, self.figure)
        self.Bind(wx.EVT_ENTER_WINDOW, self.ChangeCursor)
Example #31
0
class GraphFrame(wx.Frame):
    """ The main frame of the application
    """
    def __init__(self, state):
        wx.Frame.__init__(self, None, -1, state.title)
        self.state = state
        self.data = []
        for i in range(len(state.fields)):
            self.data.append([])
        self.paused = False

        self.create_main_panel()

        self.Bind(wx.EVT_IDLE, self.on_idle)

        self.redraw_timer = wx.Timer(self)
        self.Bind(wx.EVT_TIMER, self.on_redraw_timer, self.redraw_timer)
        self.redraw_timer.Start(1000 * self.state.tickresolution)

    def create_main_panel(self):
        from matplotlib.backends.backend_wxagg import \
             FigureCanvasWxAgg as FigCanvas
        self.panel = wx.Panel(self)

        self.init_plot()
        self.canvas = FigCanvas(self.panel, -1, self.fig)

        self.close_button = wx.Button(self.panel, -1, "Close")
        self.Bind(wx.EVT_BUTTON, self.on_close_button, self.close_button)

        self.pause_button = wx.Button(self.panel, -1, "Pause")
        self.Bind(wx.EVT_BUTTON, self.on_pause_button, self.pause_button)
        self.Bind(wx.EVT_UPDATE_UI, self.on_update_pause_button,
                  self.pause_button)

        self.hbox1 = wx.BoxSizer(wx.HORIZONTAL)
        self.hbox1.Add(self.close_button,
                       border=5,
                       flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL)
        self.hbox1.AddSpacer(1)
        self.hbox1.Add(self.pause_button,
                       border=5,
                       flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL)

        self.vbox = wx.BoxSizer(wx.VERTICAL)
        self.vbox.Add(self.canvas, 1, flag=wx.LEFT | wx.TOP | wx.GROW)
        self.vbox.Add(self.hbox1, 0, flag=wx.ALIGN_LEFT | wx.TOP)

        self.panel.SetSizer(self.vbox)
        self.vbox.Fit(self)

    def init_plot(self):
        self.dpi = 100
        import pylab, numpy
        from matplotlib.figure import Figure
        self.fig = Figure((6.0, 3.0), dpi=self.dpi)

        self.axes = self.fig.add_subplot(111)
        self.axes.set_axis_bgcolor('white')

        pylab.setp(self.axes.get_xticklabels(), fontsize=8)
        pylab.setp(self.axes.get_yticklabels(), fontsize=8)

        # plot the data as a line series, and save the reference
        # to the plotted line series
        #
        self.plot_data = []
        if len(self.data[0]) == 0:
            max_y = min_y = 0
        else:
            max_y = min_y = self.data[0][0]
        for i in range(len(self.data)):
            p = self.axes.plot(
                self.data[i],
                linewidth=1,
                color=self.state.colors[i],
                label=self.state.fields[i],
            )[0]
            self.plot_data.append(p)
            if len(self.data[i]) != 0:
                min_y = min(min_y, min(self.data[i]))
                max_y = max(max_y, max(self.data[i]))

        # create X data
        self.xdata = numpy.arange(-self.state.timespan, 0,
                                  self.state.tickresolution)
        self.axes.set_xbound(lower=self.xdata[0], upper=0)
        if min_y == max_y:
            self.axes.set_ybound(min_y, max_y + 0.1)
        self.axes.legend(self.state.fields,
                         loc='upper left',
                         bbox_to_anchor=(0, 1.1))

    def draw_plot(self):
        """ Redraws the plot
        """
        import numpy, pylab
        state = self.state

        if len(self.data[0]) == 0:
            print("no data to plot")
            return
        vhigh = max(self.data[0])
        vlow = min(self.data[0])

        for i in range(1, len(self.plot_data)):
            vhigh = max(vhigh, max(self.data[i]))
            vlow = min(vlow, min(self.data[i]))
        ymin = vlow - 0.05 * (vhigh - vlow)
        ymax = vhigh + 0.05 * (vhigh - vlow)

        if ymin == ymax:
            ymax = ymin + 0.1
            ymin = ymin - 0.1
        self.axes.set_ybound(lower=ymin, upper=ymax)
        self.axes.grid(True, color='gray')
        pylab.setp(self.axes.get_xticklabels(), visible=True)
        pylab.setp(self.axes.get_legend().get_texts(), fontsize='small')

        for i in range(len(self.plot_data)):
            ydata = numpy.array(self.data[i])
            xdata = self.xdata
            if len(ydata) < len(self.xdata):
                xdata = xdata[-len(ydata):]
            self.plot_data[i].set_xdata(xdata)
            self.plot_data[i].set_ydata(ydata)

        self.canvas.draw()

    def on_pause_button(self, event):
        self.paused = not self.paused

    def on_update_pause_button(self, event):
        label = "Resume" if self.paused else "Pause"
        self.pause_button.SetLabel(label)

    def on_close_button(self, event):
        self.redraw_timer.Stop()
        self.Destroy()

    def on_idle(self, event):
        import time
        time.sleep(self.state.tickresolution * 0.5)

    def on_redraw_timer(self, event):
        # if paused do not add data, but still redraw the plot
        # (to respond to scale modifications, grid change, etc.)
        #
        state = self.state
        if state.close_graph.wait(0.001):
            self.redraw_timer.Stop()
            self.Destroy()
            return
        while state.child_pipe.poll():
            state.values = state.child_pipe.recv()
        if self.paused:
            return
        for i in range(len(self.plot_data)):
            if state.values[i] is not None:
                self.data[i].append(state.values[i])
                while len(self.data[i]) > len(self.xdata):
                    self.data[i].pop(0)

        for i in range(len(self.plot_data)):
            if state.values[i] is None or len(self.data[i]) < 2:
                return
        self.draw_plot()
class GraphFrame(wx.Frame):
    """ The main frame of the application
    """
    title = 'Demo: dynamic matplotlib graph'
    
    def __init__(self):
        wx.Frame.__init__(self, None, -1, self.title)
        
        self.datagen = DataGen()
        self.data = [self.datagen.next()]
        self.paused = False
        
        self.create_menu()
        self.create_status_bar()
        self.create_main_panel()
        
        self.redraw_timer = wx.Timer(self)
        self.Bind(wx.EVT_TIMER, self.on_redraw_timer, self.redraw_timer)        
        self.redraw_timer.Start(REFRESH_INTERVAL_MS)

    def create_menu(self):
        self.menubar = wx.MenuBar()
        
        menu_file = wx.Menu()
        m_expt = menu_file.Append(-1, "&Save plot\tCtrl-S", "Save plot to file")
        self.Bind(wx.EVT_MENU, self.on_save_plot, m_expt)
        menu_file.AppendSeparator()
        m_exit = menu_file.Append(-1, "E&xit\tCtrl-X", "Exit")
        self.Bind(wx.EVT_MENU, self.on_exit, m_exit)
                
        self.menubar.Append(menu_file, "&File")
        self.SetMenuBar(self.menubar)

    def create_main_panel(self):
        self.panel = wx.Panel(self)

        self.init_plot()
        self.canvas = FigCanvas(self.panel, -1, self.fig)

        self.xmin_control = BoundControlBox(self.panel, -1, "X min", 0)
        self.xmax_control = BoundControlBox(self.panel, -1, "X max", 50)
        self.ymin_control = BoundControlBox(self.panel, -1, "Y min", 0)
        self.ymax_control = BoundControlBox(self.panel, -1, "Y max", 100)
        
        self.pause_button = wx.Button(self.panel, -1, "Pause")
        self.Bind(wx.EVT_BUTTON, self.on_pause_button, self.pause_button)
        self.Bind(wx.EVT_UPDATE_UI, self.on_update_pause_button, self.pause_button)
        
        self.cb_grid = wx.CheckBox(self.panel, -1, 
            "Show Grid",
            style=wx.ALIGN_RIGHT)
        self.Bind(wx.EVT_CHECKBOX, self.on_cb_grid, self.cb_grid)
        self.cb_grid.SetValue(True)
        
        self.cb_xlab = wx.CheckBox(self.panel, -1, 
            "Show X labels",
            style=wx.ALIGN_RIGHT)
        self.Bind(wx.EVT_CHECKBOX, self.on_cb_xlab, self.cb_xlab)        
        self.cb_xlab.SetValue(True)
        
        self.hbox1 = wx.BoxSizer(wx.HORIZONTAL)
        self.hbox1.Add(self.pause_button, border=5, flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL)
        self.hbox1.AddSpacer(20)
        self.hbox1.Add(self.cb_grid, border=5, flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL)
        self.hbox1.AddSpacer(10)
        self.hbox1.Add(self.cb_xlab, border=5, flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL)
        
        self.hbox2 = wx.BoxSizer(wx.HORIZONTAL)
        self.hbox2.Add(self.xmin_control, border=5, flag=wx.ALL)
        self.hbox2.Add(self.xmax_control, border=5, flag=wx.ALL)
        self.hbox2.AddSpacer(24)
        self.hbox2.Add(self.ymin_control, border=5, flag=wx.ALL)
        self.hbox2.Add(self.ymax_control, border=5, flag=wx.ALL)
        
        self.vbox = wx.BoxSizer(wx.VERTICAL)
        self.vbox.Add(self.canvas, 1, flag=wx.LEFT | wx.TOP | wx.GROW)        
        self.vbox.Add(self.hbox1, 0, flag=wx.ALIGN_LEFT | wx.TOP)
        self.vbox.Add(self.hbox2, 0, flag=wx.ALIGN_LEFT | wx.TOP)
        
        self.panel.SetSizer(self.vbox)
        self.vbox.Fit(self)
    
    def create_status_bar(self):
        self.statusbar = self.CreateStatusBar()

    def init_plot(self):
        self.dpi = 100
        self.fig = Figure((3.0, 3.0), dpi=self.dpi)

        self.axes = self.fig.add_subplot(111)
        self.axes.set_axis_bgcolor('black')
        self.axes.set_title('Arduino Serial Data', size=12)
        
        pylab.setp(self.axes.get_xticklabels(), fontsize=8)
        pylab.setp(self.axes.get_yticklabels(), fontsize=8)

        # plot the data as a line series, and save the reference 
        # to the plotted line series
        #
        self.plot_data = self.axes.plot(
            self.data, 
            linewidth=1,
            color=(1, 1, 0),
            )[0]

    def draw_plot(self):
        """ Redraws the plot
        """
        # when xmin is on auto, it "follows" xmax to produce a 
        # sliding window effect. therefore, xmin is assigned after
        # xmax.
        #
        if self.xmax_control.is_auto():
            xmax = len(self.data) if len(self.data) > 50 else 50
        else:
            xmax = int(self.xmax_control.manual_value())
            
        if self.xmin_control.is_auto():            
            xmin = xmax - 50
        else:
            xmin = int(self.xmin_control.manual_value())

        # for ymin and ymax, find the minimal and maximal values
        # in the data set and add a mininal margin.
        # 
        # note that it's easy to change this scheme to the 
        # minimal/maximal value in the current display, and not
        # the whole data set.
        # 
        if self.ymin_control.is_auto():
            ymin = round(min(self.data), 0) - 1
        else:
            ymin = int(self.ymin_control.manual_value())
        
        if self.ymax_control.is_auto():
            ymax = round(max(self.data), 0) + 1
        else:
            ymax = int(self.ymax_control.manual_value())

        self.axes.set_xbound(lower=xmin, upper=xmax)
        self.axes.set_ybound(lower=ymin, upper=ymax)
        
        # anecdote: axes.grid assumes b=True if any other flag is
        # given even if b is set to False.
        # so just passing the flag into the first statement won't
        # work.
        #
        if self.cb_grid.IsChecked():
            self.axes.grid(True, color='gray')
        else:
            self.axes.grid(False)

        # Using setp here is convenient, because get_xticklabels
        # returns a list over which one needs to explicitly 
        # iterate, and setp already handles this.
        #  
        pylab.setp(self.axes.get_xticklabels(), 
            visible=self.cb_xlab.IsChecked())
        
        self.plot_data.set_xdata(np.arange(len(self.data)))
        self.plot_data.set_ydata(np.array(self.data))
        
        self.canvas.draw()
    
    def on_pause_button(self, event):
        self.paused = not self.paused
    
    def on_update_pause_button(self, event):
        label = "Resume" if self.paused else "Pause"
        self.pause_button.SetLabel(label)
    
    def on_cb_grid(self, event):
        self.draw_plot()
    
    def on_cb_xlab(self, event):
        self.draw_plot()
    
    def on_save_plot(self, event):
        file_choices = "PNG (*.png)|*.png"
        
        dlg = wx.FileDialog(
            self, 
            message="Save plot as...",
            defaultDir=os.getcwd(),
            defaultFile="plot.png",
            wildcard=file_choices,
            style=wx.SAVE)
        
        if dlg.ShowModal() == wx.ID_OK:
            path = dlg.GetPath()
            self.canvas.print_figure(path, dpi=self.dpi)
            self.flash_status_message("Saved to %s" % path)
    
    def on_redraw_timer(self, event):
        # if paused do not add data, but still redraw the plot
        # (to respond to scale modifications, grid change, etc.)
        #
        if not self.paused:
            self.data.append(self.datagen.next())
        
        self.draw_plot()
    
    def on_exit(self, event):
        self.Destroy()
    
    def flash_status_message(self, msg, flash_len_ms=1500):
        self.statusbar.SetStatusText(msg)
        self.timeroff = wx.Timer(self)
        self.Bind(
            wx.EVT_TIMER, 
            self.on_flash_status_off, 
            self.timeroff)
        self.timeroff.Start(flash_len_ms, oneShot=True)
    
    def on_flash_status_off(self, event):
        self.statusbar.SetStatusText('')
Example #33
0
class MainWindow(wx.Frame):
    MENU_ITEM_LOAD_STREAM = 0x00
    MENU_ITEM_CLOSE_STREAM = 0x01
    MENU_ITEM_DRAW_ALL_FRAMES = 0x02
    MENU_ITEM_EXPORT_ALL_FRAMES = 0x03
    MENU_ITEM_STREAM_PROPERTIES = 0xFE
    MENU_ITEM_EXIT = 0x04
    MENU_ITEM_GO_TO_FIRST = 0x05
    MENU_ITEM_GO_TO_LAST = 0x06
    MENU_ITEM_GO_TO_PREVIOUS = 0x07
    MENU_ITEM_GO_TO_NEXT = 0x08
    MENU_ITEM_GO_TO = 0x09
    MENU_ITEM_FRAME_SAVE = 0x0A
    MENU_ITEM_PLAY = 0x0B
    MENU_ITEM_STOP = 0x0C
    MENU_ITEM_COLORMAP = 0xFF
    MENU_ITEM_COLORMAP_JET = 0x0D
    MENU_ITEM_COLORMAP_HSV = 0x0E
    MENU_ITEM_COLORMAP_GRAY = 0x0F
    MENU_ITEM_COLORBAR = 0x10
    MENU_ITEM_SET_LIMITS = 0x11

    TOOL_FIRST = 0x20
    TOOL_PREVIOUS = 0x21
    TOOL_NEXT = 0x22
    TOOL_LAST = 0x23

    __figure = None
    __canvas = None
    __clim = -1.0, 1.0
    __timer = None

    __filename = None
    __stream = None
    __frame = None

    def __init__(self, filename=None):
        super().__init__(parent=None, title="Stream view", size=(700, 500))
        self.__createMenuBar()
        self.__createToolbar()
        self.__createAxes()
        self.CreateStatusBar()
        self.__timer = wx.Timer(self)
        self.Bind(wx.EVT_TIMER, lambda event: self.autoNext(), self.__timer)
        self.Centre(wx.BOTH)
        self.SetMinSize((200, 100))
        self.Show()
        self.drawClosedState()
        if filename is not None:
            self.loadStream(filename)
        self.Bind(wx.EVT_CLOSE, lambda event: self.onClose())

    def onClose(self):
        self.closeStream()
        self.Destroy()

    def __createMenuBar(self):
        mainMenu = wx.MenuBar()

        fileMenu = wx.Menu()
        fileLoad = fileMenu.Append(self.MENU_ITEM_LOAD_STREAM,
                                   "L&oad stream...\tCTRL+O",
                                   "Loads stream from the hard disk",
                                   wx.ITEM_NORMAL)
        self.Bind(wx.EVT_MENU, lambda event: self.loadStreamCallback(),
                  fileLoad)
        fileClose = fileMenu.Append(self.MENU_ITEM_CLOSE_STREAM,
                                    "&Close stream\tCTRL+W",
                                    "Coses the stream", wx.ITEM_NORMAL)
        self.Bind(wx.EVT_MENU, lambda event: self.closeStream(), fileClose)
        fileMenu.AppendSeparator()
        fileDraw = fileMenu.Append(
            self.MENU_ITEM_DRAW_ALL_FRAMES, "&Draw all frames...",
            "Saves each frame of the stream as an image in the certain folder",
            wx.ITEM_NORMAL)
        self.Bind(wx.EVT_MENU, lambda event: self.drawAllFramesCallback(),
                  fileDraw)
        fileExport = fileMenu.Append(
            self.MENU_ITEM_EXPORT_ALL_FRAMES, "Export all frames...",
            "Saves all frames as data stored in a MATLAB file", wx.ITEM_NORMAL)
        self.Bind(wx.EVT_MENU, lambda event: self.exportAllFramesCallback(),
                  fileExport)
        fileStreamProperties = fileMenu.Append(
            self.MENU_ITEM_STREAM_PROPERTIES, "Stream &properties\tALT+ENTER",
            "Prints all stream properties...", wx.ITEM_NORMAL)
        self.Bind(wx.EVT_MENU, lambda event: self.getStreamProperties(),
                  fileStreamProperties)
        fileMenu.AppendSeparator()
        fileExit = fileMenu.Append(self.MENU_ITEM_EXIT, "&Exit\tCTRL+Q",
                                   "Quits from the program", wx.ITEM_NORMAL)
        self.Bind(wx.EVT_MENU, lambda event: self.Close(), fileExit)
        mainMenu.Append(fileMenu, "&File")

        frameMenu = wx.Menu()
        frameFirst = frameMenu.Append(self.MENU_ITEM_GO_TO_FIRST,
                                      "&First frame\tHOME",
                                      "Moves to the first frame",
                                      wx.ITEM_NORMAL)
        self.Bind(wx.EVT_MENU, lambda event: self.goToFirst(), frameFirst)
        framePrevious = frameMenu.Append(self.MENU_ITEM_GO_TO_PREVIOUS,
                                         "&Previous frame\tKP_4",
                                         "Moves to the previous frame",
                                         wx.ITEM_NORMAL)
        self.Bind(wx.EVT_MENU, lambda event: self.goToPrevious(),
                  framePrevious)
        frameNext = frameMenu.Append(self.MENU_ITEM_GO_TO_NEXT,
                                     "&Next frame\tKP_6",
                                     "Moves to the next frame", wx.ITEM_NORMAL)
        self.Bind(wx.EVT_MENU, lambda event: self.goToNext(), frameNext)
        frameLast = frameMenu.Append(self.MENU_ITEM_GO_TO_LAST,
                                     "&Last frame\tEND",
                                     "Moves to the last frame", wx.ITEM_NORMAL)
        self.Bind(wx.EVT_MENU, lambda event: self.goToLast(), frameLast)
        frameGoto = frameMenu.Append(self.MENU_ITEM_GO_TO, "&Go to...\tCTRL+G",
                                     "Moves to the specified frame",
                                     wx.ITEM_NORMAL)
        self.Bind(wx.EVT_MENU, lambda event: self.goToCallback(), frameGoto)
        frameMenu.AppendSeparator()
        frameSave = frameMenu.Append(self.MENU_ITEM_FRAME_SAVE,
                                     "&Save frame...\tCTRL+S",
                                     "Saves a certain frame", wx.ITEM_NORMAL)
        self.Bind(wx.EVT_MENU, lambda event: self.saveFrameCallback(),
                  frameSave)
        mainMenu.Append(frameMenu, "F&rame")

        viewMenu = wx.Menu()
        viewPlay = viewMenu.Append(self.MENU_ITEM_PLAY, "&Play...\tCTRL+P",
                                   "Plays the stream", wx.ITEM_NORMAL)
        self.Bind(wx.EVT_MENU, lambda event: self.play(), viewPlay)
        viewStop = viewMenu.Append(self.MENU_ITEM_STOP, "&Stop...\tCTRL+L",
                                   "Stops playing of the stream",
                                   wx.ITEM_NORMAL)
        self.Bind(wx.EVT_MENU, lambda event: self.stop(), viewStop)
        viewMenu.AppendSeparator()

        colormapMenu = wx.Menu()
        colormapJet = colormapMenu.Append(
            self.MENU_ITEM_COLORMAP_JET, "&Jet",
            "Specifies colored image representing non-periodic values",
            wx.ITEM_RADIO)
        self.Bind(wx.EVT_MENU, lambda event: self.jet(), colormapJet)
        colormapHsv = colormapMenu.Append(
            self.MENU_ITEM_COLORMAP_HSV, "&Hsv",
            "Speficies colored image representing periodic values",
            wx.ITEM_RADIO)
        self.Bind(wx.EVT_MENU, lambda event: self.hsv(), colormapHsv)
        colormapGray = colormapMenu.Append(
            self.MENU_ITEM_COLORMAP_GRAY, "&Gray",
            "Specifies black-and-white image for non-pediodic values",
            wx.ITEM_RADIO)
        self.Bind(wx.EVT_MENU, lambda event: self.gray(), colormapGray)
        viewMenu.Append(self.MENU_ITEM_COLORMAP, "Color&map", colormapMenu,
                        "Specifies color codes for the matrix values")
        colormapMenu.Check(self.MENU_ITEM_COLORMAP_JET, True)

        viewColorbar = viewMenu.Append(
            self.MENU_ITEM_COLORBAR, "Color&bar",
            "Toggles on/off colorbar at the right of the frame image",
            wx.ITEM_CHECK)
        self.Bind(wx.EVT_MENU, self.colorbarCallback, viewColorbar)
        viewSetLimits = viewMenu.Append(
            self.MENU_ITEM_SET_LIMITS, "Set &limits...",
            "Sets minimum and maximum value for the color axis",
            wx.ITEM_NORMAL)
        self.Bind(wx.EVT_MENU, lambda event: self.setLimitsCallback(),
                  viewSetLimits)
        mainMenu.Append(viewMenu, "&View")

        self.SetMenuBar(mainMenu)

    def __createToolbar(self):
        toolbar = self.CreateToolBar()
        current_dir = os.path.dirname(__file__)

        first_icon_filename = os.path.join(current_dir,
                                           "beginning-media-button-arrow.svg")
        first_icon = wx.Bitmap(first_icon_filename)
        first = toolbar.AddTool(self.TOOL_FIRST, "Go to first frame",
                                first_icon, "Moves to the first frame",
                                wx.ITEM_NORMAL)
        self.Bind(wx.EVT_TOOL, lambda event: self.goToFirst(), first)

        previous_icon_filename = os.path.join(current_dir, "left-arrow.svg")
        previous_icon = wx.Bitmap(previous_icon_filename)
        previous = toolbar.AddTool(self.TOOL_PREVIOUS, "Go to previous frame",
                                   previous_icon,
                                   "Moves to the previous frame",
                                   wx.ITEM_NORMAL)
        self.Bind(wx.EVT_TOOL, lambda event: self.goToPrevious(), previous)

        next_icon_filename = os.path.join(current_dir, "right-arrow.svg")
        next_icon = wx.Bitmap(next_icon_filename)
        next = toolbar.AddTool(self.TOOL_NEXT, "Go to next frame", next_icon,
                               "Moves to the next frame", wx.ITEM_NORMAL)
        self.Bind(wx.EVT_TOOL, lambda event: self.goToNext(), next)

        last_icon_filename = os.path.join(current_dir,
                                          "finishing-media-button-arrow.svg")
        last_icon = wx.Bitmap(last_icon_filename)
        last = toolbar.AddTool(self.TOOL_LAST, "Go to last frame", last_icon,
                               "Moves to the last frame", wx.ITEM_NORMAL)
        self.Bind(wx.EVT_TOOL, lambda event: self.goToLast(), last)

        toolbar.Realize()

    def __createAxes(self):
        panel = wx.Panel(self)

        self.__figure = Figure()
        self.__axes = self.__figure.add_subplot(111)
        self.__canvas = FigureCanvas(panel, -1, self.__figure)
        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(self.__canvas, 1, wx.ALL | wx.EXPAND, 10)
        panel.SetSizer(sizer)
        panel.Fit()

    def drawClosedState(self):
        self.SetTitle("Stream view")
        menu = self.GetMenuBar()
        menu.Enable(self.MENU_ITEM_CLOSE_STREAM, False)
        menu.Enable(self.MENU_ITEM_DRAW_ALL_FRAMES, False)
        menu.Enable(self.MENU_ITEM_EXPORT_ALL_FRAMES, False)
        menu.Enable(self.MENU_ITEM_STREAM_PROPERTIES, False)
        menu.EnableTop(1, False)
        menu.EnableTop(2, False)

        toolbar = self.GetToolBar()
        toolbar.EnableTool(self.TOOL_FIRST, False)
        toolbar.EnableTool(self.TOOL_LAST, False)
        toolbar.EnableTool(self.TOOL_PREVIOUS, False)
        toolbar.EnableTool(self.TOOL_NEXT, False)

        self.__figure.clf()
        self.__canvas.draw()

    def drawFrame(self):
        self.SetTitle("{0} - Stream view".format(
            os.path.basename(self.__filename)))
        menu = self.GetMenuBar()
        tools = self.GetToolBar()

        menu.Enable(self.MENU_ITEM_CLOSE_STREAM, True)
        menu.Enable(self.MENU_ITEM_DRAW_ALL_FRAMES, True)
        menu.Enable(self.MENU_ITEM_EXPORT_ALL_FRAMES, True)
        menu.Enable(self.MENU_ITEM_STREAM_PROPERTIES, True)
        menu.EnableTop(1, True)
        menu.EnableTop(2, True)
        tools.EnableTool(self.TOOL_FIRST, True)
        tools.EnableTool(self.TOOL_LAST, True)

        current_frame = self.__stream.getHeaders()['current_frame']
        if current_frame > 1:
            menu.Enable(self.MENU_ITEM_GO_TO_PREVIOUS, True)
            tools.EnableTool(self.TOOL_PREVIOUS, True)
        else:
            menu.Enable(self.MENU_ITEM_GO_TO_PREVIOUS, False)
            tools.EnableTool(self.TOOL_PREVIOUS, False)

        if current_frame < self.__stream.getHeaders()['nframes']:
            menu.Enable(self.MENU_ITEM_GO_TO_NEXT, True)
            tools.EnableTool(self.TOOL_NEXT, True)
        else:
            menu.Enable(self.MENU_ITEM_GO_TO_NEXT, False)
            tools.EnableTool(self.TOOL_NEXT, False)

        self.__figure.clf()
        ax = self.__figure.add_subplot(111)
        img = ax.imshow(self.__frame,
                        cmap=self.getColormap(),
                        vmin=self.__clim[0],
                        vmax=self.__clim[1])
        ax.set_aspect("equal")
        time = 1000 * (current_frame -
                       1) / self.__stream.getHeaders()['sample_rate']
        ax.set_title("t = {0:.2f} ms".format(time))
        if self.isColorbar():
            self.__figure.colorbar(img)
        self.__canvas.draw()

    def getColormap(self):
        menu = self.GetMenuBar()
        if menu.IsChecked(self.MENU_ITEM_COLORMAP_JET):
            return "jet"
        if menu.IsChecked(self.MENU_ITEM_COLORMAP_HSV):
            return "hsv"
        if menu.IsChecked(self.MENU_ITEM_COLORMAP_GRAY):
            return "gray"

    def isColorbar(self):
        return self.GetMenuBar().IsChecked(self.MENU_ITEM_COLORBAR)

    def loadStreamCallback(self):
        dlg = wx.FileDialog(self,
                            "Open the stream file",
                            style=wx.FD_OPEN | wx.FD_FILE_MUST_EXIST)
        result = dlg.ShowModal()
        if result == wx.ID_CANCEL:
            return
        filename = dlg.GetPath()
        self.loadStream(filename)

    def loadStream(self, filename):
        self.closeStream()
        import vis_brain.streams
        import inspect
        from vis_brain.streams.Stream import Stream
        for module_name in dir(vis_brain.streams):
            instance = getattr(vis_brain.streams, module_name)
            if inspect.isclass(instance):
                if issubclass(instance, Stream):
                    try:
                        self.__loadSpecifiedStream(filename, instance)
                        return
                    except Exception as exc:
                        print(
                            "Stream class {0} gave {1}. Trying another class".
                            format(instance.__name__, exc))
        wx.MessageDialog(
            self, "Unsupported stream format or error opening the stream",
            "Load stream", wx.OK | wx.ICON_ERROR | wx.CENTRE).ShowModal()

    def __loadSpecifiedStream(self, filename, streamclass):
        stream = streamclass(filename, stream_mode="read")
        stream.open()
        self.__filename = filename
        self.__stream = stream
        self.__frame = stream.read()
        self.drawFrame()

    def closeStream(self):
        if self.__stream is not None and self.__stream.getHeaders()['opened']:
            self.__stream.close()
            self.drawClosedState()

    def drawAllFramesCallback(self):
        dlg = wx.DirDialog(self,
                           "Folder where a set of PNG files shall be located")
        if dlg.ShowModal() == wx.ID_OK:
            dirname = dlg.GetPath()
            if not os.path.isdir(dirname):
                os.mkdir(dirname)
            self.drawAllFrames(dirname)

    def drawAllFrames(self, dirname):
        self.goToFirst()
        while self.__stream.getHeaders(
        )['current_frame'] < self.__stream.getHeaders()['nframes']:
            time = (self.__stream.getHeaders()['current_frame'] -
                    1) * 1000.0 / self.__stream.getHeaders()['sample_rate']
            short_file = "t={0}ms.png".format(time)
            full_file = os.path.join(dirname, short_file)
            self.__figure.savefig(full_file)
            self.GetStatusBar().SetStatusText("Saving {0} ms...".format(time))
            self.goToNext()
        self.GetStatusBar().SetStatusText("")

    def exportAllFramesCallback(self):
        dlg = wx.FileDialog(self,
                            "Export all frames to .mat file",
                            wildcard="MAT files (.mat)|*.mat",
                            style=wx.FD_SAVE | wx.FD_OVERWRITE_PROMPT)
        if dlg.ShowModal() == wx.ID_OK:
            filename = dlg.GetPath()
            if filename[-4:] != ".mat":
                filename += ".mat"
            self.exportAllFrames(filename)

    def exportAllFrames(self, filename):
        import scipy.io
        output_data = {
            "stream_name": self.__filename,
            "times": [],
            "time_units": "ms",
            "frames": [],
            "nframes": self.__stream.getHeaders()['nframes'],
            "sample_rate": self.__stream.getHeaders()['sample_rate'],
            "height": self.__stream.getHeaders()['height'],
            "width": self.__stream.getHeaders()['width'],
            "height_um": self.__stream.getHeaders()['height_um'],
            "width_um": self.__stream.getHeaders()['width_um']
        }
        print(self.__stream)
        self.__stream.first()
        while self.__stream.getHeaders(
        )['current_frame'] < self.__stream.getHeaders()['nframes']:
            time = self.__stream.getHeaders(
            )['current_frame'] * 1000 / self.__stream.getHeaders(
            )['sample_rate']
            self.GetStatusBar().SetStatusText(
                "Exporting t = {0} ms".format(time))
            output_data["times"].append(time)
            frame = self.__stream.read()
            output_data["frames"].append(frame)
        output_data['times'] = np.array(output_data['times'])
        scipy.io.savemat(filename, output_data)
        self.GetStatusBar().SetStatusText("")
        self.goToFirst()

    def getStreamProperties(self):
        from .StreamPropertiesWindow import StreamPropertiesWindow
        dlg = StreamPropertiesWindow(self, self.__stream)
        dlg.ShowModal()

    def goToFirst(self):
        try:
            self.__stream.first()
            self.__frame = self.__stream.read()
            self.drawFrame()
        except Exception as err:
            wx.MessageBox(str(err), "Moving to the beginning of the stream",
                          wx.OK | wx.ICON_ERROR | wx.CENTRE)

    def goToPrevious(self):
        try:
            self.__stream.move(-2)
            self.__frame = self.__stream.read()
            self.drawFrame()
        except Exception as err:
            wx.MessageBox(str(err), "Moving to the previous frame",
                          wx.OK | wx.ICON_ERROR | wx.CENTRE)

    def goToNext(self):
        try:
            self.__frame = self.__stream.read()
            self.drawFrame()
        except Exception as err:
            wx.MessageBox(str(err), "Moving to the next frame",
                          wx.OK | wx.ICON_ERROR | wx.CENTRE)

    def autoNext(self):
        headers = self.__stream.getHeaders()
        if headers['current_frame'] == headers['nframes']:
            self.goToFirst()
        else:
            self.goToNext()

    def goToLast(self):
        try:
            self.__stream.last()
            self.__frame = self.__stream.read()
            self.drawFrame()
        except Exception as err:
            wx.MessageBox(str(err), "Moving to the last frame",
                          wx.OK + wx.ICON_ERROR | wx.CENTRE)

    def goToCallback(self):
        from .GoToWindow import GoToWindow
        dlg = GoToWindow(self, self.__stream)
        if dlg.ShowModal() == wx.ID_OK:
            n = dlg.getFrameNumber()
            self.goTo(n)

    def goTo(self, n):
        self.__stream.first()
        self.__stream.move(n)
        self.__frame = self.__stream.read()
        self.drawFrame()

    def saveFrameBin(self, filename):
        if filename[-4:] != ".bin":
            filename += ".bin"
        from vis_brain.readers import BinReader
        reader = BinReader(filename)
        reader.setHeightUm(self.__stream.getHeaders()["height_um"])
        reader.setWidthUm(self.__stream.getHeaders()["width_um"])
        reader.save(self.__frame)

    def saveFrameMat(self, filename):
        if filename[-4:] != ".mat":
            filename += ".mat"
        import scipy.io
        output_data = {
            "stream_name":
            self.__filename,
            "frame_number":
            self.__stream.getHeaders()["current_frame"],
            "frame_time": (self.__stream.getHeaders()["current_frame"] - 1) *
            1000 / self.__stream.getHeaders()['sample_rate'],
            "frame_time_units":
            "ms",
            "height":
            self.__stream.getHeaders()['height'],
            "width":
            self.__stream.getHeaders()["width"],
            "height_um":
            self.__stream.getHeaders()["height_um"],
            "width_um":
            self.__stream.getHeaders()["width_um"],
            "data":
            self.__frame
        }
        scipy.io.savemat(filename, output_data)

    def saveFramePng(self, filename):
        print("SAVE FRAME TO PNG: " + filename)

    def saveFrameCallback(self):
        dlg = wx.FileDialog(
            self,
            "Save Frame",
            wildcard="vis-brain data file (.bin)|*.bin|" +
            "MATLAB/Octave file (.mat)|*.mat|Image (.png)|*.png",
            style=wx.FD_SAVE | wx.FD_OVERWRITE_PROMPT)
        if dlg.ShowModal() == wx.ID_OK:
            filename = dlg.GetPath()
            index = dlg.GetFilterIndex()
            if index == 0:
                self.saveFrameBin(filename)
            if index == 1:
                self.saveFrameMat(filename)
            if index == 2:
                self.saveFramePng(filename)

    def play(self):
        actualTime = 1000 / self.__stream.getHeaders()['sample_rate']
        presentationTime = int(actualTime * 20)
        self.__timer.Start(presentationTime, wx.TIMER_CONTINUOUS)

    def stop(self):
        self.__timer.Stop()

    def jet(self):
        self.drawFrame()

    def hsv(self):
        self.drawFrame()

    def gray(self):
        self.drawFrame()

    def colorbarCallback(self, event):
        self.drawFrame()

    def setLimits(self, minValue, maxValue):
        self.__clim = minValue, maxValue
        self.drawFrame()

    def setLimitsCallback(self):
        from .SetLimitsWindow import SetLimitsWindow
        dlg = SetLimitsWindow(self, self.__clim)
        if dlg.ShowModal() == wx.ID_OK:
            limits = dlg.getLimits()
            self.setLimits(limits[0], limits[1])
Example #34
0
class GraphCanvasPanel(wx.Panel):
    def __init__(self, graphFrame, parent):
        super().__init__(parent)
        self.graphFrame = graphFrame

        # Remove matplotlib font cache, see #234
        try:
            cache_dir = mpl._get_cachedir()
        except (KeyboardInterrupt, SystemExit):
            raise
        except:
            cache_dir = os.path.expanduser(os.path.join('~', '.matplotlib'))
        cache_file = os.path.join(cache_dir, 'fontList.cache')
        if os.access(cache_dir,
                     os.W_OK | os.X_OK) and os.path.isfile(cache_file):
            os.remove(cache_file)

        mainSizer = wx.BoxSizer(wx.VERTICAL)

        self.figure = Figure(figsize=(5, 3), tight_layout={'pad': 1.08})
        rgbtuple = wx.SystemSettings.GetColour(wx.SYS_COLOUR_BTNFACE).Get()
        clr = [c / 255. for c in rgbtuple]
        self.figure.set_facecolor(clr)
        self.figure.set_edgecolor(clr)
        self.canvas = Canvas(self, -1, self.figure)
        self.canvas.SetBackgroundColour(wx.Colour(*rgbtuple))
        self.canvas.mpl_connect('button_press_event', self.OnMplCanvasClick)
        self.subplot = self.figure.add_subplot(111)
        self.subplot.grid(True)
        mainSizer.Add(self.canvas, 1, wx.EXPAND | wx.ALL, 0)

        self.SetSizer(mainSizer)

        self.xMark = None
        self.mplOnDragHandler = None
        self.mplOnReleaseHandler = None

    def draw(self, accurateMarks=True):
        self.subplot.clear()
        self.subplot.grid(True)
        allXs = set()
        allYs = set()
        plotData = {}
        legendData = []
        chosenX = self.graphFrame.ctrlPanel.xType
        chosenY = self.graphFrame.ctrlPanel.yType
        self.subplot.set(xlabel=self.graphFrame.ctrlPanel.formatLabel(chosenX),
                         ylabel=self.graphFrame.ctrlPanel.formatLabel(chosenY))

        mainInput, miscInputs = self.graphFrame.ctrlPanel.getValues()
        view = self.graphFrame.getView()
        sources = self.graphFrame.ctrlPanel.sources
        if view.hasTargets:
            iterList = tuple(
                itertools.product(sources, self.graphFrame.ctrlPanel.targets))
        else:
            iterList = tuple((f, None) for f in sources)

        # Draw plot lines and get data for legend
        for source, target in iterList:
            # Get line style data
            try:
                colorData = BASE_COLORS[source.colorID]
            except KeyError:
                pyfalog.warning('Invalid color "{}" for "{}"'.format(
                    source.colorID, source.name))
                continue
            color = colorData.hsl
            lineStyle = 'solid'
            if target is not None:
                try:
                    lightnessData = LIGHTNESSES[target.lightnessID]
                except KeyError:
                    pyfalog.warning('Invalid lightness "{}" for "{}"'.format(
                        target.lightnessID, target.name))
                    continue
                color = lightnessData.func(color)
                try:
                    lineStyleData = STYLES[target.lineStyleID]
                except KeyError:
                    pyfalog.warning('Invalid line style "{}" for "{}"'.format(
                        target.lightnessID, target.name))
                    continue
                lineStyle = lineStyleData.mplSpec
            color = hsv_to_rgb(hsl_to_hsv(color))

            # Get point data
            try:
                xs, ys = view.getPlotPoints(mainInput=mainInput,
                                            miscInputs=miscInputs,
                                            xSpec=chosenX,
                                            ySpec=chosenY,
                                            src=source,
                                            tgt=target)
                if not self.__checkNumbers(xs, ys):
                    pyfalog.warning(
                        'Failed to plot "{}" vs "{}" due to inf or NaN in values'
                        .format(source.name,
                                '' if target is None else target.name))
                    continue
                plotData[(source, target)] = (xs, ys)
                allXs.update(xs)
                allYs.update(ys)
                # If we have single data point, show marker - otherwise line won't be shown
                if len(xs) == 1 and len(ys) == 1:
                    self.subplot.plot(xs,
                                      ys,
                                      color=color,
                                      linestyle=lineStyle,
                                      marker='.')
                else:
                    self.subplot.plot(xs, ys, color=color, linestyle=lineStyle)
                # Fill data for legend
                if target is None:
                    legendData.append((color, lineStyle, source.shortName))
                else:
                    legendData.append(
                        (color, lineStyle,
                         '{} vs {}'.format(source.shortName,
                                           target.shortName)))
            except (KeyboardInterrupt, SystemExit):
                raise
            except Exception:
                pyfalog.warning('Failed to plot "{}" vs "{}"'.format(
                    source.name, '' if target is None else target.name))
                self.canvas.draw()
                self.Refresh()
                return

        # Setting Y limits for canvas
        if self.graphFrame.ctrlPanel.showY0:
            allYs.add(0)
        canvasMinY, canvasMaxY = self._getLimits(allYs,
                                                 minExtra=0.05,
                                                 maxExtra=0.1)
        canvasMinX, canvasMaxX = self._getLimits(allXs,
                                                 minExtra=0.02,
                                                 maxExtra=0.02)
        self.subplot.set_ylim(bottom=canvasMinY, top=canvasMaxY)
        self.subplot.set_xlim(left=canvasMinX, right=canvasMaxX)
        # Process X marks line
        if self.xMark is not None:
            minX = min(allXs, default=None)
            maxX = max(allXs, default=None)
            if minX is not None and maxX is not None:
                minY = min(allYs, default=None)
                maxY = max(allYs, default=None)
                yDiff = (maxY or 0) - (minY or 0)
                xMark = max(min(self.xMark, maxX), minX)
                # If in top 10% of X coordinates, align labels differently
                if xMark > canvasMinX + 0.9 * (canvasMaxX - canvasMinX):
                    labelAlignment = 'right'
                    labelPrefix = ''
                    labelSuffix = ' '
                else:
                    labelAlignment = 'left'
                    labelPrefix = ' '
                    labelSuffix = ''
                # Draw line
                self.subplot.axvline(x=xMark,
                                     linestyle='dotted',
                                     linewidth=1,
                                     color=(0, 0, 0))
                # Draw its X position
                if chosenX.unit is None:
                    xLabel = '{}{}{}'.format(labelPrefix,
                                             roundToPrec(xMark,
                                                         4), labelSuffix)
                else:
                    xLabel = '{}{} {}{}'.format(labelPrefix,
                                                roundToPrec(xMark, 4),
                                                chosenX.unit, labelSuffix)
                self.subplot.annotate(xLabel,
                                      xy=(xMark, canvasMaxY - 0.01 *
                                          (canvasMaxY - canvasMinY)),
                                      xytext=(0, 0),
                                      annotation_clip=False,
                                      textcoords='offset pixels',
                                      ha=labelAlignment,
                                      va='top',
                                      fontsize='small')
                # Get Y values
                yMarks = set()

                def addYMark(val):
                    if val is None:
                        return
                    # Round according to shown Y range - the bigger the range,
                    # the rougher the rounding
                    if yDiff != 0:
                        rounded = roundToPrec(val, 4, nsValue=yDiff)
                    else:
                        rounded = val
                    # If due to some bug or insufficient plot density we're
                    # out of bounds, do not add anything
                    if minY <= val <= maxY or minY <= rounded <= maxY:
                        yMarks.add(rounded)

                for source, target in iterList:
                    xs, ys = plotData[(source, target)]
                    if not xs or xMark < min(xs) or xMark > max(xs):
                        continue
                    # Fetch values from graphs when we're asked to provide accurate data
                    if accurateMarks:
                        try:
                            y = view.getPoint(x=xMark,
                                              miscInputs=miscInputs,
                                              xSpec=chosenX,
                                              ySpec=chosenY,
                                              src=source,
                                              tgt=target)
                            addYMark(y)
                        except (KeyboardInterrupt, SystemExit):
                            raise
                        except Exception:
                            pyfalog.warning(
                                'Failed to get X mark for "{}" vs "{}"'.format(
                                    source.name,
                                    '' if target is None else target.name))
                            # Silently skip this mark, otherwise other marks and legend display will fail
                            continue
                    # Otherwise just do linear interpolation between two points
                    else:
                        if xMark in xs:
                            # We might have multiples of the same value in our sequence, pick value for the last one
                            idx = len(xs) - xs[::-1].index(xMark) - 1
                            addYMark(ys[idx])
                            continue
                        idx = bisect(xs, xMark)
                        yMark = self._interpolateX(x=xMark,
                                                   x1=xs[idx - 1],
                                                   y1=ys[idx - 1],
                                                   x2=xs[idx],
                                                   y2=ys[idx])
                        addYMark(yMark)

                # Draw Y values
                for yMark in yMarks:
                    self.subplot.annotate('{}{}{}'.format(
                        labelPrefix, yMark, labelSuffix),
                                          xy=(xMark, yMark),
                                          xytext=(0, 0),
                                          textcoords='offset pixels',
                                          ha=labelAlignment,
                                          va='center',
                                          fontsize='small')

        legendLines = []
        for i, iData in enumerate(legendData):
            color, lineStyle, label = iData
            legendLines.append(
                Line2D([0], [0],
                       color=color,
                       linestyle=lineStyle,
                       label=label.replace('$', '\$')))

        if len(legendLines) > 0 and self.graphFrame.ctrlPanel.showLegend:
            legend = self.subplot.legend(handles=legendLines)
            for t in legend.get_texts():
                t.set_fontsize('small')
            for l in legend.get_lines():
                l.set_linewidth(1)

        self.canvas.draw()
        self.Refresh()

    def markXApproximate(self, x):
        if x is not None:
            self.xMark = x
            self.draw(accurateMarks=False)

    def unmarkX(self):
        self.xMark = None
        self.draw()

    @staticmethod
    def _getLimits(vals, minExtra=0, maxExtra=0):
        minVal = min(vals, default=0)
        maxVal = max(vals, default=0)
        # Extend range a little for some visual space
        valRange = maxVal - minVal
        minVal -= valRange * minExtra
        maxVal += valRange * maxExtra
        # Extend by % of value if we show function of a constant
        if minVal == maxVal:
            minVal -= minVal * 0.05
            maxVal += minVal * 0.05
        # If still equal, function is 0, spread out visual space as special case
        if minVal == maxVal:
            minVal -= 5
            maxVal += 5
        return minVal, maxVal

    @staticmethod
    def _interpolateX(x, x1, y1, x2, y2):
        pos = (x - x1) / (x2 - x1)
        y = y1 + pos * (y2 - y1)
        return y

    @staticmethod
    def __checkNumbers(xs, ys):
        for number in itertools.chain(xs, ys):
            if math.isnan(number) or math.isinf(number):
                return False
        return True

    # Matplotlib event handlers
    def OnMplCanvasClick(self, event):
        if event.button == 1:
            if not self.mplOnDragHandler:
                self.mplOnDragHandler = self.canvas.mpl_connect(
                    'motion_notify_event', self.OnMplCanvasDrag)
            if not self.mplOnReleaseHandler:
                self.mplOnReleaseHandler = self.canvas.mpl_connect(
                    'button_release_event', self.OnMplCanvasRelease)
            self.markXApproximate(event.xdata)
        elif event.button == 3:
            self.unmarkX()

    def OnMplCanvasDrag(self, event):
        self.markXApproximate(event.xdata)

    def OnMplCanvasRelease(self, event):
        if event.button == 1:
            if self.mplOnDragHandler:
                self.canvas.mpl_disconnect(self.mplOnDragHandler)
                self.mplOnDragHandler = None
            if self.mplOnReleaseHandler:
                self.canvas.mpl_disconnect(self.mplOnReleaseHandler)
                self.mplOnReleaseHandler = None
            # Do not write markX here because of strange mouse behavior: when dragging,
            # sometimes when you release button, x coordinate changes. To avoid that,
            # we just re-use coordinates set on click/drag and just request to redraw
            # using accurate data
            self.draw(accurateMarks=True)
Example #35
0
class MPL_Panel_base(wx.Panel):
    ''' #MPL_Panel_base面板,可以继承或者创建实例'''
    def __init__(self, parent):
        wx.Panel.__init__(self, parent=parent, id=-1)

        self.Figure = matplotlib.figure.Figure(figsize=(4, 3))
        self.axes = self.Figure.add_axes([0.1, 0.1, 0.8, 0.8])
        self.FigureCanvas = FigureCanvas(self, -1, self.Figure)

        self.NavigationToolbar = NavigationToolbar(self.FigureCanvas)

        self.StaticText = wx.StaticText(self, -1, label='Show Help String')

        self.SubBoxSizer = wx.BoxSizer(wx.HORIZONTAL)
        self.SubBoxSizer.Add(self.NavigationToolbar,
                             proportion=0,
                             border=2,
                             flag=wx.ALL | wx.EXPAND)
        self.SubBoxSizer.Add(self.StaticText,
                             proportion=-1,
                             border=2,
                             flag=wx.ALL | wx.EXPAND)

        self.TopBoxSizer = wx.BoxSizer(wx.VERTICAL)
        self.TopBoxSizer.Add(self.SubBoxSizer,
                             proportion=-1,
                             border=2,
                             flag=wx.ALL | wx.EXPAND)
        self.TopBoxSizer.Add(self.FigureCanvas,
                             proportion=-10,
                             border=2,
                             flag=wx.ALL | wx.EXPAND)

        self.SetSizer(self.TopBoxSizer)

        ###方便调用
        self.pylab = pylab
        self.pl = pylab
        self.pyplot = pyplot
        self.numpy = np
        self.np = np
        self.plt = pyplot

        self.pylab.gray()  # 总是显示灰度图

    def UpdatePlot(self):
        '''#修改图形的任何属性后都必须使用self.UpdatePlot()更新GUI界面 '''
        self.FigureCanvas.draw()

    def plot(self, *args, **kwargs):
        '''#最常用的绘图命令plot '''
        self.axes.plot(*args, **kwargs)
        self.UpdatePlot()

    def imshow(self, im):
        self.axes.imshow(im)
        self.UpdatePlot()

    def semilogx(self, *args, **kwargs):
        ''' #对数坐标绘图命令 '''
        self.axes.semilogx(*args, **kwargs)
        self.UpdatePlot()

    def semilogy(self, *args, **kwargs):
        ''' #对数坐标绘图命令 '''
        self.axes.semilogy(*args, **kwargs)
        self.UpdatePlot()

    def loglog(self, *args, **kwargs):
        ''' #对数坐标绘图命令 '''
        self.axes.loglog(*args, **kwargs)
        self.UpdatePlot()

    def grid(self, flag=True):
        ''' ##显示网格  '''
        if flag:
            self.axes.grid()
        else:
            self.axes.grid(False)

    def title_MPL(self, TitleString="wxMatPlotLib Example In wxPython"):
        ''' # 给图像添加一个标题   '''
        self.axes.set_title(TitleString)

    def xlabel(self, XabelString="X"):
        ''' # Add xlabel to the plotting    '''
        self.axes.set_xlabel(XabelString)

    def ylabel(self, YabelString="Y"):
        ''' # Add ylabel to the plotting '''
        self.axes.set_ylabel(YabelString)

    def xticker(self, major_ticker=1.0, minor_ticker=0.1):
        ''' # 设置X轴的刻度大小 '''
        self.axes.xaxis.set_major_locator(MultipleLocator(major_ticker))
        self.axes.xaxis.set_minor_locator(MultipleLocator(minor_ticker))

    def yticker(self, major_ticker=1.0, minor_ticker=0.1):
        ''' # 设置Y轴的刻度大小 '''
        self.axes.yaxis.set_major_locator(MultipleLocator(major_ticker))
        self.axes.yaxis.set_minor_locator(MultipleLocator(minor_ticker))

    def legend(self, *args, **kwargs):
        ''' #图例legend for the plotting  '''
        self.axes.legend(*args, **kwargs)

    def xlim(self, x_min, x_max):
        ''' # 设置x轴的显示范围  '''
        self.axes.set_xlim(x_min, x_max)

    def ylim(self, y_min, y_max):
        ''' # 设置y轴的显示范围   '''
        self.axes.set_ylim(y_min, y_max)

    def savefig(self, *args, **kwargs):
        ''' #保存图形到文件 '''
        self.Figure.savefig(*args, **kwargs)

    def cla(self):
        ''' # 再次画图前,必须调用该命令清空原来的图形  '''
        self.axes.clear()
        self.Figure.set_canvas(self.FigureCanvas)
        self.UpdatePlot()

    def ShowHelpString(self, HelpString="Show Help String"):
        ''' #可以用它来显示一些帮助信息,如鼠标位置等 '''
        self.StaticText.SetLabel(HelpString)
class DialogWinFunc(wx.Dialog):
    def __init__(self, parent, winFunc):
        self.winFunc = winFunc
        x = numpy.linspace(-numpy.pi, numpy.pi, 1000)
        self.data = numpy.sin(x) + 0j

        wx.Dialog.__init__(self, parent=parent, title="Window Function")

        self.figure = matplotlib.figure.Figure(facecolor='white',
                                               figsize=(5, 4))
        self.figure.suptitle('Window Function')
        self.canvas = FigureCanvas(self, -1, self.figure)
        self.axesWin = self.figure.add_subplot(211)
        self.axesFft = self.figure.add_subplot(212)

        text = wx.StaticText(self, label='Function')

        self.choice = wx.Choice(self, choices=WINFUNC[::2])
        self.choice.SetSelection(WINFUNC[::2].index(winFunc))

        sizerButtons = wx.StdDialogButtonSizer()
        buttonOk = wx.Button(self, wx.ID_OK)
        buttonCancel = wx.Button(self, wx.ID_CANCEL)
        sizerButtons.AddButton(buttonOk)
        sizerButtons.AddButton(buttonCancel)
        sizerButtons.Realize()

        sizerFunction = wx.BoxSizer(wx.HORIZONTAL)
        sizerFunction.Add(text, flag=wx.ALL, border=5)
        sizerFunction.Add(self.choice, flag=wx.ALL, border=5)

        sizerGrid = wx.GridBagSizer(5, 5)
        sizerGrid.Add(self.canvas, pos=(0, 0), span=(1, 2), border=5)
        sizerGrid.Add(sizerFunction,
                      pos=(1, 0),
                      span=(1, 2),
                      flag=wx.ALIGN_CENTRE | wx.ALL,
                      border=5)
        sizerGrid.Add(sizerButtons,
                      pos=(2, 1),
                      flag=wx.ALIGN_RIGHT | wx.ALL,
                      border=5)

        self.Bind(wx.EVT_CHOICE, self.__on_choice, self.choice)
        self.Bind(wx.EVT_BUTTON, self.__on_ok, buttonOk)

        self.__plot()

        self.SetSizerAndFit(sizerGrid)

    def __plot(self):
        pos = WINFUNC[::2].index(self.winFunc)
        function = WINFUNC[1::2][pos](512)

        self.axesWin.clear()
        self.axesWin.plot(function, 'g')
        self.axesWin.set_xlabel('Time')
        self.axesWin.set_ylabel('Multiplier')
        self.axesWin.set_xlim(0, 512)
        self.axesWin.set_xticklabels([])
        self.axesFft.clear()
        self.axesFft.psd(self.data, NFFT=512, Fs=1000, window=function)
        self.axesFft.set_xlabel('Frequency')
        self.axesFft.set_ylabel('$\mathsf{dB/\sqrt{Hz}}$')
        self.axesFft.set_xlim(-256, 256)
        self.axesFft.set_xticklabels([])
        self.figure.tight_layout()

        self.canvas.draw()

    def __on_choice(self, _event):
        self.winFunc = WINFUNC[::2][self.choice.GetSelection()]
        self.plot()

    def __on_ok(self, _event):
        self.EndModal(wx.ID_OK)

    def get_win_func(self):
        return self.winFunc
    def __init__(self, parent, device, offset, winFunc):
        self.device = device
        self.offset = offset * 1e3
        self.winFunc = winFunc
        self.band1 = None
        self.band2 = None

        wx.Dialog.__init__(self, parent=parent, title="Scan Offset")

        figure = matplotlib.figure.Figure(facecolor='white')
        self.axes = figure.add_subplot(111)
        self.canvas = FigureCanvas(self, -1, figure)

        textHelp = wx.StaticText(
            self,
            label="Remove the aerial and press refresh, "
            "adjust the offset so the shaded areas overlay the flattest parts "
            "of the plot_line.")

        textFreq = wx.StaticText(self, label="Test frequency (MHz)")
        self.spinFreq = wx.SpinCtrl(self)
        self.spinFreq.SetRange(F_MIN, F_MAX)
        self.spinFreq.SetValue(200)

        textGain = wx.StaticText(self, label="Test gain (dB)")
        self.spinGain = wx.SpinCtrl(self)
        self.spinGain.SetRange(-100, 200)
        self.spinGain.SetValue(200)

        refresh = wx.Button(self, wx.ID_ANY, 'Refresh')
        self.Bind(wx.EVT_BUTTON, self.__on_refresh, refresh)

        textOffset = wx.StaticText(self, label="Offset (kHz)")
        self.spinOffset = wx.SpinCtrl(self)
        self.spinOffset.SetRange(0, ((SAMPLE_RATE / 2) - BANDWIDTH) / 1e3)
        self.spinOffset.SetValue(offset)
        self.Bind(wx.EVT_SPINCTRL, self.__on_spin, self.spinOffset)

        sizerButtons = wx.StdDialogButtonSizer()
        buttonOk = wx.Button(self, wx.ID_OK)
        buttonCancel = wx.Button(self, wx.ID_CANCEL)
        sizerButtons.AddButton(buttonOk)
        sizerButtons.AddButton(buttonCancel)
        sizerButtons.Realize()
        self.Bind(wx.EVT_BUTTON, self.__on_ok, buttonOk)

        boxSizer1 = wx.BoxSizer(wx.HORIZONTAL)
        boxSizer1.Add(textFreq, border=5)
        boxSizer1.Add(self.spinFreq, border=5)
        boxSizer1.Add(textGain, border=5)
        boxSizer1.Add(self.spinGain, border=5)

        boxSizer2 = wx.BoxSizer(wx.HORIZONTAL)
        boxSizer2.Add(textOffset, border=5)
        boxSizer2.Add(self.spinOffset, border=5)

        gridSizer = wx.GridBagSizer(5, 5)
        gridSizer.Add(self.canvas,
                      pos=(0, 0),
                      span=(1, 2),
                      flag=wx.ALIGN_CENTRE | wx.ALL,
                      border=5)
        gridSizer.Add(textHelp,
                      pos=(1, 0),
                      span=(1, 2),
                      flag=wx.ALIGN_CENTRE | wx.ALL,
                      border=5)
        gridSizer.Add(boxSizer1,
                      pos=(2, 0),
                      span=(1, 2),
                      flag=wx.ALIGN_CENTRE | wx.ALL,
                      border=5)
        gridSizer.Add(refresh,
                      pos=(3, 0),
                      span=(1, 2),
                      flag=wx.ALIGN_CENTRE | wx.ALL,
                      border=5)
        gridSizer.Add(boxSizer2,
                      pos=(4, 0),
                      span=(1, 2),
                      flag=wx.ALIGN_CENTRE | wx.ALL,
                      border=5)
        gridSizer.Add(sizerButtons,
                      pos=(5, 1),
                      flag=wx.ALIGN_RIGHT | wx.ALL,
                      border=5)

        self.SetSizerAndFit(gridSizer)
        self.__draw_limits()

        self.__setup_plot()
class DialogOffset(wx.Dialog):
    def __init__(self, parent, device, offset, winFunc):
        self.device = device
        self.offset = offset * 1e3
        self.winFunc = winFunc
        self.band1 = None
        self.band2 = None

        wx.Dialog.__init__(self, parent=parent, title="Scan Offset")

        figure = matplotlib.figure.Figure(facecolor='white')
        self.axes = figure.add_subplot(111)
        self.canvas = FigureCanvas(self, -1, figure)

        textHelp = wx.StaticText(
            self,
            label="Remove the aerial and press refresh, "
            "adjust the offset so the shaded areas overlay the flattest parts "
            "of the plot_line.")

        textFreq = wx.StaticText(self, label="Test frequency (MHz)")
        self.spinFreq = wx.SpinCtrl(self)
        self.spinFreq.SetRange(F_MIN, F_MAX)
        self.spinFreq.SetValue(200)

        textGain = wx.StaticText(self, label="Test gain (dB)")
        self.spinGain = wx.SpinCtrl(self)
        self.spinGain.SetRange(-100, 200)
        self.spinGain.SetValue(200)

        refresh = wx.Button(self, wx.ID_ANY, 'Refresh')
        self.Bind(wx.EVT_BUTTON, self.__on_refresh, refresh)

        textOffset = wx.StaticText(self, label="Offset (kHz)")
        self.spinOffset = wx.SpinCtrl(self)
        self.spinOffset.SetRange(0, ((SAMPLE_RATE / 2) - BANDWIDTH) / 1e3)
        self.spinOffset.SetValue(offset)
        self.Bind(wx.EVT_SPINCTRL, self.__on_spin, self.spinOffset)

        sizerButtons = wx.StdDialogButtonSizer()
        buttonOk = wx.Button(self, wx.ID_OK)
        buttonCancel = wx.Button(self, wx.ID_CANCEL)
        sizerButtons.AddButton(buttonOk)
        sizerButtons.AddButton(buttonCancel)
        sizerButtons.Realize()
        self.Bind(wx.EVT_BUTTON, self.__on_ok, buttonOk)

        boxSizer1 = wx.BoxSizer(wx.HORIZONTAL)
        boxSizer1.Add(textFreq, border=5)
        boxSizer1.Add(self.spinFreq, border=5)
        boxSizer1.Add(textGain, border=5)
        boxSizer1.Add(self.spinGain, border=5)

        boxSizer2 = wx.BoxSizer(wx.HORIZONTAL)
        boxSizer2.Add(textOffset, border=5)
        boxSizer2.Add(self.spinOffset, border=5)

        gridSizer = wx.GridBagSizer(5, 5)
        gridSizer.Add(self.canvas,
                      pos=(0, 0),
                      span=(1, 2),
                      flag=wx.ALIGN_CENTRE | wx.ALL,
                      border=5)
        gridSizer.Add(textHelp,
                      pos=(1, 0),
                      span=(1, 2),
                      flag=wx.ALIGN_CENTRE | wx.ALL,
                      border=5)
        gridSizer.Add(boxSizer1,
                      pos=(2, 0),
                      span=(1, 2),
                      flag=wx.ALIGN_CENTRE | wx.ALL,
                      border=5)
        gridSizer.Add(refresh,
                      pos=(3, 0),
                      span=(1, 2),
                      flag=wx.ALIGN_CENTRE | wx.ALL,
                      border=5)
        gridSizer.Add(boxSizer2,
                      pos=(4, 0),
                      span=(1, 2),
                      flag=wx.ALIGN_CENTRE | wx.ALL,
                      border=5)
        gridSizer.Add(sizerButtons,
                      pos=(5, 1),
                      flag=wx.ALIGN_RIGHT | wx.ALL,
                      border=5)

        self.SetSizerAndFit(gridSizer)
        self.__draw_limits()

        self.__setup_plot()

    def __setup_plot(self):
        self.axes.clear()
        self.band1 = None
        self.band2 = None
        self.axes.set_xlabel("Frequency (MHz)")
        self.axes.set_ylabel('Level ($\mathsf{dB/\sqrt{Hz}}$)')
        self.axes.set_yscale('log')
        self.axes.set_xlim(-1, 1)
        self.axes.set_ylim(auto=True)
        self.axes.grid(True)
        self.__draw_limits()

    def __plot(self, capture):
        self.__setup_plot()
        pos = WINFUNC[::2].index(self.winFunc)
        function = WINFUNC[1::2][pos]
        powers, freqs = matplotlib.mlab.psd(capture,
                                            NFFT=1024,
                                            Fs=SAMPLE_RATE / 1e6,
                                            window=function(1024))

        plot = []
        for x, y in itertools.izip(freqs, powers):
            plot.append((x, y))
        plot.sort()
        x, y = numpy.transpose(plot)
        self.axes.plot(x, y, linewidth=0.4)
        self.canvas.draw()

    def __on_ok(self, _event):
        self.EndModal(wx.ID_OK)

    def __on_refresh(self, _event):
        dlg = wx.BusyInfo('Please wait...')

        try:
            if self.device.isDevice:
                sdr = rtlsdr.RtlSdr(self.device.indexRtl)
            else:
                sdr = RtlTcp(self.device.server, self.device.port, None)
            sdr.set_sample_rate(SAMPLE_RATE)
            sdr.set_center_freq(self.spinFreq.GetValue() * 1e6)
            sdr.set_gain(self.spinGain.GetValue())
            capture = sdr.read_samples(2**21)
            sdr.close()
        except IOError as error:
            if self.device.isDevice:
                message = error.message
            else:
                message = error
            dlg.Destroy()
            dlg = wx.MessageDialog(self, 'Capture failed:\n{}'.format(message),
                                   'Error', wx.OK | wx.ICON_ERROR)
            dlg.ShowModal()
            dlg.Destroy()
            return

        self.__plot(capture)

        dlg.Destroy()

    def __on_spin(self, _event):
        self.offset = self.spinOffset.GetValue() * 1e3
        self.__draw_limits()

    def __draw_limits(self):
        limit1 = self.offset
        limit2 = limit1 + BANDWIDTH / 2
        limit1 /= 1e6
        limit2 /= 1e6
        if self.band1 is not None:
            self.band1.remove()
        if self.band2 is not None:
            self.band2.remove()
        self.band1 = self.axes.axvspan(limit1, limit2, color='g', alpha=0.25)
        self.band2 = self.axes.axvspan(-limit1, -limit2, color='g', alpha=0.25)
        self.canvas.draw()

    def get_offset(self):
        return self.offset / 1e3
class KMatrixFrame(util.GenericView):

    helpTitle = "Help"
    helpMessage = """Run K"""
    helpPage = os.environ["RTTOV_GUI_PREFIX"] + "/doc/helpKMatrixFrame.html"

    def __init__(self, parent, title, fname, runNumber=1):
        util.GenericView.__init__(self, parent, title)

        self.CreateMenuBar()
        self.runNumber = runNumber
        self.mykProfileView = None
        self.SetSize((900, 650))
        self.SetPosition((10, 10))
        self.sbgen = self.CreateStatusBar()
        self.sbgen.SetBackgroundColour('WHITE')
        txt = 'KMatrix file = %s' % fname
        self.sbgen.SetStatusText(txt)

        # timer affichage StatusBar
        self.txtsb = ''
        self.timer = wx.Timer(self)
        self.Bind(wx.EVT_TIMER, self.refreshSB, self.timer)
        """ read kmat.h5 file """
        self.fh5 = fname
        self.kmat = rttov.kmatrix.Kmatrix()
        self.kmat101 = rttov.kmatrix.Kmatrix()
        """ read profile in kmat.h5 """
        self.baseProfile = rttov.profile.Profile()
        self.baseProfile = rmodel.project.OpenAProfile(self.fh5, 1)
        t0 = time.clock()
        frad = h5py.File(self.fh5, 'r')
        h5 = frad['/']
        self.kmat.loadh5(h5)
        frad.close()

        t1 = time.clock()
        txt = 'lecture fichier %s : %d sec.' % (self.fh5, (t1 - t0))

        self.sat = self.kmat.misc['SATELLITE']
        self.ins = self.kmat.misc['INSTRUMENT']

        self.lev = self.kmat.profile['NLEVELS']
        self.tabP = self.kmat.profile['P']
        #
        #  growth the levels  < 101
        #
        #  map the levels

        self.tabilevels = np.zeros(levx, int)
        for l in range(0, levx):
            self.tabilevels[l] = round(l * self.lev / levx)

        if self.lev < levx:
            tabNP = np.zeros(levx)
            for l in range(0, levx):
                tabNP[l] = self.tabP[self.tabilevels[l]]
            self.tabP = tabNP

        self.tabW = self.kmat.misc['WAVENUMBERS']
        self.tabY = {}

        self.chn = self.kmat.kmatrix['T'].shape[1]
        """
        gasplot : 0.0 not shown ?
        """
        self.tcomm = {}
        self.tunit = {}
        self.tcbar = {}
        self.gasplot = []
        for gas in ['T', 'Q'] + gaslist:
            if self.kmat.kmatrix[gas] is None:
                continue
            kmin = np.amin(self.kmat.kmatrix[gas])
            kmax = np.amax(self.kmat.kmatrix[gas])
            self.tcbar[gas] = 1
            if kmin == 0.0 and kmax == 0.0:
                self.tcbar[gas] = 0

            attr = '%s_ATTRIBUTE' % gas
            self.tcomm[gas] = self.kmat.kmatrix[attr]['COMMENT']
            self.tunit[gas] = self.kmat.kmatrix[attr]['UNITS']

            if not gas == 'T' and not gas == 'Q':
                self.gasplot.append(gas)

#
# init figure
#
        self.fig = figPlot()
        self.cnv = FigureCanvas(self, -1, self.fig)
        self.cnv.mpl_connect('motion_notify_event', self.onMMotion)
        self.cnv.mpl_connect('key_press_event', self.onkeypress)
        #
        # subplot width
        #
        self.barwidth = max(1, int(wix / self.chn))
        self.yMax = self.lev
        if self.chn >= chnx:
            self.xMax = self.chn
        else:
            self.xMax = self.barwidth * self.chn

        self.txtsb = '%s / %s' % (self.sat.replace(
            ' ', '').upper(), self.ins.upper())

        #
        # choice gas in subplot 313
        #
        self.glabel = {}
        self.gasID = {}

        self.tlb = MyCustomToolbar(self.cnv)

        if len(self.gasplot) > 1:
            for ig in self.gasplot:
                self.gasID[ig] = wx.NewId()
                self.glabel[self.gasID[ig]] = ig
                ico = os.environ["RTTOV_GUI_PREFIX"] + '/icons/%s.png' % ig
                self.tlb.AddSimpleTool(self.gasID[ig], _load_bitmap(ico), ig,
                                       '')
                wx.EVT_TOOL(self.tlb, self.gasID[ig], self.gaschoice)

#
# toolbar : custom buttons
#
        self.LEFTLEFT_ID = wx.NewId()
        self.tlb.AddSimpleTool(self.LEFTLEFT_ID, _load_bitmap('hand.xpm'),
                               'One screen left', '')
        wx.EVT_TOOL(self.tlb, self.LEFTLEFT_ID, self.onleftleft)

        self.LEFT_ID = wx.NewId()
        self.tlb.AddSimpleTool(self.LEFT_ID, _load_bitmap('stock_left.xpm'),
                               'left', '')
        wx.EVT_TOOL(self.tlb, self.LEFT_ID, self.onleft)

        self.RIGHT_ID = wx.NewId()
        self.tlb.AddSimpleTool(self.RIGHT_ID, _load_bitmap('stock_right.xpm'),
                               'right', '')
        wx.EVT_TOOL(self.tlb, self.RIGHT_ID, self.onright)

        self.RIGHTRIGHT_ID = wx.NewId()
        self.tlb.AddSimpleTool(self.RIGHTRIGHT_ID, _load_bitmap('hand.xpm'),
                               'One screen right', '')
        wx.EVT_TOOL(self.tlb, self.RIGHTRIGHT_ID, self.onrightright)

        self.UP_ID = wx.NewId()
        self.tlb.AddSimpleTool(self.UP_ID, _load_bitmap('stock_up.xpm'),
                               'scroll up', '')
        wx.EVT_TOOL(self.tlb, self.UP_ID, self.onup)

        self.DOWN_ID = wx.NewId()
        self.tlb.AddSimpleTool(self.DOWN_ID, _load_bitmap('stock_down.xpm'),
                               'scroll down', '')
        wx.EVT_TOOL(self.tlb, self.DOWN_ID, self.ondown)
        #
        # add kscale icon : K / K%
        #
        self.scalek = 0
        self.SCALE10K_ID = wx.NewId()
        self.tlb.AddSimpleTool(
            self.SCALE10K_ID,
            _load_bitmap(os.environ["RTTOV_GUI_PREFIX"] + '/icons/k10.png'),
            'scale Kx10%', '')
        wx.EVT_TOOL(self.tlb, self.SCALE10K_ID, self.onscale10k)

        self.RESETK_ID = wx.NewId()
        self.tlb.AddSimpleTool(
            self.RESETK_ID,
            _load_bitmap(os.environ["RTTOV_GUI_PREFIX"] + '/icons/reset.png'),
            'reset K', '')
        wx.EVT_TOOL(self.tlb, self.RESETK_ID, self.onresetk)

        #
        # add box : select channel
        #
        self.SELCHAN_ID = wx.NewId()
        self.tlb.AddSimpleTool(
            self.SELCHAN_ID,
            _load_bitmap(os.environ["RTTOV_GUI_PREFIX"] + '/icons/kP.png'),
            'select channnel', '')
        wx.EVT_TOOL(self.tlb, self.SELCHAN_ID, self.onselchan)

        self.tlb.Realize()

        # canvas and toolbar in sizer
        sizer = wx.BoxSizer(wx.VERTICAL)

        sizer.Add(self.tlb, 0, wx.GROW)
        sizer.Add(self.cnv, 1, wx.LEFT | wx.TOP | wx.GROW)
        self.SetSizer(sizer)

        self.Fit()
        #
        self.kprof = None
        #

        self.subP = {}
        self.cax = {}
        #
        # subplots T and Q
        #
        self.subP['T'] = self.fig.add_subplot(3, 1, 1)
        self.tabY['T'] = self.extract_kgas('T')
        tt = '%s : %s' % ('T', self.tcomm['T'])
        self.subP['T'].set_title(tt)
        img = self.subP['T'].imshow(self.tabY['T'], origin='upper')
        self.subP['T'].set_ylabel('P levels')
        divider = make_axes_locatable(self.subP['T'])
        self.cax['T'] = divider.append_axes("right", size="1%", pad=0.05)
        self.fig.colorbar(img, cax=self.cax['T'])
        self.subP['T'].set_xlim([0, min(self.xMax, wix)])
        self.draw_plot('T', 'T',
                       self.kmat.kmatrix['%s_ATTRIBUTE' % 'T']['COMMENT'])

        self.subP['Q'] = self.fig.add_subplot(3,
                                              1,
                                              2,
                                              sharex=self.subP['T'],
                                              sharey=self.subP['T'])
        self.tabY['Q'] = self.extract_kgas('Q')
        tt = '%s : %s' % ('Q', self.tcomm['Q'])
        self.subP['Q'].set_title(tt)
        img = self.subP['Q'].imshow(self.tabY['Q'], origin='upper')
        self.subP['Q'].set_ylabel('P levels')
        divider = make_axes_locatable(self.subP['Q'])
        self.cax['Q'] = divider.append_axes("right", size="1%", pad=0.05)
        self.fig.colorbar(img, cax=self.cax['Q'])
        self.subP['Q'].set_xlim([0, min(self.xMax, wix)])
        self.draw_plot('Q', 'Q',
                       self.kmat.kmatrix['%s_ATTRIBUTE' % 'Q']['COMMENT'])

        #
        # subplot other gases if exist
        #
        if self.gasplot:
            for gas in self.gasplot:
                self.tabY[gas] = self.extract_kgas(gas)

            gas = self.gasplot[0]
            self.subP['G'] = self.fig.add_subplot(3,
                                                  1,
                                                  3,
                                                  sharex=self.subP['T'],
                                                  sharey=self.subP['T'])
            tt = '%s : %s' % (gas, self.tcomm[gas])
            self.subP['G'].set_title(tt)
            img = self.subP['G'].imshow(self.tabY[gas], origin='upper')
            self.subP['G'].set_ylabel('P levels')

            divider = make_axes_locatable(self.subP['G'])
            self.cax['G'] = divider.append_axes("right", size="1%", pad=0.05)
            self.fig.colorbar(img, cax=self.cax['G'])

            self.subP['G'].set_xlim([0, min(self.xMax, wix)])
            self.draw_plot('G', gas,
                           self.kmat.kmatrix['%s_ATTRIBUTE' % gas]['COMMENT'])

        self.fig.tight_layout()
        self.fig.canvas.draw()

    def zoomp(self, evt):
        zp = int(self.szp.val)
        print "z :", zp
        axes = self.subP['T']
        y1, y2 = axes.get_ylim()
        ym = (y1 - y2) / 2
        print 'avant :', y1, y2, ym
        yy1 = ym + 50 / zp
        yy2 = ym - 50 / zp
        axes.set_ylim(yy1, yy2)
        print 'apres :', yy1, yy2
        self.redraw_fig()

    def gaschoice(self, evt):
        gas = self.glabel[evt.GetId()]
        self.draw_plot('G', gas, self.tcomm[gas])
        return

    def onkeypress(self, evt):
        if (evt.key == 'p' or evt.key == 'P') and evt.inaxes:

            if self.chn > chnx:
                c = int(round(evt.xdata)) + 1
            else:
                c = int(round(evt.xdata) / self.barwidth) + 1

            # print 'x=', evt.xdata ,' c=',c
            if c < 0 or c > self.chn:
                return

            txt = 'display profile channel : %d from %s' % (c, self.fh5)
            self.writeSB(txt, 'green', 5, 1)
            pchan = self.kmat.getchanprof(c - 1)

            self.mykProfileView = rview.kprofileframe.KProfileView(
                self,
                pchan,
                channel=c,
                baseProfile=self.baseProfile,
                runNumber=self.runNumber)

    def extract_kgas(self, gas):

        # levels : 101 niveaux qqsoit le profil

        tab101 = np.zeros((levx, self.chn))
        for l in range(0, levx):
            tab101[l][:] = self.kmat.kmatrix[gas][self.tabilevels[l]][:]

        self.kmat101.kmatrix[gas] = tab101

        if self.chn >= chnx:
            return self.kmat101.kmatrix[gas]
        else:
            tY = np.zeros(shape=((self.barwidth) * self.chn, levx))

            kmin = np.amin(self.kmat101.kmatrix[gas])
            kmax = np.amax(self.kmat101.kmatrix[gas])
            kmoy = (kmax + kmin) / 2
            pc = 0
            for ic in range(0, self.chn):

                for ir in range(0, self.barwidth - 1):
                    tY[pc] = np.transpose(self.kmat101.kmatrix[gas])[ic]
                    pc += 1
#
# separation bandes
#
                tY[pc] = kmoy
                pc += 1

            return np.transpose(tY)

    # pan the graph to the left
    def onleftleft(self, evt):
        if evt.GetId() == self.LEFTLEFT_ID:
            axes = self.cnv.figure.axes[0]
            x1, x2 = axes.get_xlim()
            shift = x2 - x1
            if x1 - shift <= 0:
                axes.set_xlim(0, shift)
            else:
                axes.set_xlim(x1 - shift, x2 - shift)
            self.redraw_fig()

    def onleft(self, evt):
        if evt.GetId() == self.LEFT_ID:
            axes = self.cnv.figure.axes[0]
            x1, x2 = axes.get_xlim()
            shift = (x2 - x1) / 10
            axes.set_xlim(x1 - shift, x2 - shift)
            self.redraw_fig()

    def onrightright(self, evt):
        if evt.GetId() == self.RIGHTRIGHT_ID:
            axes = self.cnv.figure.axes[0]
            x1, x2 = axes.get_xlim()
            shift = x2 - x1
            if x2 + shift >= self.xMax:
                axes.set_xlim(self.xMax - shift, self.xMax)
            else:
                axes.set_xlim(x1 + shift, x2 + shift)
            self.redraw_fig()

    def onright(self, evt):
        if evt.GetId() == self.RIGHT_ID:
            axes = self.cnv.figure.axes[0]
            x1, x2 = axes.get_xlim()
            shift = (x2 - x1) / 10
            axes.set_xlim(x1 + shift, x2 + shift)
            self.redraw_fig()

    def onup(self, evt):
        if evt.GetId() == self.UP_ID:
            axes = self.cnv.figure.axes[0]
            y1, y2 = axes.get_ylim()
            axes.set_ylim(y1 - 1, y2 - 1)
            self.redraw_fig()

    def ondown(self, evt):
        if evt.GetId() == self.DOWN_ID:
            axes = self.cnv.figure.axes[0]
            y1, y2 = axes.get_ylim()
            axes.set_ylim(y1 + 1, y2 + 1)
            self.redraw_fig()

    def redraw_y(self):
        axes = self.cnv.figure.axes[0]
        y1, y2 = axes.get_ylim()
        axes.set_ylim(y1, y2)

    # scale K-K%
    def onscale5k(self, evt):
        if evt.GetId() == self.SCALE5K_ID:
            self.scalexk(0.05)

    def onscale10k(self, evt):
        if evt.GetId() == self.SCALE10K_ID:
            self.scalexk(0.1)

    def onscale20k(self, evt):
        if evt.GetId() == self.SCALE20K_ID:
            self.scalexk(0.2)

    def scalexk(self, coeff):
        if self.scalek == 1:
            return

        self.scalek = 1
        text = 'init kmatrix scale'
        self.writeSB(text, 'yellow', 5, 1)
        t1 = time.clock()
        print "Q :", self.tabY['Q'].shape
        self.kmat.kscale(coeff)
        t2 = time.clock()
        text1 = 'end k scale : %s seconds' % (t2 - t1)
        self.writeSB(text, 'green', 5, 1)

        #
        # update for all present gases
        #
        for ig in ['Q'] + self.gasplot:
            self.tabY[ig] = self.extract_kgas(ig)
            self.tcomm[ig] = '%s scaled by %3.2f input profile' % (
                self.tcomm[ig], coeff)

#
# redraw subplots
#
        for a in self.cnv.figure.axes:
            gas = a.get_title().split(' :')[0]
            if gas == 'T':
                continue
            elif gas:
                if gas == 'Q':
                    plot = 'Q'
                else:
                    plot = 'G'

                img = self.subP[plot].imshow(self.tabY[gas], origin='upper')
                self.fig.colorbar(img, cax=self.cax[plot])
                tt = '%s : %s' % (gas, self.tcomm[gas])
                self.subP[plot].set_title(tt)
                self.draw_plot(plot, gas, self.tcomm[gas])

        self.redraw_fig()
        t3 = time.clock()
        text2 = ' / update graph % sec.' % (t3 - t2)
        self.writeSB(text1 + text2, 'green', 5, 1)

    def onresetk(self, evt):
        if self.scalek == 0:
            return
        self.scalek = 0
        text = 'init kmatix reset'
        self.writeSB(text, 'yellow', 5, 1)
        t1 = time.clock()
        frad = h5py.File(self.fh5, 'r')
        h5 = frad['/']
        self.kmat.loadh5(h5)
        frad.close()
        t2 = time.clock()
        text1 = 'end k reset : %s seconds' % (t2 - t1)

        #
        # update for all present gases
        #
        for ig in ['Q'] + self.gasplot:
            self.tabY[ig] = self.extract_kgas(ig)
            attr = '%s_ATTRIBUTE' % ig
            self.tcomm[ig] = self.kmat.kmatrix[attr]['COMMENT']

        for a in self.cnv.figure.axes:
            gas = a.get_title().split(' :')[0]
            if gas == 'T':
                continue
            elif gas:
                if gas == 'Q':
                    self.draw_plot('Q', 'Q', self.tcomm[gas])
                else:
                    self.draw_plot('G', gas, self.tcomm[gas])

        self.redraw_fig()
        t3 = time.clock()
        text2 = ' / update graph % sec.' % (t3 - t2)
        self.writeSB(text1 + text2, 'green', 5, 1)

    def onselchan(self, evt):
        if evt.GetId() != self.SELCHAN_ID:
            return

        txtbox = 'Select a channel number [%01d..%d] : ' % (1, self.chn)
        chnbox = util.SimpleFSDialogBox(self,
                                        -1,
                                        "Select channel",
                                        text=txtbox,
                                        text2="Channel",
                                        minval=1,
                                        maxval=self.chn,
                                        increment=1)
        chnbox.CenterOnParent()
        if (chnbox.ShowModal() == wx.ID_OK):
            c = chnbox.GetSelections()
            txt = 'display profile channel : %d from %s' % (c, self.fh5)
            self.writeSB(txt, 'green', 5, 1)
            pchan = self.kmat.getchanprof(c - 1)
            self.mykProfileView = rview.kprofileframe.KProfileView(
                self,
                pchan,
                channel=c,
                baseProfile=self.baseProfile,
                runNumber=self.runNumber)

            chnbox.Destroy()

    def draw_plot(self, plot, gas, comment):
        tt = '%s : %s' % (gas, comment)
        self.subP[plot].set_title(tt)
        img = self.subP[plot].imshow(self.tabY[gas], origin='upper')
        if self.tcbar[gas]:
            self.fig.colorbar(img, cax=self.cax[plot])

# x ticks = channel number
        if self.chn <= chnx:
            if self.chn <= 10:
                xtl = []
                xtp = []
                if gas == "T":
                    for i in range(0, self.chn + 1):
                        xtl.append(i + 1)
                        xtp.append((xtl[i] - 1) * self.barwidth +
                                   int(self.barwidth) / 2)

                    self.subP[gas].set_xticks(xtp)
                    self.subP[gas].set_xticklabels(xtl)
            else:
                xtl = []
                xtp = []
                if gas == "T":
                    for i in range(0, (self.chn + 1) / 2):
                        xtl.append(2 * i + 1)
                        xtp.append(
                            int(self.barwidth / 2) +
                            (xtl[i] - 1) * self.barwidth)

                    self.subP[gas].set_xticks(xtp)
                    self.subP[gas].set_xticklabels(
                        xtl, horizontalalignment='center')

        else:

            xa = self.subP[plot].get_xaxis()
            xa.set_major_locator(MaxNLocator(nbins=10, integer=True))

        self.redraw_fig()

    def redraw_fig(self):
        #
        # for each axes compute and set yticklables
        #
        taxes = self.fig.get_axes()
        for ax in range(0, len(taxes)):
            if taxes[ax].get_title():
                ylabs = np.zeros(len(taxes[ax].get_yticks()), int)
                for yl in range(0, len(taxes[ax].get_yticks())):
                    ylabs[yl] = (int(
                        round(taxes[ax].get_yticks()[yl] * self.lev / levx)))
                    taxes[ax].set_yticklabels(ylabs)

        self.fig.tight_layout()
        self.fig.canvas.draw_idle()

        return

    def MenuData(self):
        return (
            (
                "&File",  # File Menu
                ('&Quit', 'Quit', self.OnQuit, "quit", True)),
            (
                "&Help",  # Help Menu
                ("About", "About screen", self.OnAbout, "about", True),
                ("&Help", "Help", self.OnHelpHTML, "help", True)))

    def onMMotion(self, evt):
        if evt.inaxes:
            gas = evt.inaxes.title.get_text().split(' :')[0]

            if self.chn > chnx:
                c = int(round(evt.xdata)) + 1
            else:
                c = int(round(evt.xdata) / self.barwidth) + 1

            # print 'x=', evt.xdata ,' c=',c, 'xmax=', self.xMax
            if c < 0 or c > self.xMax:
                return

            y = int(evt.ydata)
            # separation canaux
            if (c > 1 and self.barwidth > 1
                    and round(evt.xdata) % self.barwidth == 0.0):
                self.writeSB('channel separator', 'grey', 5, 0)
                return


#
# pression, canal, k
#
            try:
                tabwc = self.tabW[c - 1]
            except:
                tabwc = self.tabW

            try:
                k = self.tabY[gas][y][int(round(evt.xdata))]

                if tabwc >= wnx:
                    txt0 = ' %s=%.3f %sm]' % (u'\u03BB',
                                              (10000 / tabwc), u'\u03BC')
                else:
                    txt0 = ' %s=%.4f GHz]' % (u'\u03BD',
                                              (spl * tabwc / 1000000000))
                mylevel = self.tabilevels[y] + 1
                text = "%s : C=#%d P(%d)=%.3f hPa k=%g %s [wn=%.3f cm-1" % (
                    gas, c, mylevel, self.tabP[y], k, self.tunit[gas],
                    tabwc) + txt0
                #
                # ecriture message dans status bar
                #
                self.writeSB(text, 'grey', 15, 0)
            except:
                return
    def __init__(self, parent, title, fname, runNumber=1):
        util.GenericView.__init__(self, parent, title)

        self.CreateMenuBar()
        self.runNumber = runNumber
        self.mykProfileView = None
        self.SetSize((900, 650))
        self.SetPosition((10, 10))
        self.sbgen = self.CreateStatusBar()
        self.sbgen.SetBackgroundColour('WHITE')
        txt = 'KMatrix file = %s' % fname
        self.sbgen.SetStatusText(txt)

        # timer affichage StatusBar
        self.txtsb = ''
        self.timer = wx.Timer(self)
        self.Bind(wx.EVT_TIMER, self.refreshSB, self.timer)
        """ read kmat.h5 file """
        self.fh5 = fname
        self.kmat = rttov.kmatrix.Kmatrix()
        self.kmat101 = rttov.kmatrix.Kmatrix()
        """ read profile in kmat.h5 """
        self.baseProfile = rttov.profile.Profile()
        self.baseProfile = rmodel.project.OpenAProfile(self.fh5, 1)
        t0 = time.clock()
        frad = h5py.File(self.fh5, 'r')
        h5 = frad['/']
        self.kmat.loadh5(h5)
        frad.close()

        t1 = time.clock()
        txt = 'lecture fichier %s : %d sec.' % (self.fh5, (t1 - t0))

        self.sat = self.kmat.misc['SATELLITE']
        self.ins = self.kmat.misc['INSTRUMENT']

        self.lev = self.kmat.profile['NLEVELS']
        self.tabP = self.kmat.profile['P']
        #
        #  growth the levels  < 101
        #
        #  map the levels

        self.tabilevels = np.zeros(levx, int)
        for l in range(0, levx):
            self.tabilevels[l] = round(l * self.lev / levx)

        if self.lev < levx:
            tabNP = np.zeros(levx)
            for l in range(0, levx):
                tabNP[l] = self.tabP[self.tabilevels[l]]
            self.tabP = tabNP

        self.tabW = self.kmat.misc['WAVENUMBERS']
        self.tabY = {}

        self.chn = self.kmat.kmatrix['T'].shape[1]
        """
        gasplot : 0.0 not shown ?
        """
        self.tcomm = {}
        self.tunit = {}
        self.tcbar = {}
        self.gasplot = []
        for gas in ['T', 'Q'] + gaslist:
            if self.kmat.kmatrix[gas] is None:
                continue
            kmin = np.amin(self.kmat.kmatrix[gas])
            kmax = np.amax(self.kmat.kmatrix[gas])
            self.tcbar[gas] = 1
            if kmin == 0.0 and kmax == 0.0:
                self.tcbar[gas] = 0

            attr = '%s_ATTRIBUTE' % gas
            self.tcomm[gas] = self.kmat.kmatrix[attr]['COMMENT']
            self.tunit[gas] = self.kmat.kmatrix[attr]['UNITS']

            if not gas == 'T' and not gas == 'Q':
                self.gasplot.append(gas)

#
# init figure
#
        self.fig = figPlot()
        self.cnv = FigureCanvas(self, -1, self.fig)
        self.cnv.mpl_connect('motion_notify_event', self.onMMotion)
        self.cnv.mpl_connect('key_press_event', self.onkeypress)
        #
        # subplot width
        #
        self.barwidth = max(1, int(wix / self.chn))
        self.yMax = self.lev
        if self.chn >= chnx:
            self.xMax = self.chn
        else:
            self.xMax = self.barwidth * self.chn

        self.txtsb = '%s / %s' % (self.sat.replace(
            ' ', '').upper(), self.ins.upper())

        #
        # choice gas in subplot 313
        #
        self.glabel = {}
        self.gasID = {}

        self.tlb = MyCustomToolbar(self.cnv)

        if len(self.gasplot) > 1:
            for ig in self.gasplot:
                self.gasID[ig] = wx.NewId()
                self.glabel[self.gasID[ig]] = ig
                ico = os.environ["RTTOV_GUI_PREFIX"] + '/icons/%s.png' % ig
                self.tlb.AddSimpleTool(self.gasID[ig], _load_bitmap(ico), ig,
                                       '')
                wx.EVT_TOOL(self.tlb, self.gasID[ig], self.gaschoice)

#
# toolbar : custom buttons
#
        self.LEFTLEFT_ID = wx.NewId()
        self.tlb.AddSimpleTool(self.LEFTLEFT_ID, _load_bitmap('hand.xpm'),
                               'One screen left', '')
        wx.EVT_TOOL(self.tlb, self.LEFTLEFT_ID, self.onleftleft)

        self.LEFT_ID = wx.NewId()
        self.tlb.AddSimpleTool(self.LEFT_ID, _load_bitmap('stock_left.xpm'),
                               'left', '')
        wx.EVT_TOOL(self.tlb, self.LEFT_ID, self.onleft)

        self.RIGHT_ID = wx.NewId()
        self.tlb.AddSimpleTool(self.RIGHT_ID, _load_bitmap('stock_right.xpm'),
                               'right', '')
        wx.EVT_TOOL(self.tlb, self.RIGHT_ID, self.onright)

        self.RIGHTRIGHT_ID = wx.NewId()
        self.tlb.AddSimpleTool(self.RIGHTRIGHT_ID, _load_bitmap('hand.xpm'),
                               'One screen right', '')
        wx.EVT_TOOL(self.tlb, self.RIGHTRIGHT_ID, self.onrightright)

        self.UP_ID = wx.NewId()
        self.tlb.AddSimpleTool(self.UP_ID, _load_bitmap('stock_up.xpm'),
                               'scroll up', '')
        wx.EVT_TOOL(self.tlb, self.UP_ID, self.onup)

        self.DOWN_ID = wx.NewId()
        self.tlb.AddSimpleTool(self.DOWN_ID, _load_bitmap('stock_down.xpm'),
                               'scroll down', '')
        wx.EVT_TOOL(self.tlb, self.DOWN_ID, self.ondown)
        #
        # add kscale icon : K / K%
        #
        self.scalek = 0
        self.SCALE10K_ID = wx.NewId()
        self.tlb.AddSimpleTool(
            self.SCALE10K_ID,
            _load_bitmap(os.environ["RTTOV_GUI_PREFIX"] + '/icons/k10.png'),
            'scale Kx10%', '')
        wx.EVT_TOOL(self.tlb, self.SCALE10K_ID, self.onscale10k)

        self.RESETK_ID = wx.NewId()
        self.tlb.AddSimpleTool(
            self.RESETK_ID,
            _load_bitmap(os.environ["RTTOV_GUI_PREFIX"] + '/icons/reset.png'),
            'reset K', '')
        wx.EVT_TOOL(self.tlb, self.RESETK_ID, self.onresetk)

        #
        # add box : select channel
        #
        self.SELCHAN_ID = wx.NewId()
        self.tlb.AddSimpleTool(
            self.SELCHAN_ID,
            _load_bitmap(os.environ["RTTOV_GUI_PREFIX"] + '/icons/kP.png'),
            'select channnel', '')
        wx.EVT_TOOL(self.tlb, self.SELCHAN_ID, self.onselchan)

        self.tlb.Realize()

        # canvas and toolbar in sizer
        sizer = wx.BoxSizer(wx.VERTICAL)

        sizer.Add(self.tlb, 0, wx.GROW)
        sizer.Add(self.cnv, 1, wx.LEFT | wx.TOP | wx.GROW)
        self.SetSizer(sizer)

        self.Fit()
        #
        self.kprof = None
        #

        self.subP = {}
        self.cax = {}
        #
        # subplots T and Q
        #
        self.subP['T'] = self.fig.add_subplot(3, 1, 1)
        self.tabY['T'] = self.extract_kgas('T')
        tt = '%s : %s' % ('T', self.tcomm['T'])
        self.subP['T'].set_title(tt)
        img = self.subP['T'].imshow(self.tabY['T'], origin='upper')
        self.subP['T'].set_ylabel('P levels')
        divider = make_axes_locatable(self.subP['T'])
        self.cax['T'] = divider.append_axes("right", size="1%", pad=0.05)
        self.fig.colorbar(img, cax=self.cax['T'])
        self.subP['T'].set_xlim([0, min(self.xMax, wix)])
        self.draw_plot('T', 'T',
                       self.kmat.kmatrix['%s_ATTRIBUTE' % 'T']['COMMENT'])

        self.subP['Q'] = self.fig.add_subplot(3,
                                              1,
                                              2,
                                              sharex=self.subP['T'],
                                              sharey=self.subP['T'])
        self.tabY['Q'] = self.extract_kgas('Q')
        tt = '%s : %s' % ('Q', self.tcomm['Q'])
        self.subP['Q'].set_title(tt)
        img = self.subP['Q'].imshow(self.tabY['Q'], origin='upper')
        self.subP['Q'].set_ylabel('P levels')
        divider = make_axes_locatable(self.subP['Q'])
        self.cax['Q'] = divider.append_axes("right", size="1%", pad=0.05)
        self.fig.colorbar(img, cax=self.cax['Q'])
        self.subP['Q'].set_xlim([0, min(self.xMax, wix)])
        self.draw_plot('Q', 'Q',
                       self.kmat.kmatrix['%s_ATTRIBUTE' % 'Q']['COMMENT'])

        #
        # subplot other gases if exist
        #
        if self.gasplot:
            for gas in self.gasplot:
                self.tabY[gas] = self.extract_kgas(gas)

            gas = self.gasplot[0]
            self.subP['G'] = self.fig.add_subplot(3,
                                                  1,
                                                  3,
                                                  sharex=self.subP['T'],
                                                  sharey=self.subP['T'])
            tt = '%s : %s' % (gas, self.tcomm[gas])
            self.subP['G'].set_title(tt)
            img = self.subP['G'].imshow(self.tabY[gas], origin='upper')
            self.subP['G'].set_ylabel('P levels')

            divider = make_axes_locatable(self.subP['G'])
            self.cax['G'] = divider.append_axes("right", size="1%", pad=0.05)
            self.fig.colorbar(img, cax=self.cax['G'])

            self.subP['G'].set_xlim([0, min(self.xMax, wix)])
            self.draw_plot('G', gas,
                           self.kmat.kmatrix['%s_ATTRIBUTE' % gas]['COMMENT'])

        self.fig.tight_layout()
        self.fig.canvas.draw()
Example #41
0
    def __init__(self,frame,id):
        wx.Panel.__init__(self,frame,id,style = wx.BORDER_RAISED)

        z_layer = 0
        self.omf = frame.omf
        self.halfstep = (float(self.omf.parameters['zstepsize'])/2.0)*1.0e10

        self.figure = Figure(frameon = True)
        self.figure.set_facecolor('.82')

        self.canvas = FigureCanvas(self, -1, self.figure)

        fm = FigureManagerBase(self.canvas, 0)
        _pylab_helpers.Gcf.set_active(fm)

        self.wheel_cmap = LinearSegmentedColormap.from_list('wheel_rgby',
                               ['red', 'green', 'blue', 'yellow', 'red'])

        mpl_toolbar = Toolbar(self.canvas)
        mpl_toolbar.Realize()

        x,y = indices((100,100), dtype = float) - 50.
        wheel_angle = arctan2(x,y)

        self.ax1 = self.figure.add_axes([0.1,0.1,0.7,0.8])

        self.angle = ma.array(arctan2(-self.omf.my[:,:,z_layer],
                                 self.omf.mx[:,:,z_layer]),
                                  mask=(self.omf.M[:,:,z_layer] == 0.0))
        self.angle[self.angle==360] = 0.0
        print ma.getdata(self.angle)
        xmax = (float(self.omf.parameters['xnodes']) *
                float(self.omf.parameters['xstepsize']) * 1.0e10)

        ymax = (float(self.omf.parameters['ynodes']) *
                float(self.omf.parameters['ystepsize']) * 1.0e10)
        
        self.extent = [0., xmax, 0., ymax]

        self.im = self.ax1.imshow(self.angle.T, origin='lower',
                                  interpolation = 'nearest',
                                  extent = self.extent,
                                  cmap = self.wheel_cmap,
                                  vmin = -pi, vmax = pi)


        self.ax1.set_title('Z Slice = ' +
               str(z_layer*float(self.omf.parameters['zstepsize'])* 1.0e10
                   + self.halfstep) +' Ang' ,size = 'xx-large')

        self.ax1.set_xlabel('$x (\AA)$', size = 'x-large')
        self.ax1.set_ylabel('$y (\AA)$', size = 'x-large')


        self.ax1w = self.figure.add_axes([0.75,0.4,0.3,0.2], polar=True)

        self.ax1w.yaxis.set_visible(False)

        self.ax1w.imshow(wheel_angle, cmap=self.wheel_cmap,
                         extent=[0,2*pi,0,pi])

        self.ax1w.set_title('M direction\n(in-plane)')


        self.zselect = wx.Slider(self,-1,size = [300,40],minValue = int(0),
                                 maxValue = int(self.omf.dims[2]-1),
                                 style = wx.SL_AUTOTICKS)


        self.datavalue = wx.StatusBar(self,-1)
        self.datavalue.SetStatusText('Angle Value: ')
        self.label = wx.StaticText(self,-1,'Select Z layer: ')

        self.minVal = wx.StaticText(self,-1, '0.0')

        self.maxVal = wx.StaticText(self,-1, str(self.omf.dims[2]*
                         (float(self.omf.parameters['zstepsize'])* 1.0e10)
                         -self.halfstep))

        #Sizer Creation
        toolSize = wx.BoxSizer(wx.HORIZONTAL)
        BotSize = wx.BoxSizer(wx.HORIZONTAL)
        vertSize = wx.BoxSizer(wx.VERTICAL)

        BotSize.Add(self.label,0,wx.LEFT|wx.RIGHT,border = 5)
        BotSize.Add(self.minVal,0,wx.LEFT|wx.RIGHT,border = 5)
        BotSize.Add(self.zselect,0,wx.TOP|wx.LEFT|wx.RIGHT,border = 5)
        BotSize.Add(self.maxVal,0,wx.LEFT|wx.RIGHT,border = 5)

        toolSize.Add(mpl_toolbar,0,wx.RIGHT,border = 20)
        toolSize.Add(self.datavalue,0,wx.LEFT|wx.RIGHT|wx.TOP,border = 20)

        vertSize.Add(self.canvas,-1,wx.EXPAND|wx.LEFT|wx.RIGHT,border = 5)
        vertSize.Add(toolSize,0)
        vertSize.Add(BotSize,0,wx.ALL, border = 10)

        self.SetSizer(vertSize)

        self.Fit()


        self.zselect.Bind(wx.EVT_SCROLL,self.newMomentZ)
        self.canvas.mpl_connect('motion_notify_event',self.onMouseOver)
Example #42
0
class wavCanvasPanel(wx.Panel):
    def __init__(self, parent):
        wx.Panel.__init__(self, parent)
        dpi = 60
        width = PLOT_PANEL_WIDTH / dpi
        height = PLOT_PANEL_HEIGHT / dpi
        self.wavFigure = Figure(figsize=[width, height],
                                dpi=dpi,
                                facecolor='#404040')
        self.wavCanvas = FigureCanvas(self, -1, self.wavFigure)
        self.wavSizer = wx.BoxSizer(wx.VERTICAL)
        self.wavSizer.Add(self.wavCanvas, 1, wx.EXPAND | wx.ALL)
        self.SetSizerAndFit(self.wavSizer)
        self.wavAxes = [None] * MAX_AUDIO_CHANNEL
        self.wavCursor = [None] * MAX_AUDIO_CHANNEL

    def fromstring(self, wavData, alignedByte):
        if alignedByte <= 8:
            src = numpy.ndarray(len(wavData), numpy.dtype('>i1'), wavData)
            dest = numpy.zeros(len(wavData) / alignedByte, numpy.dtype('>i8'))
            for i in range(alignedByte):
                dest.view(dtype='>i1')[alignedByte - 1 - i::8] = src.view(
                    dtype='>i1')[i::alignedByte]
            [hex(x) for x in dest]
            return True, dest
        else:
            return False, wavData

    def readWave(self, wavPath, wavInfo):
        if os.path.isfile(wavPath):
            # Open the wav file to get wave data and parameters
            wavFile = wave.open(wavPath, "rb")
            wavParams = wavFile.getparams()
            wavChannels = wavParams[0]
            wavSampwidth = wavParams[1]
            wavFramerate = wavParams[2]
            wavFrames = wavParams[3]
            wavInfo.SetStatusText('Opened Audio Info = ' + 'Channels:' +
                                  str(wavChannels) + ', SampWidth:' +
                                  str(wavSampwidth) + 'Byte' + ', SampRate:' +
                                  str(wavFramerate) + 'kHz' + ', FormatTag:' +
                                  wavParams[4])
            wavData = wavFile.readframes(wavFrames)
            wavFile.close()
            # Transpose the wav data if wave has multiple channels
            if wavSampwidth == 1:
                dtype = numpy.int8
            elif wavSampwidth == 2:
                dtype = numpy.int16
            elif wavSampwidth == 3:
                dtype = None
            elif wavSampwidth == 4:
                dtype = numpy.float32
            else:
                return 0, 0, 0
            if dtype != None:
                retData = numpy.fromstring(wavData, dtype=dtype)
            else:
                # Implement int24 manually
                status, retData = self.fromstring(wavData, 3)
                if not status:
                    return 0, 0, 0
            if wavChannels != 1:
                retData.shape = -1, wavChannels
                retData = retData.T
            # Calculate and arange wave time
            retTime = numpy.arange(0, wavFrames) * (1.0 / wavFramerate)
            retChannels = wavChannels
            return retChannels, retData, retTime
        else:
            return 0, 0, 0

    def showWave(self, wavPath, wavDomain, wavInfo):
        self.wavFigure.clear()
        waveChannels, waveData, waveTime = self.readWave(wavPath, wavInfo)
        if waveChannels != 0:
            # Note: only show max supported channel if actual channel > max supported channel
            if waveChannels > MAX_AUDIO_CHANNEL:
                waveChannels = MAX_AUDIO_CHANNEL
            # Polt the waveform of each channel in sequence
            for i in range(waveChannels):
                left = PLOT_AXES_HEIGHT_LABEL
                bottom = (1.0 / waveChannels) * (waveChannels - 1 -
                                                 i) + PLOT_AXES_HEIGHT_LABEL
                height = 1.0 / waveChannels - (PLOT_AXES_WIDTH_TITLE +
                                               PLOT_AXES_HEIGHT_LABEL)
                width = 1 - left - 0.05
                self.wavAxes[i] = self.wavFigure.add_axes(
                    [left, bottom, width, height], facecolor='k')
                if waveChannels == 1:
                    waveAmplitude = waveData
                else:
                    waveAmplitude = waveData[i]
                if wavDomain == 'Time':
                    self.wavAxes[i].set_prop_cycle(color='#00F279', lw=[1])
                    self.wavAxes[i].set_xlabel('time (s)', color='w')
                    self.wavAxes[i].plot(waveTime, waveAmplitude)
                    self.wavCursor[i] = wavCursor(self.wavAxes[i], waveTime,
                                                  waveAmplitude)
                elif wavDomain == 'Frequency':
                    self.wavAxes[i].set_prop_cycle(color='red', lw=[1])
                    self.wavAxes[i].set_xlabel('Frequency (Hz)', color='w')
                    waveMagnitude = numpy.absolute(
                        numpy.fft.rfft(waveAmplitude))
                    waveFreq = numpy.fft.rfftfreq(len(waveTime),
                                                  numpy.diff(waveTime)[0])
                    self.wavAxes[i].plot(waveFreq, waveMagnitude)
                    self.wavCursor[i] = wavCursor(self.wavAxes[i], waveFreq,
                                                  waveMagnitude)
                self.wavAxes[i].set_ylabel('value', color='w')
                self.wavAxes[i].grid()
                self.wavAxes[i].tick_params(labelcolor='w')
                self.wavAxes[i].set_title('Audio Channel ' + str(i), color='w')
                self.wavCanvas.mpl_connect('motion_notify_event',
                                           self.wavCursor[i].moveMouse)
        # Note!!!: draw() must be called if figure has been cleared once
        self.wavCanvas.draw()

    def showWelcome(self):
        self.wavFigure.clear()
        # Get Code from below link
        # https://matplotlib.org/gallery/images_contours_and_fields/tripcolor_demo.html#sphx-glr-gallery-images-contours-and-fields-tripcolor-demo-py
        n_angles = 36
        n_radii = 8
        min_radius = 0.25
        radii = numpy.linspace(min_radius, 0.95, n_radii)
        angles = numpy.linspace(0, 2 * numpy.pi, n_angles, endpoint=False)
        angles = numpy.repeat(angles[..., numpy.newaxis], n_radii, axis=1)
        angles[:, 1::2] += numpy.pi / n_angles
        x = (radii * numpy.cos(angles)).flatten()
        y = (radii * numpy.sin(angles)).flatten()
        z = (numpy.cos(radii) * numpy.cos(3 * angles)).flatten()
        triang = Tri.Triangulation(x, y)
        triang.set_mask(
            numpy.hypot(x[triang.triangles].mean(
                axis=1), y[triang.triangles].mean(axis=1)) < min_radius)
        welcomeAxes = self.wavFigure.add_axes([0.13, 0.2, 0.7, 0.7],
                                              facecolor='#404040')
        #welcomeAxes.set_aspect('equal')
        welcomeAxes.tripcolor(triang, z, shading='flat')
        # Set some properties
        welcomeAxes.set_title('Welcome to use Jays-PySPEECH', color='w')
        welcomeAxes.set_xticks([])
        welcomeAxes.set_yticks([])
        welcomeAxes.spines['top'].set_visible(False)
        welcomeAxes.spines['right'].set_visible(False)
        welcomeAxes.spines['bottom'].set_visible(False)
        welcomeAxes.spines['left'].set_visible(False)
        self.wavCanvas.draw()
Example #43
0
class PlotFigure(wx.Frame):
    """Matplotlib wxFrame with animation effect"""
    def __init__(self):
        # initialize the super class
        wx.Frame.__init__(self,
                          None,
                          wx.ID_ANY,
                          title="CPU Usage Monitor",
                          size=(600, 400))
        # Matplotlib Figure
        self.fig = Figure((6, 4), 100)
        # bind the Figure to the backend specific canvas
        self.canvas = FigureCanvas(self, wx.ID_ANY, self.fig)
        # add a subplot
        self.ax = self.fig.add_subplot(111)

        # limit the X and Y axes dimensions
        # we prefer 2 separate functions for clarity
        self.ax.set_ylim([0, 100])
        self.ax.set_xlim([0, POINTS])
        # but we want a "frozen" window (defined by y/xlim functions)
        self.ax.set_autoscale_on(False)
        # we do not want ticks on X axis
        self.ax.set_xticks([])
        # we want a tick every 10 point on Y (101 is to have 100 too)
        self.ax.set_yticks(range(0, 101, 10))
        # disable autoscale, since we don't want the Axes to adapt
        # draw a grid (it will be only for Y)
        self.ax.grid(True)
        # generates first "empty" plots
        self.user = [None] * POINTS
        self.nice = [None] * POINTS
        self.sys = [None] * POINTS
        self.idle = [None] * POINTS
        self.l_user, = self.ax.plot(range(POINTS), self.user, label='User%')
        self.l_nice, = self.ax.plot(range(POINTS), self.nice, label='Nice%')
        self.l_sys, = self.ax.plot(range(POINTS), self.sys, label='Sys%')
        self.l_idle, = self.ax.plot(range(POINTS), self.idle, label='Idle%')
        # add the legend
        self.ax.legend(loc='upper center',
                       ncol=4,
                       prop=font_manager.FontProperties(size=10))
        # force a draw on the canvas()
        # trick to show the grid and the legend
        self.canvas.draw()
        # save the clean background - everything but the line
        # is drawn and saved in the pixel buffer background
        self.bg = self.canvas.copy_from_bbox(self.ax.bbox)
        # take a snapshot of CPU usage, needed for the update algorithm

        self.before = self.prepare_cpu_usage()
        # bind events coming from timer with id = TIMER_ID
        # to the onTimer callback function
        wx.EVT_TIMER(self, TIMER_ID, self.onTimer)

    def prepare_cpu_usage(self):
        """helper function to return CPU usage info"""
        # get the CPU times using psutil module
        t = p.cpu_times()
        # return only the values we're interested in
        if hasattr(t, 'nice'):
            return [t.user, t.nice, t.system, t.idle]
        else:
            # special case for Windows, without 'nice' value
            return [t.user, 0, t.system, t.idle]

    def get_cpu_usage(self):
        """Compute CPU usage comparing previous and currentmeasurements"""
        # take the current CPU usage information
        now = self.prepare_cpu_usage()
        # compute deltas between current and previous measurements
        delta = [now[i] - self.before[i] for i in range(len(now))]
        # compute the total (needed for percentages calculation)
        total = sum(delta)
        # save the current measurement to before object
        self.before = now
        # return the percentage of CPU usage for our 4 categories
        return [(100.0 * dt) / total for dt in delta]

    def onTimer(self, evt):
        """callback function for timer events"""
        # get the CPU usage information
        tmp = self.get_cpu_usage()
        # restore the clean background, saved at the beginning
        self.canvas.restore_region(self.bg)
        # update the data
        self.user = self.user[1:] + [tmp[0]]
        self.nice = self.nice[1:] + [tmp[1]]
        self.sys = self.sys[1:] + [tmp[2]]
        self.idle = self.idle[1:] + [tmp[3]]
        # update the plot
        self.l_user.set_ydata(self.user)
        self.l_nice.set_ydata(self.nice)
        self.l_sys.set_ydata(self.sys)
        self.l_idle.set_ydata(self.idle)
        # just draw the "animated" objects
        self.ax.draw_artist(self.l_user)
        self.ax.draw_artist(self.l_nice)
        self.ax.draw_artist(self.l_sys)
        self.ax.draw_artist(self.l_idle)
        # "blit" the background with the animated lines
        self.canvas.blit(self.ax.bbox)
Example #44
0
class ScatterPlotWidget(wx.Panel, ManageBusyCursorMixin):
    def __init__(self, parent, scatt_id, scatt_mgr, transpose, id=wx.ID_ANY):
        #TODO should not be transpose and scatt_id but x, y
        wx.Panel.__init__(self, parent, id)
        # bacause of aui (if floatable it can not take cursor from parent)
        ManageBusyCursorMixin.__init__(self, window=self)

        self.parent = parent
        self.full_extend = None
        self.mode = None

        self._createWidgets()
        self._doLayout()
        self.scatt_id = scatt_id
        self.scatt_mgr = scatt_mgr

        self.cidpress = None
        self.cidrelease = None

        self.rend_dt = {}

        self.transpose = transpose

        self.inverse = False

        self.SetSize((200, 100))
        self.Layout()

        self.base_scale = 1.2
        self.Bind(wx.EVT_CLOSE, lambda event: self.CleanUp())

        self.plotClosed = Signal("ScatterPlotWidget.plotClosed")
        self.cursorMove = Signal("ScatterPlotWidget.cursorMove")

        self.contex_menu = ScatterPlotContextMenu(plot=self)

        self.ciddscroll = None

        self.canvas.mpl_connect('motion_notify_event', self.Motion)
        self.canvas.mpl_connect('button_press_event', self.OnPress)
        self.canvas.mpl_connect('button_release_event', self.OnRelease)
        self.canvas.mpl_connect('draw_event', self.DrawCallback)
        self.canvas.mpl_connect('figure_leave_event', self.OnCanvasLeave)

    def DrawCallback(self, event):
        self.polygon_drawer.DrawCallback(event)
        self.axes.draw_artist(self.zoom_rect)

    def _createWidgets(self):

        # Create the mpl Figure and FigCanvas objects.
        # 5x4 inches, 100 dots-per-inch
        #
        self.dpi = 100
        self.fig = Figure((1.0, 1.0), dpi=self.dpi)
        self.fig.autolayout = True

        self.canvas = FigCanvas(self, -1, self.fig)

        self.axes = self.fig.add_axes([0.0, 0.0, 1, 1])

        pol = Polygon(list(zip([0], [0])), animated=True)
        self.axes.add_patch(pol)
        self.polygon_drawer = PolygonDrawer(self.axes, pol=pol, empty_pol=True)

        self.zoom_wheel_coords = None
        self.zoom_rect_coords = None
        self.zoom_rect = Polygon(list(zip([0], [0])), facecolor='none')
        self.zoom_rect.set_visible(False)
        self.axes.add_patch(self.zoom_rect)

    def ZoomToExtend(self):
        if self.full_extend:
            self.axes.axis(self.full_extend)
            self.canvas.draw()

    def SetMode(self, mode):
        self._deactivateMode()
        if mode == 'zoom':
            self.ciddscroll = self.canvas.mpl_connect('scroll_event',
                                                      self.ZoomWheel)
            self.mode = 'zoom'
        elif mode == 'zoom_extend':
            self.mode = 'zoom_extend'
        elif mode == 'pan':
            self.mode = 'pan'
        elif mode:
            self.polygon_drawer.SetMode(mode)

    def SetSelectionPolygonMode(self, activate):
        self.polygon_drawer.SetSelectionPolygonMode(activate)

    def _deactivateMode(self):
        self.mode = None
        self.polygon_drawer.SetMode(None)

        if self.ciddscroll:
            self.canvas.mpl_disconnect(self.ciddscroll)

        self.zoom_rect.set_visible(False)
        self._stopCategoryEdit()

    def GetCoords(self):

        coords = self.polygon_drawer.GetCoords()
        if coords is None:
            return

        if self.transpose:
            for c in coords:
                tmp = c[0]
                c[0] = c[1]
                c[1] = tmp

        return coords

    def SetEmpty(self):
        return self.polygon_drawer.SetEmpty()

    def OnRelease(self, event):
        if not self.mode == "zoom": return
        self.zoom_rect.set_visible(False)
        self.ZoomRectangle(event)
        self.canvas.draw()

    def OnPress(self, event):
        'on button press we will see if the mouse is over us and store some data'
        if not event.inaxes:
            return
        if self.mode == "zoom_extend":
            self.ZoomToExtend()

        if event.xdata and event.ydata:
            self.zoom_wheel_coords = {'x': event.xdata, 'y': event.ydata}
            self.zoom_rect_coords = {'x': event.xdata, 'y': event.ydata}
        else:
            self.zoom_wheel_coords = None
            self.zoom_rect_coords = None

    def _stopCategoryEdit(self):
        'disconnect all the stored connection ids'

        if self.cidpress:
            self.canvas.mpl_disconnect(self.cidpress)
        if self.cidrelease:
            self.canvas.mpl_disconnect(self.cidrelease)
        #self.canvas.mpl_disconnect(self.cidmotion)

    def _doLayout(self):

        self.main_sizer = wx.BoxSizer(wx.VERTICAL)
        self.main_sizer.Add(self.canvas, 1, wx.LEFT | wx.TOP | wx.GROW)
        self.SetSizer(self.main_sizer)
        self.main_sizer.Fit(self)

    def Plot(self, cats_order, scatts, ellipses, styles):
        """Redraws the figure
        """

        callafter_list = []

        if self.full_extend:
            cx = self.axes.get_xlim()
            cy = self.axes.get_ylim()
            c = cx + cy
        else:
            c = None

        q = Queue()
        _rendDtMemmapsToFiles(self.rend_dt)
        p = Process(target=MergeImg,
                    args=(cats_order, scatts, styles, self.rend_dt, q))
        p.start()
        merged_img, self.full_extend, self.rend_dt = q.get()
        p.join()

        _rendDtFilesToMemmaps(self.rend_dt)
        merged_img = np.memmap(filename=merged_img['dt'],
                               shape=merged_img['sh'])

        #merged_img, self.full_extend = MergeImg(cats_order, scatts, styles, None)
        self.axes.clear()
        self.axes.axis('equal')

        if self.transpose:
            merged_img = np.transpose(merged_img, (1, 0, 2))

        img = imshow(self.axes,
                     merged_img,
                     extent=[int(ceil(x)) for x in self.full_extend],
                     origin='lower',
                     interpolation='nearest',
                     aspect="equal")

        callafter_list.append([self.axes.draw_artist, [img]])
        callafter_list.append([grass.try_remove, [merged_img.filename]])

        for cat_id in cats_order:
            if cat_id == 0:
                continue
            if not ellipses.has_key(cat_id):
                continue

            e = ellipses[cat_id]
            if not e:
                continue

            colors = styles[cat_id]['color'].split(":")
            if self.transpose:
                e['theta'] = 360 - e['theta'] + 90
                if e['theta'] >= 360:
                    e['theta'] = abs(360 - e['theta'])

                e['pos'] = [e['pos'][1], e['pos'][0]]

            ellip = Ellipse(xy=e['pos'],
                            width=e['width'],
                            height=e['height'],
                            angle=e['theta'],
                            edgecolor="w",
                            linewidth=1.5,
                            facecolor='None')
            self.axes.add_artist(ellip)
            callafter_list.append([self.axes.draw_artist, [ellip]])

            color = map(lambda v: int(v) / 255.0,
                        styles[cat_id]['color'].split(":"))

            ellip = Ellipse(xy=e['pos'],
                            width=e['width'],
                            height=e['height'],
                            angle=e['theta'],
                            edgecolor=color,
                            linewidth=1,
                            facecolor='None')

            self.axes.add_artist(ellip)
            callafter_list.append([self.axes.draw_artist, [ellip]])

            center = Line2D(
                [e['pos'][0]],
                [e['pos'][1]],
                marker='x',
                markeredgecolor='w',
                #markerfacecolor=color,
                markersize=2)
            self.axes.add_artist(center)
            callafter_list.append([self.axes.draw_artist, [center]])

        callafter_list.append([self.fig.canvas.blit, []])

        if c:
            self.axes.axis(c)
        wx.CallAfter(lambda: self.CallAfter(callafter_list))

    def CallAfter(self, funcs_list):
        while funcs_list:
            fcn, args = funcs_list.pop(0)
            fcn(*args)

        self.canvas.draw()

    def CleanUp(self):
        self.plotClosed.emit(scatt_id=self.scatt_id)
        self.Destroy()

    def ZoomWheel(self, event):
        # get the current x and y limits
        if not event.inaxes:
            return
        # tcaswell
        # http://stackoverflow.com/questions/11551049/matplotlib-plot-zooming-with-scroll-wheel
        cur_xlim = self.axes.get_xlim()
        cur_ylim = self.axes.get_ylim()

        xdata = event.xdata
        ydata = event.ydata
        if event.button == 'up':
            scale_factor = 1 / self.base_scale
        elif event.button == 'down':
            scale_factor = self.base_scale
        else:
            scale_factor = 1

        extend = (xdata - (xdata - cur_xlim[0]) * scale_factor,
                  xdata + (cur_xlim[1] - xdata) * scale_factor,
                  ydata - (ydata - cur_ylim[0]) * scale_factor,
                  ydata + (cur_ylim[1] - ydata) * scale_factor)

        self.axes.axis(extend)

        self.canvas.draw()

    def ZoomRectangle(self, event):
        # get the current x and y limits
        if not self.mode == "zoom": return
        if event.inaxes is None: return
        if event.button != 1: return

        cur_xlim = self.axes.get_xlim()
        cur_ylim = self.axes.get_ylim()

        x1, y1 = event.xdata, event.ydata
        x2 = deepcopy(self.zoom_rect_coords['x'])
        y2 = deepcopy(self.zoom_rect_coords['y'])

        if x1 == x2 or y1 == y2:
            return

        if x1 > x2:
            tmp = x1
            x1 = x2
            x2 = tmp

        if y1 > y2:
            tmp = y1
            y1 = y2
            y2 = tmp

        self.axes.axis((x1, x2, y1, y2))
        #self.axes.set_xlim(x1, x2)#, auto = True)
        #self.axes.set_ylim(y1, y2)#, auto = True)
        self.canvas.draw()

    def Motion(self, event):
        self.PanMotion(event)
        self.ZoomRectMotion(event)

        if event.inaxes is None:
            return

        self.cursorMove.emit(x=event.xdata,
                             y=event.ydata,
                             scatt_id=self.scatt_id)

    def OnCanvasLeave(self, event):
        self.cursorMove.emit(x=None, y=None, scatt_id=self.scatt_id)

    def PanMotion(self, event):
        'on mouse movement'
        if not self.mode == "pan":
            return
        if event.inaxes is None:
            return
        if event.button != 1:
            return

        cur_xlim = self.axes.get_xlim()
        cur_ylim = self.axes.get_ylim()

        x, y = event.xdata, event.ydata

        mx = (x - self.zoom_wheel_coords['x']) * 0.6
        my = (y - self.zoom_wheel_coords['y']) * 0.6

        extend = (cur_xlim[0] - mx, cur_xlim[1] - mx, cur_ylim[0] - my,
                  cur_ylim[1] - my)

        self.zoom_wheel_coords['x'] = x
        self.zoom_wheel_coords['y'] = y

        self.axes.axis(extend)

        #self.canvas.copy_from_bbox(self.axes.bbox)
        #self.canvas.restore_region(self.background)
        self.canvas.draw()

    def ZoomRectMotion(self, event):
        if not self.mode == "zoom": return
        if event.inaxes is None: return
        if event.button != 1: return

        x1, y1 = event.xdata, event.ydata
        self.zoom_rect.set_visible(True)
        x2 = self.zoom_rect_coords['x']
        y2 = self.zoom_rect_coords['y']

        self.zoom_rect.xy = ((x1, y1), (x1, y2), (x2, y2), (x2, y1), (x1, y1))

        #self.axes.draw_artist(self.zoom_rect)
        self.canvas.draw()
class WxLineScatterWidget(wx.Panel):
    axis_width = 20
    axis_offset = 1.05

    def __init__(self, *args, **kwargs):
        kwargs['style'] = kwargs.setdefault(
            'style',
            wx.NO_FULL_REPAINT_ON_RESIZE) | wx.NO_FULL_REPAINT_ON_RESIZE
        wx.Panel.__init__(self, *args, **kwargs)
        self.id = wx.NewId()
        self.plot1 = 'none'
        self.plot2 = 'none'
        self.plot3 = 'none'
        self.lineprops1 = wxLineProps({'color': '#990000', 'fill': True})
        self.lineprops2 = wxLineProps({'color': '#009900', 'fill': True})
        self.lineprops3 = wxLineProps({'color': '#000099', 'fill': True})
        self.autoy1 = True
        self.autoy2 = True
        self.autoy3 = True
        self.smooth1 = 1
        self.smooth2 = 1
        self.smooth3 = 1
        self.xaxis = ''
        self.press = False
        self.cursor = None
        self.span = None
        self.selstart = 0
        self.selstop = 0
        self.enablecursor = True
        self.enablespan = True
        self.cursorcolor = '#FF0000'
        self.cursorwidth = 1

        self.gpxfig = Figure()
        self.ax1 = self.gpxfig.add_subplot(
            1, 1, 1
        )  # create a grid of 1 row, 1 col and put a subplot in the first cell of this grid
        self.gpxfig.subplots_adjust(right=0.9, left=0.06)

        self.ax2 = self.ax1.twinx()
        #self.ax2.spines["left"].set_visible(False)

        self.ax3 = self.ax1.twinx()
        self.ax3.spines["right"].set_position(("axes", self.axis_offset))
        #self.ax3.spines["left"].set_visible(False)
        # canvas and events
        self.gpxcanvas = FigureCanvas(self, -1, self.gpxfig)
        self.gpxcanvas.mpl_connect('scroll_event', self.OnMouseWheel)
        self.gpxcanvas.mpl_connect('button_press_event', self.OnLeftMouseDown)
        self.gpxcanvas.mpl_connect('button_release_event', self.OnLeftMouseUp)
        self.gpxcanvas.mpl_connect('motion_notify_event', self.OnMouseMotion)
        self.gpxcanvas.mpl_connect('resize_event', self.OnSize)
        self.gpxcanvas.mpl_connect('figure_enter_event', self.OnMouseEnter)
        self.gpxcanvas.mpl_connect('figure_leave_event', self.OnMouseLeave)
        self.Bind(wx.EVT_RIGHT_DOWN, self.OnRightMouseDown)
        self.sizer = wx.BoxSizer(wx.VERTICAL)
        self.sizer.Add(self.gpxcanvas, 1,
                       wx.LEFT | wx.TOP | wx.GROW | wx.EXPAND)
        self.SetSizer(self.sizer)
        #self.OnSize(None)

        msgwrap.register(self.OnSigCurChanged, signal="CurChanged")
        msgwrap.register(self.OnSigSelChanged, signal="SelChanged")
        msgwrap.register(self.OnSigValChanged, signal="ValChanged")

        #set background color to pure white
        #that code does not work on linux...
        #color = wx.SystemSettings.GetColour(wx.wx.SYS_COLOUR_BTNFACE)
        color = wx.Colour(255, 255, 255)
        self.gpxfig.set_facecolor(
            (color.red / 255.0, color.green / 255.0, color.blue / 255.0))
        self.gpxfig.set_edgecolor(
            (color.red / 255.0, color.green / 255.0, color.blue / 255.0))
        self.gpxfig.set_edgecolor((0.0, 0.0, 0.0))
        self.gpxcanvas.SetBackgroundColour(color)

        # create right now the popup menu
        self.select_menu = wx.Menu()
        for text in ["Disable selected",\
                            "Enable selected",\
                            "Delete selected",\
                            "Disable non selected",\
                            "Enable non selected",\
                            "Delete non selected",\
                            "Toggle points"]:
            item = self.select_menu.Append(wx.NewId(), text)
            self.Bind(wx.EVT_MENU, self.OnPopup, item)

    def x_to_num(self, value, scaled=True):
        if self.xaxis == 'time':
            return dates.date2num(dateutil.parser.parse(value))
        else:
            if scaled:
                #return float(value)/self.gpx.get_scale(self.xaxis)
                return float(value) * self.gpx.get_scale(self.xaxis)
            else:
                return float(value)

    def num_to_x(self, value, scaled=True):
        if self.xaxis == 'time':
            return dates.num2date(value)
        else:
            if scaled:
                #return value*self.gpx.get_scale(self.xaxis)
                return value / self.gpx.get_scale(self.xaxis)
            else:
                return value

    def x_max(self):
        if self.xaxis == 'time':
            return self.x_to_num(
                self.gpx[self.xaxis][self.gpx.get_row_count() - 1])
        else:
            return self.x_to_num(np.nanmax(self.gpx[self.xaxis]))

    def x_min(self):
        if self.xaxis == 'time':
            return self.x_to_num(self.gpx[self.xaxis][0])
        else:
            return self.x_to_num(np.nanmin(self.gpx[self.xaxis]))

    def format_x_axis(self):
        if self.xaxis == 'time':
            xlo = self.ax1.get_xlim()[0]
            xhi = self.ax1.get_xlim()[1]
            if (xhi - xlo) > 0.003:
                self.ax1.xaxis.set_major_formatter(
                    dates.DateFormatter("%H:%M"))
            else:
                self.ax1.xaxis.set_major_formatter(
                    dates.DateFormatter("%H:%M:%S"))
            self.ax1.set_xlabel('Time (HH:MM:SS)')
        else:
            #self.ax1.set_xlabel('Distance (m)')
            self.ax1.set_xlabel(self.xaxis + " (" +
                                self.gpx.get_unit(self.xaxis)[0] + ")")
            #self.ax1.xaxis.set_major_formatter(mpl.ticker.FormatStrFormatter('%.0f') )
            self.ax1.xaxis.set_major_formatter(mpl.ticker.ScalarFormatter())
            pass

    def get_axis(self, event, tolerance):
        bbox = self.ax1.get_window_extent().transformed(
            self.gpxfig.dpi_scale_trans.inverted())
        l = bbox.bounds[0] * self.gpxfig.dpi
        b = bbox.bounds[1] * self.gpxfig.dpi
        r = l + bbox.bounds[2] * self.gpxfig.dpi
        t = b + bbox.bounds[3] * self.gpxfig.dpi
        #convert screen coordinates to graph coordinates
        xlo = self.ax1.get_xlim()[0]
        xhi = self.ax1.get_xlim()[1]
        event.xdata = (event.x - l) / (r - l) * (xhi - xlo) + xlo
        if ptinrect(l - tolerance, t, l, b, event.x, event.y):
            ylo, yhi = self.ax1.get_ylim()
            event.ydata = (event.y - b) / (t - b) * (yhi - ylo) + ylo
            return 'left'
        if ptinrect(r, t, r + tolerance, b, event.x, event.y):
            ylo, yhi = self.ax2.get_ylim()
            event.ydata = (event.y - b) / (t - b) * (yhi - ylo) + ylo
            return 'right'
        if ptinrect(l, t, r, t + tolerance, event.x, event.y):
            ylo, yhi = self.ax1.get_ylim()
            event.ydata = (event.y - b) / (t - b) * (yhi - ylo) + ylo
            return 'top'
        if ptinrect(l, b - tolerance, r, b, event.x, event.y):
            ylo, yhi = self.ax1.get_ylim()
            event.ydata = (event.y - b) / (t - b) * (yhi - ylo) + ylo
            return 'bottom'
        #we need a small adjustment here, but this hack gives good results
        if ptinrect(r * self.axis_offset * 0.985, t,
                    r * self.axis_offset * 0.985 + tolerance, b, event.x,
                    event.y):
            ylo, yhi = self.ax3.get_ylim()
            event.ydata = (event.y - b) / (t - b) * (yhi - ylo) + ylo
            return "3rd"
        if ptinrect(l, t, r, b, event.x, event.y):
            ylo, yhi = self.ax1.get_ylim()
            event.ydata = (event.y - b) / (t - b) * (yhi - ylo) + ylo
            return 'main'

    def update_axis(self, ax, plot, ylo, yhi, yauto, lineprops, smooth):
        if plot != 'none':
            ## process data!!
            N = smooth
            #data=(1.0)*np.convolve(self.gpx[plot]*self.gpx.scale[plot], np.ones((N,))/N)[(N-1):]
            data = (1.0) * np.convolve(self.gpx[(plot, True)],
                                       np.ones((N, )) / N)[(N - 1):]
            data[self.gpx['ok'] == False] = np.NAN
            ##end of data processing
            #remove fill_between collection
            for coll in ax.collections:
                ax.collections.remove(coll)
            #need to rebuild dates array in case something was deleted
            self.xvalues = []
            for x in self.gpx[self.xaxis]:
                self.xvalues.append(self.x_to_num(x))
            ax.get_lines()[0].set_data(self.xvalues, data)
            self.format_x_axis()
            if lineprops['fill']:
                ax.fill_between(self.xvalues,
                                0,
                                data,
                                facecolor=lineprops['color'],
                                alpha=0.2)
            ax.get_lines()[0].set_color(lineprops['color'])
            ax.get_lines()[0].set_linewidth(lineprops['linewidth'])
            ax.get_lines()[0].set_marker(lineprops['marker'])
            ax.get_lines()[0].set_markersize(lineprops['markersize'])
            ax.set_autoscaley_on(yauto)
            ##now using legends instead of labels
            #ax.set_ylabel(plot+" ("+str(self.gpx.get_unit(plot)[0])+")")
            #ax.yaxis.label.set_color(lineprops['color'])
            lines = self.line1 + self.line2 + self.line3
            labs = [
                p for p in [self.plot1, self.plot2, self.plot3] if p != 'none'
            ]
            self.ax1.legend(
                lines, labs, loc='best'
            )  #,bbox_to_anchor=(0.5, 1.3), ncol=3, fancybox=False, shadow=False)

            if not yauto:
                ax.set_ylim(ylo, yhi)
            else:
                ax.set_ylim(np.min(self.gpx[plot] * self.gpx.scale[plot]),
                            np.max(self.gpx[plot] * self.gpx.scale[plot]))
            ax.set_visible(True)
            for tick in ax.get_yticklabels():
                tick.set_color(lineprops['color'])
            ax.spines["right"].set_edgecolor(lineprops['color'])
            ax.tick_params(axis='y', colors=lineprops['color'])
        else:
            ax.get_lines()[0].set_data(self.xvalues,
                                       np.zeros(self.gpx.get_row_count()))
            ax.set_visible(False)
        self.cursor.set_color(self.cursorcolor)
        self.cursor.set_linewidth(self.cursorwidth)
        self.format_x_axis()
        self.Draw(False)
        self.OnSize(None)

    def AttachGpx(self, data):
        self.gpx = data
        self.xvalues = []
        self.xaxis = self.gpx.get_header_names()[0]
        for x in self.gpx[self.xaxis]:
            self.xvalues.append(self.x_to_num(x))
        self.ax1.set_xlabel('')
        self.line1 = self.ax1.plot(self.xvalues,
                                   np.zeros(self.gpx.get_row_count()),
                                   picker=5,
                                   label='ax1')
        self.line2 = self.ax2.plot(self.xvalues,
                                   np.zeros(self.gpx.get_row_count()),
                                   picker=5,
                                   label='ax2')
        self.line3 = self.ax3.plot(self.xvalues,
                                   np.zeros(self.gpx.get_row_count()),
                                   picker=5,
                                   label='ax3')
        xlo = self.x_to_num(self.gpx[self.xaxis][0])
        xhi = self.x_to_num(self.gpx[self.xaxis][self.gpx.get_row_count() - 1])
        if xlo != xhi:
            self.ax1.set_xlim([xlo, xhi])
        if self.enablecursor == True:
            self.cursor = self.ax1.axvline(color='r', animated=True)
            mid = (self.ax1.get_xlim()[0] + self.ax1.get_xlim()[1]) / 2
            self.cursor.set_xdata(mid)
            #self.cursor.set_color('k')
            #self.cursor.set_linewidth(4)
        if self.enablespan == True:
            self.span = patches.Rectangle(
                (self.ax1.get_xlim()[0], 0),
                (self.ax1.get_xlim()[1] - self.ax1.get_xlim()[0]) / 3,
                200,
                color='k',
                alpha=0.3,
                animated=True)
            self.ax1.add_patch(self.span)
            self.span.set_visible(False)
        self.SetDefaultPlots()
        self.OnSize(None)

    def DetachGpx(self):
        self.gpx = None
        self.plot1 = 'none'
        self.plot2 = 'none'
        self.plot3 = 'none'
        self.autoy1 = True
        self.autoy2 = True
        self.autoy3 = True
        self.fill1 = True
        self.fill2 = True
        self.fill3 = True
        self.xaxis = ''
        self.press = False
        if self.cursor != None:
            self.cursor.remove()
            self.cursor = None
        if self.span != None:
            self.span.remove()
            self.span = None

    def OnSigSelChanged(self, arg1, arg2, arg3):
        if arg1 == self.id:
            return
        if self.span != None:
            xlo = self.x_to_num(self.gpx[self.xaxis][arg2])
            xhi = self.x_to_num(self.gpx[self.xaxis][arg3])
            self.span.set_bounds(
                xlo,
                self.ax1.get_ylim()[0], xhi - xlo,
                self.ax1.get_ylim()[1] - self.ax1.get_ylim()[0])
            self.span.set_visible(True)

    def OnSigValChanged(self, arg1):
        if arg1 == self.id:
            return
        self.update_axis(self.ax1, self.plot1,
                         self.ax1.get_xlim()[0],
                         self.ax1.get_xlim()[1], self.autoy1, self.lineprops1,
                         self.smooth1)
        self.update_axis(self.ax2, self.plot2,
                         self.ax2.get_xlim()[0],
                         self.ax2.get_xlim()[1], self.autoy2, self.lineprops2,
                         self.smooth2)
        self.update_axis(self.ax3, self.plot3,
                         self.ax2.get_xlim()[0],
                         self.ax2.get_xlim()[1], self.autoy3, self.lineprops3,
                         self.smooth3)

    def OnSigCurChanged(self, arg1, arg2):
        if arg1 == self.id:
            return
        if self.gpx != None:
            xval = self.gpx[self.xaxis][arg2]
            self.gpxcanvas.restore_region(self.background)
            if self.cursor != None:
                self.cursor.set_xdata(self.x_to_num(xval))
                self.ax1.draw_artist(self.cursor)
            if self.span != None and self.span.get_visible():
                self.ax1.draw_artist(self.span)
            self.gpxcanvas.blit()
        self.UpdateStatusBar(arg2)

    def SetDefaultPlots(self):
        self.xaxis = self.gpx.get_header_names()[0]
        self.plot1 = self.gpx.get_header_names()[1]
        self.plot2 = 'none'
        self.plot3 = 'none'
        self.update_axis(self.ax1, self.plot1, 0, 1, True, self.lineprops1,
                         self.smooth1)
        self.update_axis(self.ax2, self.plot2, 0, 1, True, self.lineprops2,
                         self.smooth2)
        self.update_axis(self.ax3, self.plot3, 0, 1, True, self.lineprops3,
                         self.smooth3)

    def XAxisAllowed(self):
        l = ''
        for name in self.gpx.get_header_names():
            l += '|' + name
        return l[1:]

    def YAxisAllowed(self):
        l = ''
        for name in self.gpx.get_header_names():
            l += '|' + name
        return l[1:]

    def Draw(self, blit):
        if blit:
            self.gpxcanvas.restore_region(self.background)
        else:
            self.gpxcanvas.draw()
            self.background = self.gpxcanvas.copy_from_bbox(self.ax1.bbox)
        if self.span != None and self.span.get_visible():
            self.ax1.draw_artist(self.span)
        if self.cursor != None:
            self.ax1.draw_artist(self.cursor)
        self.gpxcanvas.blit()

    def OnSize(self, event):
        pixels = self.GetClientSize()
        if pixels[0] < 20 or pixels[1] < 20:
            return
        self.SetSize(pixels)
        self.gpxcanvas.SetSize(pixels)
        self.gpxfig.set_size_inches(
            float(pixels[0]) / self.gpxfig.get_dpi(),
            float(pixels[1]) / self.gpxfig.get_dpi())
        leg = self.ax1.xaxis.get_tightbbox(self.gpxcanvas.get_renderer())
        leg1 = self.ax1.yaxis.get_tightbbox(self.gpxcanvas.get_renderer())
        leg2 = self.ax2.yaxis.get_tightbbox(self.gpxcanvas.get_renderer())
        leg3 = self.ax3.yaxis.get_tightbbox(self.gpxcanvas.get_renderer(
        ))  #leg2 and leg3 are exactly the same!!
        bottomalign = (leg.height + 5) / pixels[1]
        leftalign = (leg1.width + 5) / pixels[0]
        if self.plot2 == 'none' and self.plot3 == 'none':
            rightalign = (1 - (5.0) / pixels[0]) / self.axis_offset
        else:
            rightalign = (1 - (leg2.width + 5) / pixels[0]) / self.axis_offset
        if pixels[1] > 32:
            self.gpxfig.subplots_adjust(bottom=bottomalign)
        if pixels[0] > 32:
            self.gpxfig.subplots_adjust(left=leftalign, right=rightalign)
        ##PYTHON3
        self.gpxfig.subplots_adjust(right=0.9, left=0.06, bottom=0.2)
        self.Draw(False)

    def OnLeftMouseDblClick(self, event):
        #dble click. Let's get prepared
        xlo = self.num_to_x(self.ax1.get_xlim()[0], False)
        xhi = self.num_to_x(self.ax1.get_xlim()[1], False)
        y1lo = self.ax1.get_ylim()[0]
        y1hi = self.ax1.get_ylim()[1]
        y2lo = self.ax2.get_ylim()[0]
        y2hi = self.ax2.get_ylim()[1]
        y3lo = self.ax3.get_ylim()[0]
        y3hi = self.ax3.get_ylim()[1]

        (dummy,xaxis,xlo,xhi,self.cursorcolor,self.cursorwidth,
        dummy,self.plot1,y1lo,y1hi,self.autoy1,self.smooth1,
        self.lineprops1['color'],self.lineprops1['linewidth'],self.lineprops1['marker'],self.lineprops1['markersize'],self.lineprops1['fill'],\
        dummy,self.plot2,y2lo,y2hi,self.autoy2,self.smooth2,
        self.lineprops2['color'],self.lineprops2['linewidth'],self.lineprops2['marker'],self.lineprops2['markersize'],self.lineprops2['fill'],\
        dummy,self.plot3,y3lo,y3hi,self.autoy3,self.smooth3,
        self.lineprops3['color'],self.lineprops3['linewidth'],self.lineprops3['marker'],self.lineprops3['markersize'],self.lineprops3['fill'])=\
            WxQuery("Graph Settings",\
                [('wxnotebook','X Axis',None,None,None),
                 ('wxcombo','X axis',self.XAxisAllowed(),self.xaxis,'str'),
                 ("wxentry","Start",None,str(xlo),'str'),
                 ("wxentry","End",None,str(xhi),'str'),
                 ('wxcolor','Cursor color',None,self.cursorcolor,'str'),
                 ('wxspin','Cursor width','0|6|1',self.cursorwidth,'int'),

                 ('wxnotebook','Y1Axis',None,None,None),
                 ('wxcombo','Channel 1',self.YAxisAllowed(),self.plot1,'str'),
                 ('wxentry','Bottom',None,y1lo,'float'),
                 ('wxentry','Top',None,y1hi,'float'),
                 ('wxcheck','Auto Scale','-9|-8', self.autoy1,'bool'), #8
                 ('wxhscale','Smooth','1|12|1|1',self.smooth1,'int'),
                 ('wxcolor','Color',None,self.lineprops1['color'],'str'),
                 ('wxspin','Line width','0|12|1',self.lineprops1['linewidth'],'int'),
                 ('wxcombo','Marker','.|o|+|x|^|4|s|*|D',self.lineprops1['marker'],'str'),
                 ('wxspin','Marker size','0|12|1',self.lineprops1['markersize'],'int'),
                 ('wxcheck','Fill area',None,self.lineprops1['fill'],'bool'),

                 ('wxnotebook','Y2 Axis',None,None,None),
                 ('wxcombo','Channel 2',self.YAxisAllowed(),self.plot2,'str'),
                 ('wxentry','Bottom',None,y2lo,'float'),
                 ('wxentry','Top',None,y2hi,'float'),
                 ('wxcheck','Auto Scale','-20|-19', self.autoy2,'bool'),
                 ('wxhscale','Smooth','1|12|1|1',self.smooth2,'int'),
                 ('wxcolor','Color',None,self.lineprops2['color'],'str'),
                 ('wxspin','Line width','0|12|1',self.lineprops2['linewidth'],'int'),
                 ('wxcombo','Marker','.|o|+|x|^|4|s|*|D',self.lineprops2['marker'],'str'),
                 ('wxspin','Marker size','0|12|1',self.lineprops2['markersize'],'int'),
                 ('wxcheck','Fill area',None,self.lineprops2['fill'],'bool'),

                 ('wxnotebook','Y3 Axis',None,None,None),
                 ('wxcombo','Channel 3',self.YAxisAllowed(),self.plot3,'str'),
                 ('wxentry','Bottom',None,y3lo,'float'),
                 ('wxentry','Top',None,y3hi,'float'),
                 ('wxcheck','Auto Scale','-31|-30', self.autoy3,'bool'),
                 ('wxhscale','Smooth','1|12|1|1',self.smooth3,'int'),
                 ('wxcolor','Color',None,self.lineprops3['color'],'str'),
                 ('wxspin','Line width','0|12|1',self.lineprops3['linewidth'],'int'),
                 ('wxcombo','Marker','.|o|+|x|^|4|s|*|D',self.lineprops3['marker'],'str'),
                 ('wxspin','Marker size','0|12|1',self.lineprops3['markersize'],'int'),
                 ('wxcheck','Fill area',None,self.lineprops3['fill'],'bool')
                ])
        if self.xaxis == xaxis:
            xlo = max(self.x_to_num(xlo, False), self.x_min())
            xhi = min(self.x_to_num(xhi, False), self.x_max())
            self.ax1.set_xlim([xlo, xhi])
        else:  #time units have changed... don't bother and set to full x range
            self.xaxis = xaxis
            self.ax1.set_xlim([self.x_min(), self.x_max()])
        self.update_axis(self.ax1, self.plot1, y1lo, y1hi, self.autoy1,
                         self.lineprops1, self.smooth1)
        self.update_axis(self.ax2, self.plot2, y2lo, y2hi, self.autoy2,
                         self.lineprops2, self.smooth2)
        self.update_axis(self.ax3, self.plot3, y3lo, y3hi, self.autoy3,
                         self.lineprops3, self.smooth3)

    def OnLeftMouseDown(self, event):
        where = self.get_axis(event, self.axis_width)
        #if hasattr(event, 'guiEvent') and int(event.guiEvent.type)==5:
        #calling direcly the dialog may freeze on unix (linux-osX systems) under wx backend
        #workaround   is to release mouse
        #see http://stackoverflow.com/questions/16815695/modal-dialog-freezes-the-whole-application
        #event.guiEvent.GetEventObject().ReleaseMouse() for pick_event
        if event.button == 1:
            if event.dblclick:
                try:
                    event.guiEvent.GetEventObject().ReleaseMouse()
                except:
                    pass
                self.OnLeftMouseDblClick(event)
                return
            if where == 'bottom':
                (self.x0, self.y0) = (event.xdata, event.ydata)
                self.press = True
            if where == 'main' and self.span != None:
                self.span.set_visible(True)
                (self.x0, self.y0) = (event.xdata, event.ydata)
                self.selstart = self.x0
                self.selstop = self.x0
                self.span.set_bounds(
                    event.xdata,
                    self.ax1.get_ylim()[0], 0,
                    self.ax1.get_ylim()[1] - self.ax1.get_ylim()[0])
                self.press = True
        elif event.button == 3:
            if where == 'main':
                self.OnRightMouseDown(event)

    def OnLeftMouseUp(self, event):
        where = self.get_axis(event, self.axis_width)
        self.press = False
        if event.button == 1 and self.span != None:
            if where == 'main':
                idx1 = np.searchsorted(self.ax1.get_lines()[0].get_data()[0],
                                       self.x0)
                idx2 = np.searchsorted(self.ax1.get_lines()[0].get_data()[0],
                                       event.xdata)
                self.selstart = min(idx1, idx2)
                self.selstop = max(idx1, idx2)
                if self.selstart == self.selstop:
                    self.span.set_visible(False)
                msgwrap.message("SelChanged",
                                arg1=self.id,
                                arg2=self.selstart,
                                arg3=self.selstop)
                self.press = False

    def OnRightMouseDown(self, event):
        #may be necessary in some OSes
        event.guiEvent.GetEventObject().ReleaseMouse()
        if self.selstart == self.selstop:
            self.select_menu.Enable(
                self.select_menu.FindItem("Disable selected"), False)
            self.select_menu.Enable(
                self.select_menu.FindItem("Enable selected"), False)
            self.select_menu.Enable(
                self.select_menu.FindItem("Delete selected"), False)
        else:
            self.select_menu.Enable(
                self.select_menu.FindItem("Disable selected"), True)
            self.select_menu.Enable(
                self.select_menu.FindItem("Enable selected"), True)
            self.select_menu.Enable(
                self.select_menu.FindItem("Delete selected"), True)
        self.select_menu.Enable(self.select_menu.FindItem("Toggle points"),
                                True)
        # on some OS (and depending on wxPython/wxWidgets version, calling
        # wx.PopupMenu will fail unless it is called after matplotlib handler has returned
        # for some magic reason, we do not need to specify wx.Point(event.x, event.y) in parameterss
        #self.PopupMenu(self.select_menus)
        wx.CallAfter(self.PopupMenu, self.select_menu)

    def OnMouseMotion(self, event):
        where = self.get_axis(event, self.axis_width)
        if where == 'bottom' or where == 'right' or where == 'left' or where == '3rd':
            wx.SetCursor(wx.Cursor(wx.CURSOR_MAGNIFIER))
        else:
            wx.SetCursor(wx.Cursor(wx.CURSOR_ARROW))
        if where == 'bottom' and self.press:
            dx = event.xdata - self.x0
            dy = event.ydata - self.y0
            self.ax1.set_xlim(self.ax1.get_xlim()[0] - dx,
                              self.ax1.get_xlim()[1] - dx)
            self.Draw(False)
        if where == 'main' and self.press:
            self.span.set_bounds(self.x0,\
                                self.ax1.get_ylim()[0],\
                                event.xdata-self.x0,\
                                self.ax1.get_ylim()[1]-self.ax1.get_ylim()[0])
            self.Draw(True)
        if where == 'main' and self.cursor != None:
            self.cursor.set_xdata(event.xdata)
            xval = event.xdata
            idx = np.searchsorted(self.ax1.get_lines()[0].get_data()[0], xval)
            while self.gpx['ok'][
                    idx] == False and idx >= 0:  #look for nearest enabled point
                idx -= 1
            idx = clamp(idx, 0, self.gpx.get_row_count() - 1)
            self.cursor.set_xdata(self.x_to_num(self.gpx[self.xaxis][idx]))
            msgwrap.message("CurChanged", arg1=self.id, arg2=idx)
            ##send a message for the status bar
            self.UpdateStatusBar(idx)
            self.Draw(True)

    def OnMouseWheel(self, event):
        where = self.get_axis(event, self.axis_width)
        if where == 'bottom':
            xmax = self.x_max()
            xmin = self.x_min()
            xlo, xhi = self.ax1.get_xlim()
            if event.button == 'down':
                scale_factor = 1.2
            else:
                scale_factor = 1 / 1.2
            nxhi = event.xdata + (scale_factor * (xhi - event.xdata))
            nxlo = event.xdata - (scale_factor * (event.xdata - xlo))
            nxhi = min(nxhi, xmax)
            nxlo = max(nxlo, xmin)
            self.ax1.set_xlim([nxlo, nxhi])
            self.format_x_axis()
        elif where == 'left' or where == 'right' or where == '3rd':
            if where == 'left':
                ax = self.ax1
                plot = self.plot1
            elif where == 'right':
                ax = self.ax2
                plot = self.plot2
            elif where == '3rd':
                ax = self.ax3
                plot = self.plot3
            ymax = np.max(self.gpx[plot] * self.gpx.scale[plot])
            ymin = np.min(self.gpx[plot] * self.gpx.scale[plot])
            ylo, yhi = ax.get_ylim()
            if event.button == 'down':
                scale_factor = 1.2
            else:
                scale_factor = 1 / 1.2
            nyhi = event.ydata + (scale_factor * (yhi - event.ydata))
            nylo = event.ydata - (scale_factor * (event.ydata - ylo))
            nyhi = min(nyhi, ymax)
            nylo = max(nylo, ymin)
            ax.set_ylim([nylo, nyhi])
        self.Draw(False)

    def OnMouseEnter(self, event):
        self.SetFocus(
        )  # stupid bug in wxSplitterWindow, mouse wheel is always send to the same panel in wxSplittedWIndow

    def OnMouseLeave(self, event):
        wx.SetCursor(wx.Cursor(wx.CURSOR_ARROW))
        pass

    def OnPopup(self, event):
        item = self.select_menu.FindItemById(event.GetId())
        text = item.GetText()
        if text == "Disable selected":
            self.gpx['ok'][self.selstart:self.selstop] = False
        if text == "Enable selected":
            self.gpx['ok'][self.selstart:self.selstop] = True
        if text == "Disable non selected":
            self.gpx['ok'][:self.selstart] = False
            self.gpx['ok'][self.selstop:] = False
        if text == "Enable non selected":
            self.gpx['ok'][:self.selstart] = True
            self.gpx['ok'][self.selstop:] = True
        if text == "Delete selected":
            if wx.MessageDialog(None, "Delete Points...?",\
                                'Are you sure you want to delete these points',\
                                wx.YES_NO | wx.ICON_QUESTION).ShowModal()==wx.ID_YES:
                for _ in range(self.selstart, self.selstop):
                    self.gpx.drop_row(
                        self.selstart
                    )  #each time we delete, the rest of the array is shifted. so we have to delete always the same index
        if text == "Delete non selected":
            if wx.MessageDialog(None, "Delete Points...?",\
                                'Are you sure you want to delete these points',\
                                wx.YES_NO | wx.ICON_QUESTION).ShowModal()==wx.ID_YES:
                for _ in range(self.selstop, self.gpx.get_row_count()):
                    self.gpx.drop_row(
                        self.selstop
                    )  #delete first end of range, to avoid shifting selstop
                for _ in range(0, self.selstart):
                    self.gpx.drop_row(0)
        if text == "Toggle points":
            self.gpx['ok'] = np.invert(self.gpx['ok'])
        msgwrap.message("ValChanged", arg1=self.id)
        self.update_axis(self.ax1, self.plot1,
                         self.ax1.get_ylim()[0],
                         self.ax1.get_ylim()[1], self.autoy1, self.lineprops1,
                         self.smooth1)
        self.update_axis(self.ax2, self.plot2,
                         self.ax2.get_ylim()[0],
                         self.ax2.get_ylim()[1], self.autoy2, self.lineprops2,
                         self.smooth2)
        self.update_axis(self.ax3, self.plot3,
                         self.ax3.get_ylim()[0],
                         self.ax3.get_ylim()[1], self.autoy3, self.lineprops3,
                         self.smooth3)

    def UpdateStatusBar(self, idx):
        if self.plot1 != "none":
            msg1=self.plot1+\
                " ("+str(self.gpx.get_unit(self.plot1)[0])+"): "\
                +str(self.gpx[self.plot1][idx]*self.gpx.scale[self.plot1])
        else:
            msg1 = ""
        if self.plot2 != "none":
            msg2=self.plot2+\
                " ("+str(self.gpx.get_unit(self.plot2)[0])+"): "\
                +str(self.gpx[self.plot2][idx]*self.gpx.scale[self.plot2])
        else:
            msg2 = ""
        if self.plot3 != "none":
            msg3=self.plot3+\
                " ("+str(self.gpx.get_unit(self.plot3)[0])+"): "\
                +str(self.gpx[self.plot3][idx]*self.gpx.scale[self.plot3])
        else:
            msg3 = ""
        msgwrap.message("StatusChanged",arg1=self.id,\
                            arg2=self.gpx['time'][idx],\
                            arg3=msg1,\
                            arg4=msg2,\
                            arg5=msg3
                            )
    def __init__(self, *args, **kwargs):
        kwargs['style'] = kwargs.setdefault(
            'style',
            wx.NO_FULL_REPAINT_ON_RESIZE) | wx.NO_FULL_REPAINT_ON_RESIZE
        wx.Panel.__init__(self, *args, **kwargs)
        self.id = wx.NewId()
        self.plot1 = 'none'
        self.plot2 = 'none'
        self.plot3 = 'none'
        self.lineprops1 = wxLineProps({'color': '#990000', 'fill': True})
        self.lineprops2 = wxLineProps({'color': '#009900', 'fill': True})
        self.lineprops3 = wxLineProps({'color': '#000099', 'fill': True})
        self.autoy1 = True
        self.autoy2 = True
        self.autoy3 = True
        self.smooth1 = 1
        self.smooth2 = 1
        self.smooth3 = 1
        self.xaxis = ''
        self.press = False
        self.cursor = None
        self.span = None
        self.selstart = 0
        self.selstop = 0
        self.enablecursor = True
        self.enablespan = True
        self.cursorcolor = '#FF0000'
        self.cursorwidth = 1

        self.gpxfig = Figure()
        self.ax1 = self.gpxfig.add_subplot(
            1, 1, 1
        )  # create a grid of 1 row, 1 col and put a subplot in the first cell of this grid
        self.gpxfig.subplots_adjust(right=0.9, left=0.06)

        self.ax2 = self.ax1.twinx()
        #self.ax2.spines["left"].set_visible(False)

        self.ax3 = self.ax1.twinx()
        self.ax3.spines["right"].set_position(("axes", self.axis_offset))
        #self.ax3.spines["left"].set_visible(False)
        # canvas and events
        self.gpxcanvas = FigureCanvas(self, -1, self.gpxfig)
        self.gpxcanvas.mpl_connect('scroll_event', self.OnMouseWheel)
        self.gpxcanvas.mpl_connect('button_press_event', self.OnLeftMouseDown)
        self.gpxcanvas.mpl_connect('button_release_event', self.OnLeftMouseUp)
        self.gpxcanvas.mpl_connect('motion_notify_event', self.OnMouseMotion)
        self.gpxcanvas.mpl_connect('resize_event', self.OnSize)
        self.gpxcanvas.mpl_connect('figure_enter_event', self.OnMouseEnter)
        self.gpxcanvas.mpl_connect('figure_leave_event', self.OnMouseLeave)
        self.Bind(wx.EVT_RIGHT_DOWN, self.OnRightMouseDown)
        self.sizer = wx.BoxSizer(wx.VERTICAL)
        self.sizer.Add(self.gpxcanvas, 1,
                       wx.LEFT | wx.TOP | wx.GROW | wx.EXPAND)
        self.SetSizer(self.sizer)
        #self.OnSize(None)

        msgwrap.register(self.OnSigCurChanged, signal="CurChanged")
        msgwrap.register(self.OnSigSelChanged, signal="SelChanged")
        msgwrap.register(self.OnSigValChanged, signal="ValChanged")

        #set background color to pure white
        #that code does not work on linux...
        #color = wx.SystemSettings.GetColour(wx.wx.SYS_COLOUR_BTNFACE)
        color = wx.Colour(255, 255, 255)
        self.gpxfig.set_facecolor(
            (color.red / 255.0, color.green / 255.0, color.blue / 255.0))
        self.gpxfig.set_edgecolor(
            (color.red / 255.0, color.green / 255.0, color.blue / 255.0))
        self.gpxfig.set_edgecolor((0.0, 0.0, 0.0))
        self.gpxcanvas.SetBackgroundColour(color)

        # create right now the popup menu
        self.select_menu = wx.Menu()
        for text in ["Disable selected",\
                            "Enable selected",\
                            "Delete selected",\
                            "Disable non selected",\
                            "Enable non selected",\
                            "Delete non selected",\
                            "Toggle points"]:
            item = self.select_menu.Append(wx.NewId(), text)
            self.Bind(wx.EVT_MENU, self.OnPopup, item)
Example #47
0
class GraphFrame(wx.Frame):
    """ The main frame of the application
    """
    title = 'Demo: dynamic matplotlib graph'

    def __init__(self):
        wx.Frame.__init__(self, None, -1, self.title)

        self.datagen = DataGen()
        self.data = [self.datagen.next()]
        self.paused = False

        self.create_menu()
        self.create_status_bar()
        self.create_main_panel()

        self.redraw_timer = wx.Timer(self)
        self.Bind(wx.EVT_TIMER, self.on_redraw_timer, self.redraw_timer)
        self.redraw_timer.Start(100)

    def create_menu(self):
        self.menubar = wx.MenuBar()

        menu_file = wx.Menu()
        m_expt = menu_file.Append(-1, "&Save plot\tCtrl-S",
                                  "Save plot to file")
        self.Bind(wx.EVT_MENU, self.on_save_plot, m_expt)
        menu_file.AppendSeparator()
        m_exit = menu_file.Append(-1, "E&xit\tCtrl-X", "Exit")
        self.Bind(wx.EVT_MENU, self.on_exit, m_exit)

        self.menubar.Append(menu_file, "&File")
        self.SetMenuBar(self.menubar)

    def create_main_panel(self):
        self.panel = wx.Panel(self)

        self.init_plot()
        self.canvas = FigCanvas(self.panel, -1, self.fig)

        self.xmin_control = BoundControlBox(self.panel, -1, "X min", 0)
        self.xmax_control = BoundControlBox(self.panel, -1, "X max", 50)
        self.ymin_control = BoundControlBox(self.panel, -1, "Y min", 0)
        self.ymax_control = BoundControlBox(self.panel, -1, "Y max", 100)

        self.pause_button = wx.Button(self.panel, -1, "Pause")
        self.Bind(wx.EVT_BUTTON, self.on_pause_button, self.pause_button)
        self.Bind(wx.EVT_UPDATE_UI, self.on_update_pause_button,
                  self.pause_button)

        self.cb_grid = wx.CheckBox(self.panel,
                                   -1,
                                   "Show Grid",
                                   style=wx.ALIGN_RIGHT)
        self.Bind(wx.EVT_CHECKBOX, self.on_cb_grid, self.cb_grid)
        self.cb_grid.SetValue(True)

        self.cb_xlab = wx.CheckBox(self.panel,
                                   -1,
                                   "Show X labels",
                                   style=wx.ALIGN_RIGHT)
        self.Bind(wx.EVT_CHECKBOX, self.on_cb_xlab, self.cb_xlab)
        self.cb_xlab.SetValue(True)

        self.hbox1 = wx.BoxSizer(wx.HORIZONTAL)
        self.hbox1.Add(self.pause_button,
                       border=5,
                       flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL)
        self.hbox1.AddSpacer(20)
        self.hbox1.Add(self.cb_grid,
                       border=5,
                       flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL)
        self.hbox1.AddSpacer(10)
        self.hbox1.Add(self.cb_xlab,
                       border=5,
                       flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL)

        self.hbox2 = wx.BoxSizer(wx.HORIZONTAL)
        self.hbox2.Add(self.xmin_control, border=5, flag=wx.ALL)
        self.hbox2.Add(self.xmax_control, border=5, flag=wx.ALL)
        self.hbox2.AddSpacer(24)
        self.hbox2.Add(self.ymin_control, border=5, flag=wx.ALL)
        self.hbox2.Add(self.ymax_control, border=5, flag=wx.ALL)

        self.vbox = wx.BoxSizer(wx.VERTICAL)
        self.vbox.Add(self.canvas, 1, flag=wx.LEFT | wx.TOP | wx.GROW)
        self.vbox.Add(self.hbox1, 0, flag=wx.ALIGN_LEFT | wx.TOP)
        self.vbox.Add(self.hbox2, 0, flag=wx.ALIGN_LEFT | wx.TOP)

        self.panel.SetSizer(self.vbox)
        self.vbox.Fit(self)

    def create_status_bar(self):
        self.statusbar = self.CreateStatusBar()

    def init_plot(self):
        self.dpi = 100

        self.BUF_LEN = 128  # Length of data buffer
        self.timestep = 1  # Time between samples
        self.period = BUF_LEN * timestep  # Period of 1 draw cycle
        self.height = 2000000  # Expected sample value range

        # X value (time)
        self.times = numpy.arange(0, period, timestep)

        self.channels = 5
        # Y values
        self.samples = numpy.zeros([BUF_LEN, channels])
        self.lines = []

        self.styles = ['r-', 'g-', 'y-', 'm-', 'k-']

        # create 5 subplots and set their axes limits
        self.fig, self.axes = plt.subplots(nrows=self.channels)
        for i in range(self.channels):
            (self.lines).extend((self.axes[i]).plot(times,
                                                    self.samples[:, i],
                                                    self.styles[i],
                                                    animated=True))
            (self.lines[i]).axes.set_ylim(-self.height, height)
            (self.lines[i]).axes.set_xlim(-self.timestep,
                                          self.period + self.timestep)

        # capture background of the figure
        self.backgrounds = [(self.fig).canvas.copy_from_bbox(ax.bbox)
                            for ax in self.axes]

        # Make a convenient zipped list for simultaneous access
        items = zip(self.lines, self.axes, self.backgrounds)

        (self.fig).show()
        (self.fig).canvas.draw()

        # Open serial connection
        self.ser = serial.Serial(3, baudrate=57600, timeout=1)
        (self.ser).setRTS(True)  #?
        (self.ser).setRTS(False)  #?

        # array to read in 4 bytes at a time
        self.data = deque()

        self.t = 0
        self.pos = 0

        self.tstart = time.time()
        while t < 2000:

            # plot 5 channels, up to 4-byte integers (long)
            while ser.inWaiting() > 4:
                data.append(bytearray(4))
                ser.readinto(data[-1])

            if len(data) > channels:
                for i in range(channels):
                    bytes = data.popleft()
                    # construct y value
                    height = (bytes[0] << 24) + (bytes[1] << 16) + (
                        bytes[2] << 8) + bytes[3]

                    # convert to signed long
                    if (height >= 0x80000000):
                        height = height - 0x100000000

                    samples[pos, i] = numpy.long(height)

                for j, (line, ax, background) in enumerate(items):
                    fig.canvas.restore_region(background)
                    line.set_ydata(samples[:, j])
                    ax.draw_artist(line)
                    fig.canvas.blit(ax.bbox)

                pos += 1
                if (pos == BUF_LEN):
                    pos = 0

                t += 1

        print ser.inWaiting()
        print len(data)
        ser.close

    def draw_plot(self):
        """ Redraws the plot
        """
        # when xmin is on auto, it "follows" xmax to produce a
        # sliding window effect. therefore, xmin is assigned after
        # xmax.
        #
        if self.xmax_control.is_auto():
            xmax = len(self.data) if len(self.data) > 50 else 50
        else:
            xmax = int(self.xmax_control.manual_value())

        if self.xmin_control.is_auto():
            xmin = xmax - 50
        else:
            xmin = int(self.xmin_control.manual_value())

        # for ymin and ymax, find the minimal and maximal values
        # in the data set and add a mininal margin.
        #
        # note that it's easy to change this scheme to the
        # minimal/maximal value in the current display, and not
        # the whole data set.
        #
        if self.ymin_control.is_auto():
            ymin = round(min(self.data), 0) - 1
        else:
            ymin = int(self.ymin_control.manual_value())

        if self.ymax_control.is_auto():
            ymax = round(max(self.data), 0) + 1
        else:
            ymax = int(self.ymax_control.manual_value())

        self.axes.set_xbound(lower=xmin, upper=xmax)
        self.axes.set_ybound(lower=ymin, upper=ymax)

        # anecdote: axes.grid assumes b=True if any other flag is
        # given even if b is set to False.
        # so just passing the flag into the first statement won't
        # work.
        #
        if self.cb_grid.IsChecked():
            self.axes.grid(True, color='gray')
        else:
            self.axes.grid(False)

        # Using setp here is convenient, because get_xticklabels
        # returns a list over which one needs to explicitly
        # iterate, and setp already handles this.
        #
        pylab.setp(self.axes.get_xticklabels(),
                   visible=self.cb_xlab.IsChecked())

        self.plot_data.set_xdata(np.arange(len(self.data)))
        self.plot_data.set_ydata(np.array(self.data))

        self.canvas.draw()

    def on_pause_button(self, event):
        self.paused = not self.paused

    def on_update_pause_button(self, event):
        label = "Resume" if self.paused else "Pause"
        self.pause_button.SetLabel(label)

    def on_cb_grid(self, event):
        self.draw_plot()

    def on_cb_xlab(self, event):
        self.draw_plot()

    def on_save_plot(self, event):
        file_choices = "PNG (*.png)|*.png"

        dlg = wx.FileDialog(self,
                            message="Save plot as...",
                            defaultDir=os.getcwd(),
                            defaultFile="plot.png",
                            wildcard=file_choices,
                            style=wx.SAVE)

        if dlg.ShowModal() == wx.ID_OK:
            path = dlg.GetPath()
            self.canvas.print_figure(path, dpi=self.dpi)
            self.flash_status_message("Saved to %s" % path)

    def on_redraw_timer(self, event):
        # if paused do not add data, but still redraw the plot
        # (to respond to scale modifications, grid change, etc.)
        #
        if not self.paused:
            self.data.append(self.datagen.next())

        self.draw_plot()

    def on_exit(self, event):
        self.Destroy()

    def flash_status_message(self, msg, flash_len_ms=1500):
        self.statusbar.SetStatusText(msg)
        self.timeroff = wx.Timer(self)
        self.Bind(wx.EVT_TIMER, self.on_flash_status_off, self.timeroff)
        self.timeroff.Start(flash_len_ms, oneShot=True)

    def on_flash_status_off(self, event):
        self.statusbar.SetStatusText('')
Example #48
0
class PlotPanel(wx.Panel):
    """
    The PlotPanel has a Figure and a Canvas. OnSize events simply set a 
    flag, and the actual resizing of the figure is triggered by an Idle event.
    See:
        http://www.scipy.org/Matplotlib_figure_in_a_wx_panel
    """
    def __init__(self, parent, dataframes, color=None, dpi=None, **kwargs):
        # initialize Panel
        if 'id' not in kwargs.keys():
            kwargs['id'] = wx.ID_ANY
        if 'style' not in kwargs.keys():
            kwargs['style'] = wx.NO_FULL_REPAINT_ON_RESIZE
        wx.Panel.__init__(self, parent, **kwargs)
        self.parent = parent
        self.dataframes = dataframes

        # initialize matplotlib stuff
        self.figure = Figure(None, dpi)
        self.figure.autofmt_xdate()
        self.canvas = FigureCanvasWxAgg(self, -1, self.figure)
        self.SetColor(color)
        #self._SetSize((800, 600))

        self.draw()
        self._resizeflag = False
        self.Bind(wx.EVT_IDLE, self._onIdle)
        self.Bind(wx.EVT_SIZE, self._onSize)

    def SetColor(self, rgbtuple=None):
        """Set figure and canvas colours to be the same."""
        if rgbtuple is None:
            rgbtuple = wx.SystemSettings.GetColour(wx.SYS_COLOUR_BTNFACE).Get()
        clr = [c / 255. for c in rgbtuple]
        self.figure.set_facecolor(clr)
        self.figure.set_edgecolor(clr)
        self.canvas.SetBackgroundColour(wx.Colour(*rgbtuple))

    def _onSize(self, event):
        self._resizeflag = True

    def _onIdle(self, evt):
        if self._resizeflag:
            self._resizeflag = False
            self._SetSize()

    def _SetSize(self, size=None):
        if size is None:
            size = tuple(self.GetClientSize())
        self.SetSize(size)
        self.canvas.SetSize(size)
        self.figure.set_size_inches(
            float(size[0]) / self.figure.get_dpi(),
            float(size[1]) / self.figure.get_dpi())

    def draw(self):
        ax = self.figure.add_subplot(111)
        for dataframe in self.dataframes:
            x = dataframe.index
            for col in dataframe.columns:
                empty = dataframe[col].count() == 0
                y = dataframe[col].values if not empty else np.zeros(x.shape)
                ax.plot(x, y, label=col)

        try:
            self.figure.autofmt_xdate()
        except:
            pass

        ax.legend(loc="best")
        ax.grid()
class FourierDemoFrame(wx.Frame):
    def __init__(self, *args, **kwargs):
        wx.Frame.__init__(self, *args, **kwargs)
        panel = wx.Panel(self)

        # create the GUI elements
        self.createCanvas(panel)
        self.createSliders(panel)

        # place them in a sizer for the Layout
        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(self.canvas, 1, wx.EXPAND)
        sizer.Add(self.frequencySliderGroup.sizer,
                  0,
                  wx.EXPAND | wx.ALIGN_CENTER | wx.ALL,
                  border=5)
        sizer.Add(self.amplitudeSliderGroup.sizer,
                  0,
                  wx.EXPAND | wx.ALIGN_CENTER | wx.ALL,
                  border=5)
        panel.SetSizer(sizer)

    def createCanvas(self, parent):
        self.lines = []
        self.figure = Figure()
        self.canvas = FigureCanvasWxAgg(parent, -1, self.figure)
        self.canvas.callbacks.connect('button_press_event', self.mouseDown)
        self.canvas.callbacks.connect('motion_notify_event', self.mouseMotion)
        self.canvas.callbacks.connect('button_release_event', self.mouseUp)
        self.state = ''
        self.mouseInfo = (None, None, None, None)
        self.f0 = Param(2., minimum=0., maximum=6.)
        self.A = Param(1., minimum=0.01, maximum=2.)
        self.createPlots()

        # Not sure I like having two params attached to the same Knob,
        # but that is what we have here... it works but feels kludgy -
        # although maybe it's not too bad since the knob changes both params
        # at the same time (both f0 and A are affected during a drag)
        self.f0.attach(self)
        self.A.attach(self)

    def createSliders(self, panel):
        self.frequencySliderGroup = SliderGroup(panel,
                                                label='Frequency f0:',
                                                param=self.f0)
        self.amplitudeSliderGroup = SliderGroup(panel,
                                                label=' Amplitude a:',
                                                param=self.A)

    def mouseDown(self, evt):
        if self.lines[0].contains(evt)[0]:
            self.state = 'frequency'
        elif self.lines[1].contains(evt)[0]:
            self.state = 'time'
        else:
            self.state = ''
        self.mouseInfo = (evt.xdata, evt.ydata, max(self.f0.value,
                                                    .1), self.A.value)

    def mouseMotion(self, evt):
        if self.state == '':
            return
        x, y = evt.xdata, evt.ydata
        if x is None:  # outside the axes
            return
        x0, y0, f0Init, AInit = self.mouseInfo
        self.A.set(AInit + (AInit * (y - y0) / y0), self)
        if self.state == 'frequency':
            self.f0.set(f0Init + (f0Init * (x - x0) / x0))
        elif self.state == 'time':
            if (x - x0) / x0 != -1.:
                self.f0.set(1. / (1. / f0Init + (1. / f0Init * (x - x0) / x0)))

    def mouseUp(self, evt):
        self.state = ''

    def createPlots(self):
        # This method creates the subplots, waveforms and labels.
        # Later, when the waveforms or sliders are dragged, only the
        # waveform data will be updated (not here, but below in setKnob).
        if not hasattr(self, 'subplot1'):
            self.subplot1, self.subplot2 = self.figure.subplots(2)
        x1, y1, x2, y2 = self.compute(self.f0.value, self.A.value)
        color = (1., 0., 0.)
        self.lines += self.subplot1.plot(x1, y1, color=color, linewidth=2)
        self.lines += self.subplot2.plot(x2, y2, color=color, linewidth=2)
        # Set some plot attributes
        self.subplot1.set_title(
            "Click and drag waveforms to change frequency and amplitude",
            fontsize=12)
        self.subplot1.set_ylabel("Frequency Domain Waveform X(f)", fontsize=8)
        self.subplot1.set_xlabel("frequency f", fontsize=8)
        self.subplot2.set_ylabel("Time Domain Waveform x(t)", fontsize=8)
        self.subplot2.set_xlabel("time t", fontsize=8)
        self.subplot1.set_xlim([-6, 6])
        self.subplot1.set_ylim([0, 1])
        self.subplot2.set_xlim([-2, 2])
        self.subplot2.set_ylim([-2, 2])
        self.subplot1.text(0.05,
                           .95,
                           r'$X(f) = \mathcal{F}\{x(t)\}$',
                           verticalalignment='top',
                           transform=self.subplot1.transAxes)
        self.subplot2.text(0.05,
                           .95,
                           r'$x(t) = a \cdot \cos(2\pi f_0 t) e^{-\pi t^2}$',
                           verticalalignment='top',
                           transform=self.subplot2.transAxes)

    def compute(self, f0, A):
        f = np.arange(-6., 6., 0.02)
        t = np.arange(-2., 2., 0.01)
        x = A * np.cos(2 * np.pi * f0 * t) * np.exp(-np.pi * t**2)
        X = A / 2 * \
            (np.exp(-np.pi * (f - f0) ** 2) + np.exp(-np.pi * (f + f0) ** 2))
        return f, X, t, x

    def setKnob(self, value):
        # Note, we ignore value arg here and just go by state of the params
        x1, y1, x2, y2 = self.compute(self.f0.value, self.A.value)
        # update the data of the two waveforms
        self.lines[0].set(xdata=x1, ydata=y1)
        self.lines[1].set(xdata=x2, ydata=y2)
        # make the canvas draw its contents again with the new data
        self.canvas.draw()
Example #50
0
class MainFrame(wx.Frame):
    def __init__(self):
        wx.Frame.__init__(self,
                          parent=None,
                          id=wx.ID_ANY,
                          title='Image Identifier',
                          size=(500, 500))

        # Dummy variables
        self.points = []
        self.xmin = None
        self.xmax = None
        self.ymin = None
        self.ymax = None
        self.dimensions = None
        self.outfile_paths = []
        self.outfile_xmin = []
        self.outfile_ymin = []
        self.outfile_xmax = []
        self.outfile_ymax = []

        # Panels
        graph_panel = wx.Panel(self)
        widget_panel = wx.Panel(self)

        # Plot stuff
        self.figure = Figure()
        self.axes = self.figure.add_subplot(111)
        self.canvas = FigureCanvas(graph_panel, wx.ID_ANY, self.figure)

        # Button stuff
        ok_button = wx.Button(widget_panel, id=wx.ID_ANY, label='Ok')
        cancel_button = wx.Button(widget_panel,
                                  id=wx.ID_ANY,
                                  label='Select Again')
        ok_button.Bind(wx.EVT_BUTTON, self.on_ok_button)
        cancel_button.Bind(wx.EVT_BUTTON, self.on_cancel_button)

        # Sizers
        gbs = wx.BoxSizer(wx.HORIZONTAL)
        gbs.Add(self.canvas, 1, wx.EXPAND)

        wbs = wx.BoxSizer(wx.HORIZONTAL)
        wbs.Add(ok_button, -1, wx.EXPAND)
        wbs.Add(cancel_button, -1, wx.EXPAND)

        bs = wx.BoxSizer(wx.VERTICAL)
        bs.Add(widget_panel, 1, wx.EXPAND)
        bs.Add(graph_panel, 2, wx.EXPAND)

        graph_panel.SetSizer(gbs)
        widget_panel.SetSizer(wbs)
        self.SetSizer(bs)

        # Call method to show image in plot
        self.index = 0
        self.paths = self.handle_filenames()
        self.add_picture(self.paths[self.index])

        # Connect clicking event
        self.canvas.mpl_connect('button_press_event', self.pick_point)

    def add_picture(self, pic_path):
        self.axes.clear()
        my_pic = cv2.imread(pic_path, cv2.IMREAD_COLOR)
        self.dimensions = my_pic.shape
        self.axes.imshow(my_pic)
        self.canvas.draw()

    def handle_filenames(self):
        cur_dir = os.getcwd()
        all_paths = os.listdir(cur_dir)
        paths = []
        for pathname in all_paths:
            if pathname.endswith('.jpg'):
                paths.append(pathname)
        return paths

    def pick_point(self, event):
        if event.inaxes:
            x, y = event.xdata, event.ydata
            self.points.append([x, y])
            if len(self.points) == 2:
                self.set_max_min()
                self.draw_box()

    def draw_box(self):
        self.axes.axvline(
            self.xmin,
            ymin=(self.dimensions[0] - self.ymin) / self.dimensions[0],
            ymax=(self.dimensions[0] - self.ymax) / self.dimensions[0],
            c='r')
        self.axes.axhline(self.ymin,
                          xmin=self.xmin / self.dimensions[1],
                          xmax=self.xmax / self.dimensions[1],
                          c='r')
        self.axes.axvline(
            self.xmax,
            ymin=(self.dimensions[0] - self.ymin) / self.dimensions[0],
            ymax=(self.dimensions[0] - self.ymax) / self.dimensions[0],
            c='r')
        self.axes.axhline(self.ymax,
                          xmin=self.xmin / self.dimensions[1],
                          xmax=self.xmax / self.dimensions[1],
                          c='r')
        self.canvas.draw()

    def set_max_min(self):
        x_val = [self.points[0][0], self.points[1][0]]
        y_val = [self.points[0][1], self.points[1][1]]

        self.xmin = int(round(min(x_val)))
        self.xmax = int(round(max(x_val)))
        self.ymin = int(round(min(y_val)))
        self.ymax = int(round(max(y_val)))

    def on_ok_button(self, event):
        print('Okay')
        self.outfile_paths.append(self.paths[self.index])
        # Pass coordinates and data
        self.outfile_xmin.append(self.xmin)
        self.outfile_ymin.append(self.ymin)
        self.outfile_xmax.append(self.xmax)
        self.outfile_ymax.append(self.ymax)

        self.index += 1
        if self.index < len(self.paths):
            # Clear variables and move to next picture
            self.points = []
            self.xmin = None
            self.xmax = None
            self.ymin = None
            self.ymax = None
            self.add_picture(self.paths[self.index])
        else:
            self.write_outfile()
            print(
                'info.dat has been created in the current working directory.')

    def on_cancel_button(self, event):
        self.points = []
        self.xmin = None
        self.xmax = None
        self.ymin = None
        self.ymax = None
        del self.axes.lines[:]
        self.canvas.draw()

    def write_outfile(self):
        outfile = open('info.dat', 'w')
        for i in range(len(self.outfile_paths)):
            outfile.write('{}  1  {} {} {} {}\n'.format(
                "positives/" + self.outfile_paths[i], self.outfile_xmin[i],
                self.outfile_ymin[i], self.outfile_xmax[i],
                self.outfile_ymax[i]))
Example #51
0
class t_C_MatPlot(My_Control_Class):
    def __init__(self, *args, **kwargs):
        My_Control_Class.__init__(self, *args, **kwargs)

        # *************************************************************
        # Create the panel with the plot controls
        # *************************************************************
        self.Panel = wx.Panel(self.Dock)
        self.CB_Grid = wx.CheckBox(self.Panel, -1, "Grid", pos=(0, 5))
        self.CP_Grid = wx.ColourPickerCtrl(self.Panel, -1, pos=(40, 1))
        wx.StaticText(self.Panel, -1, "BackGround-", pos=(70, 5))
        self.CP_BG = wx.ColourPickerCtrl(self.Panel, -1, pos=(130, 1))
        self.CB_Axis = wx.CheckBox(self.Panel, -1, "Axis", pos=(160, 5))
        self.CB_Legend = wx.CheckBox(self.Panel, -1, "Legend", pos=(210, 5))
        self.CB_Polar = wx.CheckBox(self.Panel, -1, "Low Res", pos=(275, 5))
        self.CB_FFT = wx.CheckBox(self.Panel, -1, "FFT", pos=(335, 5))

        bmp = wx.ArtProvider.GetBitmap(wx.ART_COPY, wx.ART_BUTTON, (16, 16))
        self.Button_ClipBoard = wx.BitmapButton(self.Panel,
                                                -1,
                                                bmp,
                                                pos=(375, 0))
        self.Button_ClipBoard.SetToolTipString('Copy to ClipBoard')

        bmp = wx.ArtProvider.GetBitmap(wx.ART_FILE_SAVE, wx.ART_BUTTON,
                                       (16, 16))
        self.Button_Image = wx.BitmapButton(self.Panel, -1, bmp, pos=(405, 0))
        self.Button_Image.SetToolTipString('Save as PNG-image')

        if self.Test:
            self.Spin = wx.SpinCtrl(self.Panel,
                                    wx.ID_ANY,
                                    min=1,
                                    max=5,
                                    pos=(435, 2),
                                    size=(40, 20))
            self.Spin.SetToolTipString('Select Demo')

        # background color of the not used part of the button bar
        self.Dock.SetBackgroundColour(self.Panel.GetBackgroundColour())
        # *************************************************************

        # *************************************************************
        # *************************************************************
        # These parameters must be set before the figure is created
        # EASIER to set these parameters from rcParams, than from rc,
        # because you can use deep nested properties
        #rc ('figure.subplot', 'left' = 0.5)  ## not accepted
        rcParams['figure.subplot.top'] = 0.95
        rcParams['figure.subplot.bottom'] = 0.05
        rcParams['figure.subplot.left'] = 0.1
        rcParams['figure.subplot.right'] = 0.97

        self.figure = Figure()
        self.Canvas = FigureCanvas(self.Dock, -1, self.figure)
        self.axes = self.figure.add_subplot(111)
        self.axes_2 = None
        self.lx = None
        # *************************************************************

        # *************************************************************
        # Try to reload the settings, otherwise set defaults
        # *************************************************************
        self.Legends = ('signal 1', 'signal 2')
        self.SignalsX = []
        self.SignalsY = []
        self.Pseudo_Color = False
        if self.Test and self.Ini:
            print('piep1')
            self.Ini.Section = 'MatPlot'
            #line = self.Ini.Read ( 'Pars', '' )
            self.Load_Settings(self.Ini)

        if self.Test:
            self.MatPlot_Example(self.Spin.GetValue())
        else:
            self.MatPlot_Redraw()
        # *************************************************************

        # *************************************************************
        # *************************************************************
        Sizer = wx.BoxSizer(wx.VERTICAL)
        Sizer.Add(self.Canvas, 1, wx.EXPAND)
        Sizer.Add(self.Panel, 0)
        self.Dock.SetSizer(Sizer)
        #Dock.Fit()

        # We need this for Ubuntu, and even then it works limited
        self.Dock.Bind(wx.EVT_SIZE, self._OnSize)
        # *************************************************************

        # *************************************************************
        # *************************************************************
        self.Dock.Bind(wx.EVT_COLOURPICKER_CHANGED, self.MatPlot_OnPolar,
                       self.CP_Grid)
        self.Dock.Bind(wx.EVT_COLOURPICKER_CHANGED, self.MatPlot_OnSet_CBs,
                       self.CP_BG)
        self.Dock.Bind(wx.EVT_CHECKBOX, self.MatPlot_OnSet_CBs, self.CB_Grid)
        self.Dock.Bind(wx.EVT_CHECKBOX, self.MatPlot_OnSet_CBs, self.CB_Axis)
        self.Dock.Bind(wx.EVT_CHECKBOX, self.MatPlot_OnSet_CBs, self.CB_Legend)
        self.Dock.Bind(wx.EVT_CHECKBOX, self.MatPlot_OnPolar, self.CB_Polar)
        self.Dock.Bind(wx.EVT_CHECKBOX, self.MatPlot_OnFFT, self.CB_FFT)
        self.Button_Image.Bind(wx.EVT_BUTTON, self.MatPlot_OnSaveImage,
                               self.Button_Image)
        self.Button_ClipBoard.Bind(wx.EVT_BUTTON, self.MatPlot_OnCopyClipBoard,
                                   self.Button_ClipBoard)

        if self.Test:
            self.Spin.Bind(wx.EVT_SPINCTRL, self.MatPlot_OnSpinEvent,
                           self.Spin)
            self.Dock.Bind(wx.EVT_CLOSE, self.MatPlot_OnClose)

        #if not ( self.connect ) :
        self.Dock.connect = self.Canvas.mpl_connect('motion_notify_event',
                                                    self.MatPlot_OnMotion)
        # *************************************************************

    # *************************************************************
    # We need this for Ubuntu, and even then it works limited
    # *************************************************************
    def _OnSize(self, event):
        event.Skip()
        wx.CallAfter(self.MatPlot_Redraw)

    # *************************************************************
    # *************************************************************
    def Calculate(self):
        # input might be one of the following:
        #   1:  <array>
        #   2:  list = [ <array>, [ <signal name>,  <signal color>, <linewidth> ] ]
        #
        # array might be one of the following:
        #   A: a 1-dimensional array  ==>  y(x), x=equidistant
        #   B: a 2-dimensional array, with second dimension = 2  ==>  y = f(x)
        #   C: a 2-dimensional array, with second dimension >> 6  ==> z = f(x,y)

        # we can either use signal, which is the input channel that has changed
        # or use the Bricks input channels, so we can use all of them at once

        self.SignalsX = []
        self.SignalsY = []
        self.Legends = []

        # for test purposes, we don't have a brick but Test_Inputs
        try:
            Inputs = self.Brick.In
        except:
            Inputs = self.Test_Inputs

        for s, IVV in enumerate(Inputs[1:]):
            if IVV != None:
                #print 'MatPlot',s,len(IVV)
                if not ( operator.isSequenceType ( IVV ) ) or \
                   isinstance ( IVV, ndarray ):
                    IVV = eval('[IVV]')
                    #print 'no sequence'

                # determine the number of arrays
                # if exactly 2, special case: x,y pairs
                NA = 0
                for IV in IVV:
                    if isinstance(IV, ndarray):
                        NA += 1
                    else:
                        break

                #print 'NA',NA,IVV[0].shape

                # process all signals
                self.Pseudo_Color = False
                if IVV[0].ndim == 2:
                    self.Pseudo_Color = True
                    self.SignalsX.append(IVV[0])

                elif NA == 1:
                    L = len(IVV[0])
                    self.SignalsX.append(linspace(0, L - 1, L))
                    self.SignalsY.append(IVV[0])

                elif NA == 2:
                    self.SignalsX.append(IVV[0])
                    self.SignalsY.append(IVV[1])

                else:
                    self.SignalsX.append(IVV[0])
                    for i, IV in enumerate(IVV[1:NA]):
                        self.SignalsY.append(IV)

                # add legends
                if NA == 1:
                    if (len(IVV) > NA) and (len(IVV[NA]) > 0):
                        self.Legends.append(IVV[NA][0])
                    else:
                        self.Legends.append('Signal 1')
                for i, IV in enumerate(IVV[1:NA]):
                    if (len(IVV) > NA) and (len(IVV[NA]) > i):
                        self.Legends.append(IVV[NA][i])
                    else:
                        self.Legends.append('Signal ' + str(i + 1))

        #print 'Legends',self.Legends
        self.MatPlot_ReCreate_Plot()
        #print 'MatPlot recreated'

    # *************************************************************
    # *************************************************************
    def MatPlot_ReCreate_Plot(self):
        # BUG, "hold" doesn't work in polar, therefore create a new figure

        # helps sometimes .... for polar plot
        ## LUKT NIET MEER rcParams [ 'grid.color' ] = self.Color_2_MatPlot ( self.CP_Grid.GetColour () )

        self.figure.clear()
        self.lx = None

        if not (self.Pseudo_Color):
            self.CB_Polar.SetLabel('-Polar')

            if self.CB_FFT.GetValue(): config = 212
            else: config = 111
            self.axes = self.figure.add_subplot(config,
                                                polar=self.CB_Polar.GetValue())
            for i, SX in enumerate(self.SignalsY):
                self.axes.plot(
                    self.SignalsX[0],
                    self.SignalsY[i],
                )

            if self.CB_FFT.GetValue():
                self.axes_2 = self.figure.add_subplot(
                    211, polar=self.CB_Polar.GetValue())
                for i, SX in enumerate(self.SignalsY):
                    self.axes_2.psd(
                        self.SignalsY[i],
                        512,
                        1,
                        #detrend = mlab.detrend_linear,  #doesn't work
                        #detrend = mlab.detrend_mean,    #doesn't work
                        detrend=mlab.detrend_none,
                        #window = mlab.window_none )     #weird scaling
                        window=mlab.window_hanning)
                    # doesn't work:
                    # self.axes_2.xlabel = 'aap'
                    # self.axes_2.axis ( 0, 0, 50, -50)
            else:
                self.axes_2 = None

        else:  # Pseudo color
            self.CB_FFT.Hide()
            self.CB_Polar.SetLabel('-Low Res')
            self.axes = self.figure.add_subplot(111)

            if self.CB_Polar.GetValue():
                cmap = cm.get_cmap('jet', 10)  # 10 discrete colors
            else:
                cmap = cm.jet
            #cmap = cm.gray
            # IMPORTANT, setting the size explictly,
            # prevents rescaling which sometimes occurs when crosshair is drawn
            s = self.SignalsX[0].shape
            try:  # SignalsX might not be available yet
                im = self.axes.imshow(self.SignalsX[0],
                                      cmap=cmap,
                                      extent=(0, s[0], 0, s[1]))

                #im.set_interpolation ( 'nearest' )    # and there are a lot more !!
                #im.set_interpolation ( 'bicubic' )
                im.set_interpolation('bilinear')
                self.figure.colorbar(im)
            except:
                pass

        self.axes.hold(True)  # needed for measurement cursor
        if self.axes_2: self.axes_2.hold(True)
        self.MatPlot_Redraw()

    # *************************************************************
    # *************************************************************
    def MatPlot_Redraw(self):
        color = self.CP_BG.GetColour()
        color = self.Color_2_MatPlot(color)
        self.axes.set_axis_bgcolor(color)
        if self.axes_2: self.axes_2.set_axis_bgcolor(color)
        self.figure.set_facecolor(color)
        self.figure.set_edgecolor(color)

        if self.CB_Axis.GetValue():
            self.axes.set_axis_on()
            if self.axes_2: self.axes_2.set_axis_on()
        else:
            self.axes.set_axis_off()
            if self.axes_2: self.axes_2.set_axis_off()

        color = self.CP_Grid.GetColour()
        color = self.Color_2_MatPlot(color)
        self.axes.grid(self.CB_Grid.GetValue())
        if self.axes_2: self.axes_2.grid(self.CB_Grid.GetValue())
        # setting the grid color sometimes generates an exception
        # this seems to happen completely random ????
        try:
            if self.CB_Grid.GetValue():
                self.axes.grid(color=color)
                if self.axes_2: self.axes_2.grid(color=color)
        except:
            pass

        # Polar doesn't support legend (use figlegend)
        if self.Pseudo_Color or not (self.CB_Polar.GetValue()):
            if self.CB_Legend.GetValue():
                self.axes.legend(self.Legends)
            else:
                self.axes.legend_ = None
        # FFT plot: no legend
        if self.axes_2:
            self.axes_2.legend_ = None

        self.Canvas.draw()

    # *************************************************************
    # create an example image
    # *************************************************************
    def MatPlot_Example(self, Example):
        self.Test_Inputs = [None]
        if Example == 1:  # Sine
            x = arange(0.0, 3.0, 0.01)
            y = sin(2 * pi * x)

        elif Example == 2:  # SPIRAL
            t = arange(0, 10 * pi, 0.1)
            x = t * sin(t)
            y = t * cos(t)

        elif Example == 3:  # CARDIOID
            t = arange(0, 2 * pi, 0.1)
            x = (1 + cos(t)) * cos(t)
            y = (1 + cos(t)) * sin(t)

        elif Example == 4:  # SPIROGRAPH
            phi = linspace(0, 4, 100)
            #r=sin(phi*pi) #
            r = sin(cos(tan(phi)))
            x = phi
            y = 20 * r

        elif Example == 5:  # Pseudo Color

            def _func(x, y):
                return (1 - x / 2 + x**5 + y**3) * exp(-x**2 - y**2)

            dx, dy = 0.05, 0.05
            x = arange(-3.0, 3.0, dx)
            y = arange(-3.0, 3.0, dy)
            X, Y = meshgrid(x, y)
            self.Test_Inputs.append(_func(X, Y))

        if len(self.Test_Inputs) == 1:
            temp = []
            temp.append(x)
            temp.append(y)
            self.Test_Inputs.append(temp)

        self.Calculate()

    # *************************************************************
    # *************************************************************
    def MatPlot_OnMotion(self, event):
        if self.CB_Polar.GetValue() and not (self.Pseudo_Color): return

        x, y = event.x, event.y
        # check if within an "axes" but not in a "bar-axes"
        if event.inaxes and isinstance(event.inaxes, matplotlib.axes.Subplot):
            x, y = event.xdata, event.ydata

            if not (self.lx):
                self.minx, self.maxx = event.inaxes.get_xlim()
                self.miny, self.maxy = event.inaxes.get_ylim()
                """
        self.lx, = self.axes.plot ( ( self.minx, self.maxx ), ( y, y ), 'k-' )  # the horiz line
        self.ly, = self.axes.plot ( ( x, x ), ( self.miny, self.maxy ), 'k-' )  # the vert line
        self.meas_txt = self.axes.text ( 0.02, 0.02, 'x=%1.2f, y=%1.2f'% ( x, y ),
                                         transform = self.axes.transAxes )
        """
                self.lx, = event.inaxes.plot((self.minx, self.maxx), (y, y),
                                             'k-')  # the horiz line
                self.ly, = event.inaxes.plot((x, x), (self.miny, self.maxy),
                                             'k-')  # the vert line
                self.meas_txt = event.inaxes.text(
                    0.02,
                    0.02,
                    'x=%1.2f, y=%1.2f' % (x, y),
                    transform=event.inaxes.transAxes)
            else:
                # update the crosshair positions
                self.lx.set_data((self.minx, self.maxx), (y, y))
                self.ly.set_data((x, x), (self.miny, self.maxy))
                self.meas_txt.set_text('x=%1.2f, y=%1.2f' % (x, y))

        else:
            # Hide the cross hair
            if self.lx:
                self.lx.set_data((x, x), (y, y))
                self.ly.set_data((x, x), (y, y))
                self.meas_txt.set_text('')
                self.lx = None

        self.Canvas.draw()

    # *************************************************************
    # *************************************************************
    def MatPlot_OnSet_CBs(self, event):
        self.MatPlot_Redraw()

    # *************************************************************
    # *************************************************************
    def MatPlot_OnPolar(self, event):
        if self.CB_Polar.GetValue(): self.CB_FFT.Hide()
        else: self.CB_FFT.Show()
        self.MatPlot_ReCreate_Plot()

    # *************************************************************
    # *************************************************************
    def MatPlot_OnFFT(self, event):
        if self.CB_FFT.GetValue(): self.CB_Polar.Hide()
        else: self.CB_Polar.Show()
        self.MatPlot_ReCreate_Plot()

    # *************************************************************
    # *************************************************************
    def MatPlot_OnSpinEvent(self, event):
        Example = event.GetInt()
        self.MatPlot_Example(Example)

    # *************************************************************
    # *************************************************************
    def MatPlot_OnCopyClipBoard(self, event):
        #canvas = FigureCanvasWxAgg(...)
        self.Canvas.Copy_to_Clipboard(event=event)

    # *************************************************************
    # *************************************************************
    def MatPlot_OnSaveImage(self, event):
        file = Ask_File_For_Save(os.getcwd(),
                                 FileTypes='*.png',
                                 Title='Save Plot as PNG-image')
        if file:
            self.figure.savefig(file)

    # *************************************************************
    # Set Grid color of all backgrounds
    # Doing this gives huges problems,
    # therefor we accept that in the polar
    # *************************************************************
    """
  def OnGridColor ( self, event ) :
    rcParams [ 'grid.color' ] = self.Color_2_MatPlot ( self.CP_Grid.GetColour () )

    # Because we need to reload the resources,
    # we force it by recreating to the total plot
    self.Sizer.Remove ( self.Canvas )
    self.figure = Figure ()
    self.Canvas = FigureCanvas ( self.Dock, -1, self.figure )
    self.lx = None
    self.Sizer.Prepend ( self.Canvas, 1, wx.EXPAND )
    self.Sizer.Layout ()
    self.MatPlot_Example ( self.Spin.GetValue () )
  """

    # *************************************************************
    # MatPlot accepts RGB colors in relative range 0..1,
    # alpha blend is also not accepted
    # *************************************************************
    def Color_2_MatPlot(self, color):
        # if already in MatPlot format, just return the same value
        if isinstance(color, float) or isinstance(color[0], float):
            return color
        # else limit to 3 elements in the range 0.0 ... 1.0
        kleur = []
        for c in color[:3]:
            kleur.append(c / 255.0)
        return kleur

    # *************************************************************
    # MatPlot accepts RGB colors in relative range 0..1,
    # alpha blend is also not accepted
    # *************************************************************
    def MatPlot_2_Color(self, color):
        # if already in normal format, just return the same value
        if isinstance(color, wx.Color):
            return color

        if isinstance(color, basestring):
            try:
                color = float(color)
            except:
                return color  # named color probably
        if isinstance(color, float):
            i = int(color * 255)
            kleur = [i, i, i]
        else:
            kleur = []
            if isinstance(color[0], float):
                for c in color[:3]:
                    kleur.append(int(255 * c))
            else:
                kleur = color[:3]
        kleur = wx.Color(*kleur)
        return kleur

    # *************************************************************
    # *************************************************************
    def MatPlot_OnClose(self, event):
        if self.Ini and self.Test:
            self.Ini.Section = 'MatPlot'
            self.Ini.Write('Pos', self.Dock.GetPosition())
            self.Ini.Write('Size', self.Dock.GetSize())
            self.Save_Settings(self.Ini)
        event.Skip()

    # *************************************************************
    # *************************************************************
    def Save_Settings(self, ini, key=None):
        if ini:
            line = []
            line.append(tuple(self.CP_BG.GetColour()))
            line.append(tuple(self.CP_Grid.GetColour()))
            line.append(self.CB_Grid.GetValue())
            line.append(self.CB_Axis.GetValue())
            line.append(self.CB_Legend.GetValue())
            line.append(self.CB_Polar.GetValue())
            line.append(self.CB_FFT.GetValue())
            if self.Test:
                line.append(self.Spin.GetValue())
            if not (key):
                key = 'CS_'
            v3print('MatPlot SAVE', key, '=', line)
            line = ini.Write(key, line)

    # *************************************************************
    # *************************************************************
    def Load_Settings(self, ini, key=None):
        #print 'llkwp',line
        if not (key):
            key = 'CS_'
        line = ini.Read(key, '')
        if line:
            self.CP_BG.SetColour(line[0])
            self.CP_Grid.SetColour(line[1])
            self.CB_Grid.SetValue(line[2])
            self.CB_Axis.SetValue(line[3])
            self.CB_Legend.SetValue(line[4])
            self.CB_Polar.SetValue(line[5])
            self.CB_FFT.SetValue(line[6])
            if self.Test:
                self.Spin.SetValue(line[7])
        self.MatPlot_ReCreate_Plot()
Example #52
0
    def __init__(self, *args, **kwargs):
        My_Control_Class.__init__(self, *args, **kwargs)

        # *************************************************************
        # Create the panel with the plot controls
        # *************************************************************
        self.Panel = wx.Panel(self.Dock)
        self.CB_Grid = wx.CheckBox(self.Panel, -1, "Grid", pos=(0, 5))
        self.CP_Grid = wx.ColourPickerCtrl(self.Panel, -1, pos=(40, 1))
        wx.StaticText(self.Panel, -1, "BackGround-", pos=(70, 5))
        self.CP_BG = wx.ColourPickerCtrl(self.Panel, -1, pos=(130, 1))
        self.CB_Axis = wx.CheckBox(self.Panel, -1, "Axis", pos=(160, 5))
        self.CB_Legend = wx.CheckBox(self.Panel, -1, "Legend", pos=(210, 5))
        self.CB_Polar = wx.CheckBox(self.Panel, -1, "Low Res", pos=(275, 5))
        self.CB_FFT = wx.CheckBox(self.Panel, -1, "FFT", pos=(335, 5))

        bmp = wx.ArtProvider.GetBitmap(wx.ART_COPY, wx.ART_BUTTON, (16, 16))
        self.Button_ClipBoard = wx.BitmapButton(self.Panel,
                                                -1,
                                                bmp,
                                                pos=(375, 0))
        self.Button_ClipBoard.SetToolTipString('Copy to ClipBoard')

        bmp = wx.ArtProvider.GetBitmap(wx.ART_FILE_SAVE, wx.ART_BUTTON,
                                       (16, 16))
        self.Button_Image = wx.BitmapButton(self.Panel, -1, bmp, pos=(405, 0))
        self.Button_Image.SetToolTipString('Save as PNG-image')

        if self.Test:
            self.Spin = wx.SpinCtrl(self.Panel,
                                    wx.ID_ANY,
                                    min=1,
                                    max=5,
                                    pos=(435, 2),
                                    size=(40, 20))
            self.Spin.SetToolTipString('Select Demo')

        # background color of the not used part of the button bar
        self.Dock.SetBackgroundColour(self.Panel.GetBackgroundColour())
        # *************************************************************

        # *************************************************************
        # *************************************************************
        # These parameters must be set before the figure is created
        # EASIER to set these parameters from rcParams, than from rc,
        # because you can use deep nested properties
        #rc ('figure.subplot', 'left' = 0.5)  ## not accepted
        rcParams['figure.subplot.top'] = 0.95
        rcParams['figure.subplot.bottom'] = 0.05
        rcParams['figure.subplot.left'] = 0.1
        rcParams['figure.subplot.right'] = 0.97

        self.figure = Figure()
        self.Canvas = FigureCanvas(self.Dock, -1, self.figure)
        self.axes = self.figure.add_subplot(111)
        self.axes_2 = None
        self.lx = None
        # *************************************************************

        # *************************************************************
        # Try to reload the settings, otherwise set defaults
        # *************************************************************
        self.Legends = ('signal 1', 'signal 2')
        self.SignalsX = []
        self.SignalsY = []
        self.Pseudo_Color = False
        if self.Test and self.Ini:
            print('piep1')
            self.Ini.Section = 'MatPlot'
            #line = self.Ini.Read ( 'Pars', '' )
            self.Load_Settings(self.Ini)

        if self.Test:
            self.MatPlot_Example(self.Spin.GetValue())
        else:
            self.MatPlot_Redraw()
        # *************************************************************

        # *************************************************************
        # *************************************************************
        Sizer = wx.BoxSizer(wx.VERTICAL)
        Sizer.Add(self.Canvas, 1, wx.EXPAND)
        Sizer.Add(self.Panel, 0)
        self.Dock.SetSizer(Sizer)
        #Dock.Fit()

        # We need this for Ubuntu, and even then it works limited
        self.Dock.Bind(wx.EVT_SIZE, self._OnSize)
        # *************************************************************

        # *************************************************************
        # *************************************************************
        self.Dock.Bind(wx.EVT_COLOURPICKER_CHANGED, self.MatPlot_OnPolar,
                       self.CP_Grid)
        self.Dock.Bind(wx.EVT_COLOURPICKER_CHANGED, self.MatPlot_OnSet_CBs,
                       self.CP_BG)
        self.Dock.Bind(wx.EVT_CHECKBOX, self.MatPlot_OnSet_CBs, self.CB_Grid)
        self.Dock.Bind(wx.EVT_CHECKBOX, self.MatPlot_OnSet_CBs, self.CB_Axis)
        self.Dock.Bind(wx.EVT_CHECKBOX, self.MatPlot_OnSet_CBs, self.CB_Legend)
        self.Dock.Bind(wx.EVT_CHECKBOX, self.MatPlot_OnPolar, self.CB_Polar)
        self.Dock.Bind(wx.EVT_CHECKBOX, self.MatPlot_OnFFT, self.CB_FFT)
        self.Button_Image.Bind(wx.EVT_BUTTON, self.MatPlot_OnSaveImage,
                               self.Button_Image)
        self.Button_ClipBoard.Bind(wx.EVT_BUTTON, self.MatPlot_OnCopyClipBoard,
                                   self.Button_ClipBoard)

        if self.Test:
            self.Spin.Bind(wx.EVT_SPINCTRL, self.MatPlot_OnSpinEvent,
                           self.Spin)
            self.Dock.Bind(wx.EVT_CLOSE, self.MatPlot_OnClose)

        #if not ( self.connect ) :
        self.Dock.connect = self.Canvas.mpl_connect('motion_notify_event',
                                                    self.MatPlot_OnMotion)
Example #53
0
    def __init__(self,parent,id,title,dm):
        wx.Frame.__init__(self, parent, -1, title, size=signifWindowSize)
        
        if platform != "darwin":
            icon = wx.Icon("LogoIcon.ico", wx.BITMAP_TYPE_ICO)
            self.SetIcon(icon)

        self.signifNumBins=signifNumBins
        self.dm = dm
        
        self.Bind(wx.EVT_CLOSE,self.OnEnd)  
        
        self.WindowParent=parent
        sizer=wx.BoxSizer(wx.VERTICAL)

        panel = wx.Panel(self)

        # -------------- Begin of parameter selector

        sbParam = wx.StaticBox(panel, label="Parameter")
        sbParamSizer = wx.StaticBoxSizer(sbParam, wx.VERTICAL)
        sbParamSizer1 = wx.BoxSizer(wx.HORIZONTAL)
        sbParamSizer2 = wx.BoxSizer(wx.HORIZONTAL)
        
        AllBandsOrig = self.dm.GetVisibleBands()[0]
        AllBands=list(AllBandsOrig)
        AllBands.remove("Heart rate")

        bandsRB=[]

        for band in AllBands:
            if len(bandsRB)==0:
                tmp = wx.RadioButton(panel, label=band, style=wx.RB_GROUP)
                tmp.SetValue(True)
            else:
                tmp = wx.RadioButton(panel, label=band)
            bandsRB.append(tmp)
            if len(bandsRB)<=6:
                sbParamSizer1.Add(tmp, wx.EXPAND) 
            else:      
                sbParamSizer2.Add(tmp, wx.EXPAND) 
        
        sbParamSizer.Add(sbParamSizer1,flag=wx.EXPAND|wx.TOP|wx.LEFT|wx.RIGHT,border=borderBig)
        sbParamSizer.Add(sbParamSizer2,flag=wx.EXPAND|wx.TOP|wx.LEFT|wx.RIGHT,border=borderBig)
        sizer.Add(sbParamSizer,flag=wx.EXPAND|wx.TOP|wx.LEFT|wx.RIGHT,border=borderBig)

        for eachRB in bandsRB:
            self.Bind(wx.EVT_RADIOBUTTON,self.OnParam,eachRB)

        self.ActiveParam = AllBands[0]

        # -------------- End of parameter selector



        # -------------- Begin of tags selector

        sbTags = wx.StaticBox(panel, label="Episodes")
        sbTagsSizer = wx.StaticBoxSizer(sbTags, wx.HORIZONTAL)

        # tagsRB = []
        self.AllTags = self.dm.GetVisibleEpisodes()[0]
        self.ActiveTagLeft = self.AllTags[0]
        self.ActiveTagRight = None
        self.dm.SetSignifPlotParams(self.ActiveTagLeft,self.ActiveTagRight,self.ActiveParam)
        
        self.cbComboLeft=wx.ComboBox(panel,
            choices=self.AllTags,
            value=self.ActiveTagLeft,
            style=wx.CB_DROPDOWN|wx.CB_READONLY
            )
        sbTagsSizer.Add(self.cbComboLeft,flag=wx.ALL | wx.EXPAND, border=borderSmall)
        self.Bind(wx.EVT_COMBOBOX, self.OnComboLeft, id=self.cbComboLeft.GetId())
        

        sbTagsSizer.AddStretchSpacer(prop=1)

        ChoicesRight = ["Outside "+self.ActiveTagLeft]+self.AllTags
        ChoicesRight.remove(self.ActiveTagLeft)

        self.cbComboRight=wx.ComboBox(panel,
            choices=ChoicesRight, 
            value="Outside "+self.ActiveTagLeft, 
            style=wx.CB_DROPDOWN|wx.CB_READONLY
            )
        sbTagsSizer.Add(self.cbComboRight,flag=wx.ALL | wx.EXPAND, border=borderSmall)
        self.Bind(wx.EVT_COMBOBOX, self.OnComboRight, id=self.cbComboRight.GetId())


        sizer.Add(sbTagsSizer,flag=wx.EXPAND|wx.TOP|wx.LEFT|wx.RIGHT,border=borderBig)

        # -------------- End of tags selector


        # -------------- Begin of figure
        if ColoredBGPlots:
            self.fig = matplotlib.figure.Figure((5.0, 4.0),facecolor=SignifBGColor)
        else:
            self.fig = matplotlib.figure.Figure((5.0, 4.0))
            
        self.fig.subplots_adjust(left=0.05, bottom=0.18, right=0.98, top=0.92, wspace=0.20, hspace=0.15)
        self.canvas = FigureCanvas(panel, -1, self.fig)
        
        self.axes = self.fig.add_subplot(111)

        sizer.Add(self.canvas, 1, wx.LEFT | wx.TOP | wx.GROW)

        # -------------- End of figure

        # -------------- Begin of textbox and buttons

        hbox = wx.BoxSizer(wx.HORIZONTAL)   


        self.textOutput = wx.TextCtrl(panel, id, 'Information', size=(400, 75), style=wx.TE_READONLY|wx.TE_MULTILINE|wx.TE_RICH2)
        self.textOutput.SetFont(wx.Font(11, wx.FONTFAMILY_SWISS, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL));
        hbox.Add(self.textOutput, 1, wx.LEFT | wx.TOP | wx.GROW)

        endButton = wx.Button(panel, -1, "Close", size=buttonSizeSignif)
        self.Bind(wx.EVT_BUTTON, self.OnEnd, id=endButton.GetId())
        endButton.SetToolTip(wx.ToolTip("Click to close window"))
        hbox.Add(endButton, 0, border=borderBig, flag=wx.LEFT|wx.ALIGN_BOTTOM)
                
        sizer.Add(hbox, 0, flag=wx.EXPAND|wx.ALL, border=borderBig)

        # -------------- End of textbox and buttons

        panel.SetSizer(sizer)

        self.SetMinSize(signifWindowMinSize)

#        self.sb = self.CreateStatusBar()
#        self.sb.SetStatusText(self.sbSignifText)

#        self.canvas.Bind(wx.EVT_KEY_DOWN, self.OnKeyPress)

        self.Show(True)
        self.Layout()
        self.Refresh()
Example #54
0
class PlotPanel(BasePanel):
    """
    MatPlotlib 2D plot as a wx.Panel, suitable for embedding
    in any wx.Frame.   This does provide a right-click popup
    menu for configuration, zooming, saving an image of the
    figure, and Ctrl-C for copy-image-to-clipboard.

    For more features, see PlotFrame, which embeds a PlotPanel
    and also provides, a Menu, StatusBar, and Printing support.
    """

    def __init__(self, parent, size=(700, 450), dpi=150, axisbg=None,
                 facecolor=None, fontsize=9, trace_color_callback=None,
                 output_title='plot', with_data_process=True, theme=None,
                 **kws):

        self.trace_color_callback = trace_color_callback
        BasePanel.__init__(self, parent,
                           output_title=output_title, size=size, **kws)

        self.conf = PlotConfig(panel=self, theme=theme,
                               with_data_process=with_data_process)
        self.data_range = {}
        self.win_config = None
        self.cursor_callback = None
        self.lasso_callback = None
        self.cursor_mode = 'zoom'
        self.parent  = parent
        self.figsize = (size[0]*1.0/dpi, size[1]*1.0/dpi)
        self.dpi  = dpi
        self.conf.facecolor = ifnotNone(axisbg, self.conf.facecolor)
        self.conf.facecolor = ifnotNone(facecolor, self.conf.facecolor)

        # axesmargins : margins in px left/top/right/bottom
        self.axesmargins = (30, 30, 30, 30)

        self.BuildPanel()
        self.conf.user_limits = {} # [None, None, None, None]
        self.data_range = {}
        self.conf.zoom_lims = []
        self.conf.axes_traces = {}
        self.use_dates = False
        self.dates_style = None

    def plot(self, xdata, ydata, side='left', title=None,
             xlabel=None, ylabel=None, y2label=None,
             use_dates=False, dates_style=None, **kws):
        """
        create a new plot of x/y data, clearing any existing plot on the panel

        """
        allaxes = self.fig.get_axes()
        if len(allaxes) > 1:
            for ax in allaxes[1:]:
                if ax in self.data_range:
                    self.data_range.pop(ax)
                self.fig.delaxes(ax)

        self.data_range = {}
        self.conf.zoom_lims = []
        self.conf.axes_traces = {}
        self.clear()
        axes = self.axes
        if side == 'right':
            axes = self.get_right_axes()
        self.conf.reset_lines()
        self.conf.yscale = 'linear'
        self.conf.user_limits[axes] = 4*[None]

        if xlabel is not None:
            self.set_xlabel(xlabel, delay_draw=True)
        if ylabel is not None:
            self.set_ylabel(ylabel, delay_draw=True)
        if y2label is not None:
            self.set_y2label(y2label, delay_draw=True)
        if title is not None:
            self.set_title(title, delay_draw=True)
        self.dates_style = ifnotNone(dates_style, self.dates_style)
        self.use_dates = ifnotNone(use_dates, self.use_dates)
        return self.oplot(xdata, ydata, side=side, **kws)


    def oplot(self, xdata, ydata, side='left', label=None, xlabel=None,
              ylabel=None, y2label=None, title=None, dy=None,
              ylog_scale=None, xlog_scale=None, grid=None, xmin=None,
              xmax=None, ymin=None, ymax=None, color=None, style=None,
              drawstyle=None, linewidth=2, marker=None, markersize=None,
              refresh=True, show_legend=None, legend_loc='best',
              legend_on=True, delay_draw=False, bgcolor=None,
              framecolor=None, gridcolor=None, labelfontsize=None,
              titlefontsize=None, legendfontsize=None, fullbox=None,
              axes_style=None, zorder=None, viewpad=None, theme=None,
              use_dates=None, dates_style=None, **kws):
        """
        basic plot method, adding to an existing display

        """
        self.cursor_mode = 'zoom'
        conf = self.conf
        conf.plot_type = 'lineplot'
        axes = self.axes
        if theme is not None:
            conf.set_theme(theme=theme)
        if side == 'right':
            axes = self.get_right_axes()
        # set y scale to log/linear
        if ylog_scale is not None:
            conf.yscale = {False:'linear', True:'log'}[ylog_scale]

        if xlog_scale is not None:
            conf.xscale = {False:'linear', True:'log'}[xlog_scale]

        axes.xaxis.set_major_formatter(FuncFormatter(self.xformatter))
        self.dates_style = ifnotNone(dates_style, self.dates_style)
        self.use_dates = ifnotNone(use_dates, self.use_dates)
        if isinstance(xdata[0], datetime):
            self.use_dates = True

        if self.use_dates:
            # date handling options to get xdate to mpl dates
            #   1. xdate are in datetime: convert to mpl dates
            #   2. xdata are strings: parse with datestr2num
            #   3. xdata are floats:
            #        a) dates_styles=='dates': use directly
            #        b) else: convert as unix timestamp to mpl dates
            x0 = xdata[0]
            dstyle = self.dates_style
            if dstyle is None: dstyle = ''
            if isinstance(x0, datetime):
                xdata = dates.date2num(xdata)
            elif isinstance(x0, str) or dstyle.lower().startswith('str'):
                xdata = dates.datestr2num(xdata)
            elif not dstyle.lower().startswith('dates'):
                xdata = dates.epoch2num(xdata)
        linewidth = ifNone(linewidth, 2)
        conf.viewpad = ifnotNone(viewpad, conf.viewpad)

        if xlabel is not None:
            self.set_xlabel(xlabel, delay_draw=delay_draw)
        if ylabel is not None:
            self.set_ylabel(ylabel, delay_draw=delay_draw)
        if y2label is not None:
            self.set_y2label(y2label, delay_draw=delay_draw)
        if title  is not None:
            self.set_title(title, delay_draw=delay_draw)
        if show_legend is not None:
            conf.set_legend_location(legend_loc, legend_on)
            conf.show_legend = show_legend

        conf.show_grid = ifnotNone(grid, conf.show_grid)

        # set data range for this trace
        # datarange = [min(xdata), max(xdata), min(ydata), max(ydata)]

        if axes not in conf.user_limits:
            conf.user_limits[axes] = [None, None, None, None]

        conf.user_limits[axes][0] = ifnotNone(xmin, conf.user_limits[axes][0])
        conf.user_limits[axes][1] = ifnotNone(xmax, conf.user_limits[axes][1])
        conf.user_limits[axes][2] = ifnotNone(ymin, conf.user_limits[axes][2])
        conf.user_limits[axes][3] = ifnotNone(ymax, conf.user_limits[axes][3])

        if axes == self.axes:
            axes.yaxis.set_major_formatter(FuncFormatter(self.yformatter))
        else:
            axes.yaxis.set_major_formatter(FuncFormatter(self.y2formatter))

        zorder = ifNone(zorder, 5*(conf.ntrace+1))

        if axes not in conf.axes_traces:
            conf.axes_traces[axes] = []
        conf.axes_traces[axes].append(conf.ntrace)

        conf.gridcolor = ifnotNone(gridcolor, conf.gridcolor)
        conf.facecolor = ifnotNone(bgcolor, conf.facecolor)

        if framecolor is not None:
            self.canvas.figure.set_facecolor(framecolor)

        conf.set_trace_zorder(zorder, delay_draw=True)
        if color:
            conf.set_trace_color(color, delay_draw=True)
        if style:
            conf.set_trace_style(style, delay_draw=True)
        if marker:
            conf.set_trace_marker(marker, delay_draw=True)
        if linewidth is not None:
            conf.set_trace_linewidth(linewidth, delay_draw=True)
        if markersize is not None:
            conf.set_trace_markersize(markersize, delay_draw=True)
        if drawstyle is not None:
            conf.set_trace_drawstyle(drawstyle, delay_draw=True)
        if dy is None:
            _lines = axes.plot(xdata, ydata, drawstyle=drawstyle, zorder=zorder)
        else:
            _lines = axes.errorbar(xdata, ydata, yerr=dy, zorder=zorder)

        if axes not in conf.data_save:
            conf.data_save[axes] = []
        conf.data_save[axes].append((xdata, ydata))

        if conf.show_grid and axes == self.axes:
            # I'm sure there's a better way...
            for i in axes.get_xgridlines() + axes.get_ygridlines():
                i.set_color(conf.gridcolor)
                i.set_zorder(-100)
            axes.grid(True)
        else:
            axes.grid(False)

        if (self.conf.xscale == 'log' or self.conf.yscale == 'log'):
            self.set_logscale(xscale=self.conf.xscale,
                              yscale=self.conf.yscale,
                              delay_draw=delay_draw)

        if label is None:
            label = 'trace %i' % (conf.ntrace+1)
        conf.set_trace_label(label, delay_draw=True)
        needs_relabel = False
        if labelfontsize is not None:
            conf.labelfont.set_size(labelfontsize)
            needs_relabel = True
        if titlefontsize is not None:
            conf.titlefont.set_size(titlefontsize)
            needs_relabel = True

        if legendfontsize is not None:
            conf.legendfont.set_size(legendfontsize)
            needs_relabel = True

        if conf.ntrace < len(conf.lines):
            conf.lines[conf.ntrace] = _lines
        else:
            conf.init_trace(conf.ntrace, 'black', 'solid')
            conf.lines.append(_lines)

        # now set plot limits:
        if not delay_draw:
            self.set_viewlimits()

        if refresh:
            conf.refresh_trace(conf.ntrace)
            needs_relabel = True

        if conf.show_legend and not delay_draw:
            conf.draw_legend()

        if needs_relabel and not delay_draw:
            conf.relabel()


        # axes style ('box' or 'open')
        conf.axes_style = 'box'
        if fullbox is not None and not fullbox:
            conf.axes_style = 'open'
        if axes_style in ('open', 'box', 'bottom'):
            conf.axes_style = axes_style
        conf.set_axes_style(delay_draw=delay_draw)
        if not delay_draw:
            self.draw()
            self.canvas.Refresh()
        conf.ntrace = conf.ntrace + 1
        return _lines

    def plot_many(self, datalist, side='left', title=None,
                  xlabel=None, ylabel=None, **kws):
        """
        plot many traces at once, taking a list of (x, y) pairs
        """
        def unpack_tracedata(tdat, **kws):
            if (isinstance(tdat, dict) and
                'xdata' in tdat and 'ydata' in tdat):
                xdata = tdat.pop('xdata')
                ydata = tdat.pop('ydata')
                out = kws
                out.update(tdat)
            elif isinstance(tdat, (list, tuple)):
                out = kws
                xdata = tdat[0]
                ydata = tdat[1]
            return (xdata, ydata, out)

        opts = dict(side=side, title=title, xlabel=xlabel, ylabel=ylabel,
                    delay_draw=True)
        opts.update(kws)
        x0, y0, opts = unpack_tracedata(datalist[0], **opts)

        self.plot(x0, y0, **opts)

        for dat in datalist[1:]:
            x, y, opts = unpack_tracedata(dat, delay_draw=True)
            self.oplot(x, y, **opts)

        self.reset_formats()
        conf = self.conf
        if conf.show_legend:
            conf.draw_legend()
        conf.relabel()
        self.draw()
        self.canvas.Refresh()

    def add_text(self, text, x, y, side='left', size=None,
                 rotation=None, ha='left', va='center',
                 family=None, **kws):
        """add text at supplied x, y position
        """
        axes = self.axes
        if side == 'right':
            axes = self.get_right_axes()
        dynamic_size = False
        if size is None:
            size = self.conf.legendfont.get_size()
            dynamic_size = True
        t = axes.text(x, y, text, ha=ha, va=va, size=size,
                      rotation=rotation, family=family, **kws)
        self.conf.added_texts.append((dynamic_size, t))
        self.draw()

    def add_arrow(self, x1, y1, x2, y2,  side='left',
                  shape='full', color='black',
                  width=0.01, head_width=0.03, overhang=0, **kws):
        """add arrow supplied x, y position"""
        dx, dy = x2-x1, y2-y1

        axes = self.axes
        if side == 'right':
            axes = self.get_right_axes()
        axes.arrow(x1, y1, dx, dy, shape=shape,
                   length_includes_head=True,
                   fc=color, edgecolor=color,
                   width=width, head_width=head_width,
                   overhang=overhang, **kws)
        self.draw()

    def scatterplot(self, xdata, ydata, label=None, size=10,
                    color=None, edgecolor=None,
                    selectcolor=None, selectedge=None,
                    xlabel=None, ylabel=None, y2label=None,
                    xmin=None, xmax=None, ymin=None, ymax=None,
                    viewpad=None, title=None, grid=None, callback=None, **kw):

        if xlabel is not None:
            self.set_xlabel(xlabel)
        if ylabel is not None:
            self.set_ylabel(ylabel)
        if y2label is not None:
            self.set_y2label(y2label)
        if title  is not None:
            self.set_title(title)
        if grid is not None:
            self.conf.show_grid = grid
        if callback is not None:
            self.lasso_callback = callback

        self.conf.plot_type = 'scatter'
        self.cursor_mode = 'lasso'
        if color is not None:
            self.conf.scatter_normalcolor = color
        if edgecolor is not None:
            self.conf.scatter_normaledge  = edgecolor
        if selectcolor is not None:
            self.conf.scatter_selectcolor = selectcolor
        if selectedge is not None:
            self.conf.scatter_selectedge = selectedge
        if viewpad is not None:
            self.conf.viewpad = viewpad

        axes = self.axes
        self.conf.user_limits[axes] = [xmin, xmax, ymin, ymax]

        self.conf.axes_traces = {axes: [0]}
        self.conf.set_trace_label('scatterplot')
        # self.conf.set_trace_datarange((min(xdata), max(xdata),
        #                                min(ydata), max(ydata)))

        self.conf.scatter_xdata = xdata
        self.conf.scatter_ydata = ydata
        self.axes.scatter(xdata, ydata, c=self.conf.scatter_normalcolor,
                          edgecolors=self.conf.scatter_normaledge)

        if self.conf.show_grid:
            for i in axes.get_xgridlines()+axes.get_ygridlines():
                i.set_color(self.conf.gridcolor)
                i.set_zorder(-30)
            axes.grid(True)
        else:
            axes.grid(False)
        xrange = max(xdata) - min(xdata)
        yrange = max(ydata) - min(ydata)

        xmin = min(xdata) - xrange/25.0
        xmax = max(xdata) + xrange/25.0
        ymin = min(ydata) - yrange/25.0
        ymax = max(ydata) + yrange/25.0

        axes.set_xlim((xmin, xmax), emit=True)
        axes.set_ylim((ymin, ymax), emit=True)
        self.set_viewlimits()
        self.draw()

    def lassoHandler(self, vertices):
        conf = self.conf
        if self.conf.plot_type == 'scatter':
            xd, yd = conf.scatter_xdata, conf.scatter_ydata
            sdat = list(zip(xd, yd))
            oldmask = conf.scatter_mask
            try:
                self.axes.scatter(xd[where(oldmask)], yd[where(oldmask)],
                                  s=conf.scatter_size,
                                  c=conf.scatter_normalcolor,
                                  edgecolors=conf.scatter_normaledge)
            except IndexError:
                self.axes.scatter(xd, yd, s=conf.scatter_size,
                                  c=conf.scatter_normalcolor,
                                  edgecolors=conf.scatter_normaledge)

            mask = conf.scatter_mask = inside_poly(vertices, sdat)
            pts = nonzero(mask)[0]
            self.axes.scatter(xd[where(mask)], yd[where(mask)],
                              s=conf.scatter_size,
                              c=conf.scatter_selectcolor,
                              edgecolors=conf.scatter_selectedge)

        else:
            xdata = self.axes.lines[0].get_xdata()
            ydata = self.axes.lines[0].get_ydata()
            sdat = [(x, y) for x, y in zip(xdata, ydata)]
            mask = inside_poly(vertices,sdat)
            pts = nonzero(mask)[0]

        self.lasso = None
        self.draw()
        # self.canvas.draw_idle()
        if (self.lasso_callback is not None and
            hasattr(self.lasso_callback , '__call__')):
            self.lasso_callback(data = sdat,
                                selected=pts, mask=mask)

    def set_xylims(self, limits, axes=None, side='left'):
        "set user-defined limits and apply them"
        if axes is None:
            axes = self.axes
            if side == 'right':
                axes = self.get_right_axes()
        self.conf.user_limits[axes] = list(limits)
        self.unzoom_all()

    def set_viewlimits(self):
        """updates xy limits of a plot based on current data,
        user defined limits, and any zoom level

        """
        self.reset_formats()
        self.conf.set_viewlimits()

    def get_viewlimits(self, axes=None):
        if axes is None: axes = self.axes
        xmin, xmax = axes.get_xlim()
        ymin, ymax = axes.get_ylim()
        return (xmin, xmax, ymin, ymax)

    def clear(self):
        """ clear plot """
        for ax in self.fig.get_axes():
            ax.cla()
        self.conf.ntrace = 0
        self.conf.xlabel = ''
        self.conf.ylabel = ''
        self.conf.y2label = ''
        self.conf.title  = ''
        self.conf.data_save = {}

    def reset_config(self):
        """reset configuration to defaults."""
        self.conf.set_defaults()

    def unzoom(self, event=None, **kws):
        """ zoom out 1 level, or to full data range """
        self.reset_formats()
        self.conf.unzoom(full=False)

    def unzoom_all(self, event=None):
        """ zoom out full data range """
        self.reset_formats()
        self.conf.unzoom(full=True)

    def process_data(self, event=None, expr=None):
        if expr in self.conf.data_expressions:
            self.conf.data_expr = expr
            self.conf.process_data()
            self.draw()
        if expr is None:
            expr = ''
        if self.conf.data_deriv:
            if expr is None:
                expr = 'y'
            expr = "deriv(%s)" % expr
        self.write_message("plotting %s" % expr, panel=0)

    def toggle_deriv(self, evt=None, value=None):
        "toggle derivative of data"
        if value is None:
            self.conf.data_deriv = not self.conf.data_deriv

            expr = self.conf.data_expr or ''
            if self.conf.data_deriv:
                expr = "deriv(%s)" % expr
            self.write_message("plotting %s" % expr, panel=0)

            self.conf.process_data()

    def set_logscale(self, event=None, xscale='linear', yscale='linear',
                     delay_draw=False):
        "set log or linear scale for x, y axis"
        self.conf.set_logscale(xscale=xscale, yscale=yscale,
                               delay_draw=delay_draw)

    def toggle_legend(self, evt=None, show=None):
        "toggle legend display"
        if show is None:
            show = not self.conf.show_legend
            self.conf.show_legend = show
        self.conf.draw_legend()

    def toggle_grid(self, evt=None, show=None):
        "toggle grid display"
        if show is None:
            show = not self.conf.show_grid
        self.conf.enable_grid(show)

    def configure(self, event=None):
        """show configuration frame"""
        if self.win_config is not None:
            try:
                self.win_config.Raise()
            except:
                self.win_config = None

        if self.win_config is None:
            self.win_config = PlotConfigFrame(parent=self,
                                              config=self.conf,
                                              trace_color_callback=self.trace_color_callback)
            self.win_config.Raise()

    ####
    ## create GUI
    ####
    def BuildPanel(self):
        """ builds basic GUI panel and popup menu"""
        self.fig   = Figure(self.figsize, dpi=self.dpi)
        # 1 axes for now
        self.gridspec = GridSpec(1,1)
        self.axes  = self.fig.add_subplot(self.gridspec[0],
                                          facecolor=self.conf.facecolor)
        self.canvas = FigureCanvas(self, -1, self.fig)
        self.canvas.SetClientSize((self.figsize[0]*self.dpi, self.figsize[1]*self.dpi))
        self.canvas.SetMinSize((100, 100))

        self.printer.canvas = self.canvas
        self.set_bg(self.conf.framecolor)
        self.conf.canvas = self.canvas
        self.canvas.SetCursor(wxCursor(wx.CURSOR_CROSS))
        self.canvas.mpl_connect("pick_event", self.__onPickEvent)

        # overwrite ScalarFormatter from ticker.py here:
        self.axes.xaxis.set_major_formatter(FuncFormatter(self.xformatter))
        self.axes.yaxis.set_major_formatter(FuncFormatter(self.yformatter))

        # This way of adding to sizer allows resizing
        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(self.canvas, 2, wx.LEFT|wx.TOP|wx.BOTTOM|wx.EXPAND, 0)
        # self.SetAutoLayout(True)
        self.autoset_margins()
        self.SetSizer(sizer)
        self.SetSize(self.GetBestVirtualSize())

        canvas_draw = self.canvas.draw
        def draw(*args, **kws):
            self.autoset_margins()
            canvas_draw(*args, **kws)
        self.canvas.draw = draw
        self.addCanvasEvents()

    def BuildPopup(self):
        # build pop-up menu for right-click display
        self.popup_menu = popup = wx.Menu()
        MenuItem(self, popup, 'Configure', '',   self.configure)

        MenuItem(self, popup, 'Save Image', '',   self.save_figure)
        popup.AppendSeparator()

        MenuItem(self, popup, 'Undo Zoom/Pan', '',   self.unzoom)
        MenuItem(self, popup, 'Zoom all the way out', '', self.unzoom_all)

        popup.AppendSeparator()
        MenuItem(self, popup, 'Zoom X and Y', '',
                 partial(self.onZoomStyle, style='both x and y'),
                 kind=wx.ITEM_RADIO, checked=True)
        MenuItem(self, popup, 'Zoom X Only', '',
                 partial(self.onZoomStyle, style='x only'),
                 kind=wx.ITEM_RADIO)
        MenuItem(self, popup, 'Zoom Y Only', '',
                 partial(self.onZoomStyle, style='y only'),
                 kind=wx.ITEM_RADIO)

    def onZoomStyle(self, event=None, style='both x and y'):
        self.conf.zoom_style = style

    def _updateCanvasDraw(self):
        """ Overload of the draw function that update
        axes position before each draw"""
        fn = self.canvas.draw
        def draw2(*a,**k):
            self._updateGridSpec()
            return fn(*a,**k)
        self.canvas.draw = draw2

    def get_default_margins(self):
        """get default margins"""
        trans = self.fig.transFigure.inverted().transform

        # Static margins
        l, t, r, b = self.axesmargins
        (l, b), (r, t) = trans(((l, b), (r, t)))

        # Extent
        dl, dt, dr, db = 0, 0, 0, 0
        for i, ax in enumerate(self.fig.get_axes()):
            (x0, y0),(x1, y1) = ax.get_position().get_points()
            try:
                (ox0, oy0), (ox1, oy1) = ax.get_tightbbox(self.canvas.get_renderer()).get_points()
                (ox0, oy0), (ox1, oy1) = trans(((ox0 ,oy0),(ox1 ,oy1)))
                dl = min(0.2, max(dl, (x0 - ox0)))
                dt = min(0.2, max(dt, (oy1 - y1)))
                dr = min(0.2, max(dr, (ox1 - x1)))
                db = min(0.2, max(db, (y0 - oy0)))
            except:
                pass

        return (l + dl, t + dt, r + dr, b + db)

    def autoset_margins(self):
        """auto-set margins  left, bottom, right, top
        according to the specified margins (in pixels)
        and axes extent (taking into account labels,
        title, axis)
        """
        if not self.conf.auto_margins:
            return
        # coordinates in px -> [0,1] in figure coordinates
        trans = self.fig.transFigure.inverted().transform

        # Static margins
        if not self.use_dates:
            self.conf.margins = l, t, r, b = self.get_default_margins()
            self.gridspec.update(left=l, top=1-t, right=1-r, bottom=b)
        # Axes positions update
        for ax in self.fig.get_axes():
            try:
                ax.update_params()
            except ValueError:
                pass
            ax.set_position(ax.figbox)

    def draw(self):
        self.canvas.draw()

    def update_line(self, trace, xdata, ydata, side='left', draw=False,
                    update_limits=True):
        """ update a single trace, for faster redraw """

        x = self.conf.get_mpl_line(trace)
        x.set_data(xdata, ydata)
        # datarange = [xdata.min(), xdata.max(), ydata.min(), ydata.max()]
        # self.conf.set_trace_datarange(datarange, trace=trace)
        axes = self.axes
        if side == 'right':
            axes = self.get_right_axes()

        if update_limits:
            self.set_viewlimits()
        if draw:
            self.draw()

    def get_figure(self):
        return self.fig

    def __onPickEvent(self, event=None):
        """pick events"""
        legline = event.artist
        trace = self.conf.legend_map.get(legline, None)
        visible = True
        if trace is not None and self.conf.hidewith_legend:
            line, legline, legtext = trace
            visible = not line.get_visible()
            line.set_visible(visible)
            if visible:
                legline.set_zorder(10.00)
                legline.set_alpha(1.00)
                legtext.set_zorder(10.00)
                legtext.set_alpha(1.00)
            else:
                legline.set_alpha(0.50)
                legtext.set_alpha(0.50)


    ####
    ## GUI events
    ####
    def report_leftdown(self, event=None):
        if event is None:
            return
        ex, ey = event.x, event.y
        msg = ''
        try:
            x, y = self.axes.transData.inverted().transform((ex, ey))
        except:
            x, y = event.xdata, event.ydata

        if x is not None and y is not None:
            msg = "X,Y= %g, %g" % (x, y)
        if len(self.fig.get_axes()) > 1:
            ax2 = self.fig.get_axes()[1]
            try:
                x2, y2 = ax2.transData.inverted().transform((ex, ey))
                msg = "X,Y,Y2= %g, %g, %g" % (x, y, y2)
            except:
                pass

        nsbar = getattr(self, 'nstatusbar', 1)
        self.write_message(msg,  panel=max(0, nsbar - 2))
        if (self.cursor_callback is not None and
            hasattr(self.cursor_callback , '__call__')):
            self.cursor_callback(x=event.xdata, y=event.ydata)
Example #55
0
class myFrame(wx.Frame):
    def __init__(self):
        self.para_0 = {'SEQ': 'ON', 'SEQ_N': 200, 'polarity': 'negative'}
        #self.dos_0 = dso.Dso(self.para_0)
        super().__init__(None, -1, title='PALS', size=(1200, 800))

        #
        self.para_0['C1_TRLV'] = -0.1
        self.para_0['C2_TRLV'] = -0.1
        self.dos_0 = dso.Dso(self.para_0)
        #
        self.e_rg = {
            'c1': [0., 100.],
            'c2': [0., 100.],
            'c1_amp': [0., 5.],
            'c2_amp': [0., 5.]
        }
        self.lt_start_l = 0.
        self.lt_start_r = 300.
        self.start_fraction = 0.15
        self.lt_stop_l = 0.
        self.lt_stop_r = 300.
        self.stop_fraction = 0.2
        self.cps = 0.
        self.lt_bins = 100
        self.lt_l = -10.0
        self.lt_r = 10.0
        self.total_counts = 0
        self.counts_set = 1000000

        self.note1 = wx.Notebook(self)
        #建立page
        self.scorePanel = wx.Panel(self.note1)
        self.scorePanel_lt = wx.Panel(self.note1)
        self.note1.AddPage(self.scorePanel, "Energy")
        self.note1.AddPage(self.scorePanel_lt, "LifeTime")
        #能量显示窗口
        self.e_gridsizer = wx.GridBagSizer(2, 2)
        self.scorePanel.SetSizer(self.e_gridsizer)
        # self.box1 = wx.ListBox(self.scorePanel,size=(800, 500))
        # self.drawHistF = Figure(figsize=(8, 5), dpi=100)
        # self.drawHistCanvas = FigureCanvas(self.box1, -1, self.drawHistF)
        # self.drawHistCanvas.draw()
        self.box1 = wx.ListBox(self.scorePanel, size=(800, 500))
        self.e_gridsizer.Add(self.box1, pos=(0, 0), flag=wx.EXPAND)
        self.box2 = wx.Panel(self.scorePanel)
        self.e_gridsizer.Add(self.box2, pos=(0, 1), flag=wx.EXPAND)
        self.box3 = wx.Panel(self.scorePanel)
        self.e_gridsizer.Add(self.box3,
                             span=(1, 2),
                             pos=(1, 0),
                             flag=wx.EXPAND)
        self.scorePanel.Fit()

        self.drawHistF = Figure(figsize=(8, 5), dpi=100)
        self.drawHistCanvas = FigureCanvas(self.box1, -1, self.drawHistF)
        self.drawHistCanvas.draw()
        #右侧区域
        # self.box2 = wx.Panel(self.scorePanel, pos=(810, 0), size=(370, 500))
        # self.but1 = wx.Button(self.box2, 0, 'start', pos=(10, 10), size=(100, 50))
        # self.but2 = wx.Button(self.box2, 0, 'stop', pos=(120, 10), size=(100, 50))
        # self.but3 = wx.Button(self.box2, 0, 'clear', pos=(230, 10), size=(100, 50))
        # self.but1.Bind(wx.EVT_BUTTON, self.start_but)
        # self.but2.Bind(wx.EVT_BUTTON, self.stop_but)
        # self.but3.Bind(wx.EVT_BUTTON, self.energy_clear)
        self.eb2_gridsizer = wx.GridBagSizer(8, 3)
        self.box2.SetSizer(self.eb2_gridsizer)
        self.but1 = wx.Button(self.box2, -1, 'start')
        self.but2 = wx.Button(self.box2, -1, 'stop')
        self.but3 = wx.Button(self.box2, -1, 'clear')
        self.but1.Bind(wx.EVT_BUTTON, self.start_but)
        self.but2.Bind(wx.EVT_BUTTON, self.stop_but)
        self.but3.Bind(wx.EVT_BUTTON, self.energy_clear)
        self.eb2_gridsizer.Add(self.but1, pos=(0, 0), flag=wx.EXPAND)
        self.eb2_gridsizer.Add(self.but2, pos=(0, 1), flag=wx.EXPAND)
        self.eb2_gridsizer.Add(self.but3, pos=(0, 2), flag=wx.EXPAND)

        # 下方区域

        self.eb3_gridsizer = wx.GridBagSizer(1, 4)
        self.box3.SetSizer(self.eb3_gridsizer)
        self.eb3_c1_panel = wx.Panel(self.box3)
        self.eb3_gridsizer.Add(self.eb3_c1_panel, pos=(0, 0), flag=wx.EXPAND)
        self.eb3_c2_panel = wx.Panel(self.box3)
        self.eb3_gridsizer.Add(self.eb3_c2_panel, pos=(0, 1), flag=wx.EXPAND)
        # energy_c1_set
        self.eb3c1_gridsizer = wx.GridBagSizer(6, 4)
        self.eb3_c1_panel.SetSizer(self.eb3c1_gridsizer)
        self.eb3c1_title = wx.StaticText(self.eb3_c1_panel,
                                         -1,
                                         label='channel 1',
                                         style=wx.ALIGN_CENTER)
        self.font1 = wx.Font(15, wx.ROMAN, wx.NORMAL, wx.NORMAL)
        self.eb3c1_title.SetFont(self.font1)
        self.eb3c1_gridsizer.Add(self.eb3c1_title,
                                 span=(1, 4),
                                 pos=(0, 0),
                                 flag=wx.EXPAND)
        #
        self.eb3c1_trlv = wx.TextCtrl(self.eb3_c1_panel,
                                      -1,
                                      str(self.para_0['C1_TRLV']),
                                      style=wx.TE_CENTER)
        self.eb3c1_gridsizer.Add(self.eb3c1_trlv,
                                 span=(1, 2),
                                 pos=(1, 1),
                                 flag=wx.EXPAND)
        self.eb3c1_but1 = wx.Button(self.eb3_c1_panel, -1, 'Set')
        self.eb3c1_gridsizer.Add(self.eb3c1_but1,
                                 span=(1, 1),
                                 pos=(1, 3),
                                 flag=wx.EXPAND)
        self.eb3c1_but1.Bind(wx.EVT_BUTTON, self.e_c1_set_trlv)
        self.eb3c1_trlv_text = wx.StaticText(self.eb3_c1_panel,
                                             -1,
                                             'c1_trlv',
                                             style=wx.ALIGN_CENTER)
        self.eb3c1_trlv_text.SetFont(self.font1)
        self.eb3c1_gridsizer.Add(self.eb3c1_trlv_text,
                                 span=(1, 1),
                                 pos=(1, 0),
                                 flag=wx.EXPAND)
        #
        self.eb3c1_erg_l_text = wx.StaticText(self.eb3_c1_panel,
                                              -1,
                                              'energy_l',
                                              style=wx.ALIGN_CENTER)
        self.eb3c1_erg_l_text.SetFont(self.font1)
        self.eb3c1_gridsizer.Add(self.eb3c1_erg_l_text,
                                 span=(1, 1),
                                 pos=(2, 0),
                                 flag=wx.EXPAND)
        self.eb3c1_erg_l = wx.TextCtrl(self.eb3_c1_panel,
                                       -1,
                                       str(self.e_rg['c1'][0]),
                                       style=wx.TE_CENTER)
        self.eb3c1_gridsizer.Add(self.eb3c1_erg_l,
                                 span=(1, 1),
                                 pos=(2, 1),
                                 flag=wx.EXPAND)

        self.eb3c1_erg_r_text = wx.StaticText(self.eb3_c1_panel,
                                              -1,
                                              'energy_r',
                                              style=wx.ALIGN_CENTER)
        self.eb3c1_erg_r_text.SetFont(self.font1)
        self.eb3c1_gridsizer.Add(self.eb3c1_erg_r_text,
                                 span=(1, 1),
                                 pos=(2, 2),
                                 flag=wx.EXPAND)
        self.eb3c1_erg_r = wx.TextCtrl(self.eb3_c1_panel,
                                       -1,
                                       str(self.e_rg['c1'][1]),
                                       style=wx.TE_CENTER)
        self.eb3c1_gridsizer.Add(self.eb3c1_erg_r,
                                 span=(1, 1),
                                 pos=(2, 3),
                                 flag=wx.EXPAND)

        self.eb3c1_amp_l_text = wx.StaticText(self.eb3_c1_panel,
                                              -1,
                                              'amp_l',
                                              style=wx.ALIGN_CENTER)
        self.eb3c1_amp_l_text.SetFont(self.font1)
        self.eb3c1_gridsizer.Add(self.eb3c1_amp_l_text,
                                 span=(1, 1),
                                 pos=(3, 0),
                                 flag=wx.EXPAND)
        self.eb3c1_amp_l = wx.TextCtrl(self.eb3_c1_panel,
                                       -1,
                                       str(self.e_rg['c1_amp'][0]),
                                       style=wx.TE_CENTER)
        self.eb3c1_gridsizer.Add(self.eb3c1_amp_l,
                                 span=(1, 1),
                                 pos=(3, 1),
                                 flag=wx.EXPAND)

        self.eb3c1_amp_r_text = wx.StaticText(self.eb3_c1_panel,
                                              -1,
                                              'amp_r',
                                              style=wx.ALIGN_CENTER)
        self.eb3c1_amp_r_text.SetFont(self.font1)
        self.eb3c1_gridsizer.Add(self.eb3c1_amp_r_text,
                                 span=(1, 1),
                                 pos=(3, 2),
                                 flag=wx.EXPAND)
        self.eb3c1_amp_r = wx.TextCtrl(self.eb3_c1_panel,
                                       -1,
                                       str(self.e_rg['c1_amp'][1]),
                                       style=wx.TE_CENTER)
        self.eb3c1_gridsizer.Add(self.eb3c1_amp_r,
                                 span=(1, 1),
                                 pos=(3, 3),
                                 flag=wx.EXPAND)

        self.eb3c1_but2 = wx.Button(self.eb3_c1_panel, -1, 'Set')
        self.eb3c1_gridsizer.Add(self.eb3c1_but2,
                                 span=(1, 4),
                                 pos=(4, 0),
                                 flag=wx.EXPAND)
        self.eb3c1_but2.Bind(wx.EVT_BUTTON, self.e_c1_set_range)
        # energy_c2_set
        self.eb3c2_gridsizer = wx.GridBagSizer(6, 4)
        self.eb3_c2_panel.SetSizer(self.eb3c2_gridsizer)
        self.eb3c2_title = wx.StaticText(self.eb3_c2_panel,
                                         -1,
                                         label='channel 1',
                                         style=wx.ALIGN_CENTER)
        self.eb3c2_title.SetFont(self.font1)
        self.eb3c2_gridsizer.Add(self.eb3c2_title,
                                 span=(1, 4),
                                 pos=(0, 0),
                                 flag=wx.EXPAND)
        #
        self.eb3c2_trlv = wx.TextCtrl(self.eb3_c2_panel,
                                      -1,
                                      str(self.para_0['C2_TRLV']),
                                      style=wx.TE_CENTER)
        self.eb3c2_gridsizer.Add(self.eb3c2_trlv,
                                 span=(1, 2),
                                 pos=(1, 1),
                                 flag=wx.EXPAND)
        self.eb3c2_but1 = wx.Button(self.eb3_c2_panel, -1, 'Set')
        self.eb3c2_gridsizer.Add(self.eb3c2_but1,
                                 span=(1, 1),
                                 pos=(1, 3),
                                 flag=wx.EXPAND)
        self.eb3c2_but1.Bind(wx.EVT_BUTTON, self.e_c2_set_trlv)
        self.eb3c2_trlv_text = wx.StaticText(self.eb3_c2_panel,
                                             -1,
                                             'c2_trlv',
                                             style=wx.ALIGN_CENTER)
        self.eb3c2_trlv_text.SetFont(self.font1)
        self.eb3c2_gridsizer.Add(self.eb3c2_trlv_text,
                                 span=(1, 1),
                                 pos=(1, 0),
                                 flag=wx.EXPAND)
        #
        self.eb3c2_erg_l_text = wx.StaticText(self.eb3_c2_panel,
                                              -1,
                                              'energy_l',
                                              style=wx.ALIGN_CENTER)
        self.eb3c2_erg_l_text.SetFont(self.font1)
        self.eb3c2_gridsizer.Add(self.eb3c2_erg_l_text,
                                 span=(1, 1),
                                 pos=(2, 0),
                                 flag=wx.EXPAND)
        self.eb3c2_erg_l = wx.TextCtrl(self.eb3_c2_panel,
                                       -1,
                                       str(self.e_rg['c2'][0]),
                                       style=wx.TE_CENTER)
        self.eb3c2_gridsizer.Add(self.eb3c2_erg_l,
                                 span=(1, 1),
                                 pos=(2, 1),
                                 flag=wx.EXPAND)

        self.eb3c2_erg_r_text = wx.StaticText(self.eb3_c2_panel,
                                              -1,
                                              'energy_r',
                                              style=wx.ALIGN_CENTER)
        self.eb3c2_erg_r_text.SetFont(self.font1)
        self.eb3c2_gridsizer.Add(self.eb3c2_erg_r_text,
                                 span=(1, 1),
                                 pos=(2, 2),
                                 flag=wx.EXPAND)
        self.eb3c2_erg_r = wx.TextCtrl(self.eb3_c2_panel,
                                       -1,
                                       str(self.e_rg['c2'][1]),
                                       style=wx.TE_CENTER)
        self.eb3c2_gridsizer.Add(self.eb3c2_erg_r,
                                 span=(1, 1),
                                 pos=(2, 3),
                                 flag=wx.EXPAND)

        self.eb3c2_amp_l_text = wx.StaticText(self.eb3_c2_panel,
                                              -1,
                                              'amp_l',
                                              style=wx.ALIGN_CENTER)
        self.eb3c2_amp_l_text.SetFont(self.font1)
        self.eb3c2_gridsizer.Add(self.eb3c2_amp_l_text,
                                 span=(1, 1),
                                 pos=(3, 0),
                                 flag=wx.EXPAND)
        self.eb3c2_amp_l = wx.TextCtrl(self.eb3_c2_panel,
                                       -1,
                                       str(self.e_rg['c2_amp'][0]),
                                       style=wx.TE_CENTER)
        self.eb3c2_gridsizer.Add(self.eb3c2_amp_l,
                                 span=(1, 1),
                                 pos=(3, 1),
                                 flag=wx.EXPAND)

        self.eb3c2_amp_r_text = wx.StaticText(self.eb3_c2_panel,
                                              -1,
                                              'amp_r',
                                              style=wx.ALIGN_CENTER)
        self.eb3c2_amp_r_text.SetFont(self.font1)
        self.eb3c2_gridsizer.Add(self.eb3c2_amp_r_text,
                                 span=(1, 1),
                                 pos=(3, 2),
                                 flag=wx.EXPAND)
        self.eb3c2_amp_r = wx.TextCtrl(self.eb3_c2_panel,
                                       -1,
                                       str(self.e_rg['c2_amp'][1]),
                                       style=wx.TE_CENTER)
        self.eb3c2_gridsizer.Add(self.eb3c2_amp_r,
                                 span=(1, 1),
                                 pos=(3, 3),
                                 flag=wx.EXPAND)

        self.eb3c2_but2 = wx.Button(self.eb3_c2_panel, -1, 'Set')
        self.eb3c2_gridsizer.Add(self.eb3c2_but2,
                                 span=(1, 4),
                                 pos=(4, 0),
                                 flag=wx.EXPAND)
        self.eb3c2_but2.Bind(wx.EVT_BUTTON, self.e_c2_set_range)
        # self.e_panel3_c2 = wx.Panel(self.scorePanel)
        # self.p3c2_gridsizer = wx.GridBagSizer(5, 4)
        # self.buttest3 = wx.Button(self.e_panel3_c2, 0, 'test')
        # self.buttest4 = wx.Button(self.e_panel3_c2, 0, 'test0')
        # self.p3c2_gridsizer.Add(self.buttest3, span=(1, 4), pos=(0, 0), flag=wx.EXPAND)
        # self.p3c2_gridsizer.Add(self.buttest4, pos=(4, 2), flag=wx.EXPAND)
        # self.e_panel3_c2.SetSizer(self.p3c2_gridsizer)
        # self.e_panel3_c2.Fit()

        # lt_page
        self.lt_gridsizer = wx.GridBagSizer(2, 2)
        self.scorePanel_lt.SetSizer(self.lt_gridsizer)
        # self.lt_box1 = wx.ListBox(self.scorePanel_lt,size=(800, 500))
        # self.drawHistF = Figure(figsize=(8, 5), dpi=100)
        # self.drawHistCanvas = FigureCanvas(self.lt_box1, -1, self.drawHistF)
        # self.drawHistCanvas.draw()
        self.lt_box1 = wx.ListBox(self.scorePanel_lt, size=(800, 500))
        self.lt_gridsizer.Add(self.lt_box1, pos=(0, 0), flag=wx.EXPAND)
        self.lt_box2 = wx.Panel(self.scorePanel_lt)
        self.lt_gridsizer.Add(self.lt_box2, pos=(0, 1), flag=wx.EXPAND)
        self.lt_box3 = wx.Panel(self.scorePanel_lt)
        self.lt_gridsizer.Add(self.lt_box3,
                              span=(1, 2),
                              pos=(1, 0),
                              flag=wx.EXPAND)
        self.scorePanel_lt.Fit()

        self.drawHistF_lt = Figure(figsize=(8, 5), dpi=100)
        self.drawHistCanvas_lt = FigureCanvas(self.lt_box1, -1,
                                              self.drawHistF_lt)
        self.drawHistCanvas_lt.draw()

        # lt右侧区域
        # self.lt_box2 = wx.Panel(self.scorePanel, pos=(810, 0), size=(370, 500))
        # self.lt_but1 = wx.Button(self.lt_box2, 0, 'start', pos=(10, 10), size=(100, 50))
        # self.lt_but2 = wx.Button(self.lt_box2, 0, 'stop', pos=(120, 10), size=(100, 50))
        # self.lt_but3 = wx.Button(self.lt_box2, 0, 'clear', pos=(230, 10), size=(100, 50))
        # self.lt_but1.Bind(wx.EVT_BUTTON, self.start_but)
        # self.lt_but2.Bind(wx.EVT_BUTTON, self.stop_but)
        # self.lt_but3.Bind(wx.EVT_BUTTON, self.energy_clear)
        self.ltb2_gridsizer = wx.GridBagSizer(8, 3)
        self.lt_box2.SetSizer(self.ltb2_gridsizer)
        self.lt_but1 = wx.Button(self.lt_box2, -1, 'start')
        self.lt_but2 = wx.Button(self.lt_box2, -1, 'stop')
        self.lt_but3 = wx.Button(self.lt_box2, -1, 'clear')
        self.lt_but1.Bind(wx.EVT_BUTTON, self.lt_start_but)
        self.lt_but2.Bind(wx.EVT_BUTTON, self.lt_stop_but)
        self.lt_but3.Bind(wx.EVT_BUTTON, self.lt_clear)
        self.lt_cps_stext = wx.StaticText(self.lt_box2,
                                          -1,
                                          'cps',
                                          style=wx.ALIGN_CENTER)
        self.lt_cps_stext.SetFont(self.font1)
        self.lt_cps_text = wx.TextCtrl(self.lt_box2,
                                       -1,
                                       str(self.cps),
                                       style=wx.TE_CENTER)
        self.lt_counts_stext = wx.StaticText(self.lt_box2,
                                             -1,
                                             'counts',
                                             style=wx.ALIGN_CENTER)
        self.lt_counts_stext.SetFont(self.font1)
        self.lt_counts_text = wx.TextCtrl(self.lt_box2,
                                          -1,
                                          str(self.total_counts),
                                          style=wx.TE_CENTER)
        self.lt_but_save = wx.Button(self.lt_box2, -1, 'save')
        self.lt_but_save.Bind(wx.EVT_BUTTON, self.save_file)
        self.ltb2_gridsizer.Add(self.lt_but1, pos=(0, 0), flag=wx.EXPAND)
        self.ltb2_gridsizer.Add(self.lt_but2, pos=(0, 1), flag=wx.EXPAND)
        self.ltb2_gridsizer.Add(self.lt_but3, pos=(0, 2), flag=wx.EXPAND)
        self.ltb2_gridsizer.Add(self.lt_cps_stext, pos=(1, 0), flag=wx.EXPAND)
        self.ltb2_gridsizer.Add(self.lt_cps_text, pos=(1, 1), flag=wx.EXPAND)
        self.ltb2_gridsizer.Add(self.lt_counts_stext,
                                pos=(2, 0),
                                flag=wx.EXPAND)
        self.ltb2_gridsizer.Add(self.lt_counts_text,
                                pos=(2, 1),
                                flag=wx.EXPAND)
        self.ltb2_gridsizer.Add(self.lt_but_save, pos=(3, 0), flag=wx.EXPAND)
        self.lt_box2.Fit()

        # 下方区域
        self.ltb3_gridsizer = wx.GridBagSizer(1, 4)
        self.lt_box3.SetSizer(self.ltb3_gridsizer)
        self.ltb3_c1_panel = wx.Panel(self.lt_box3)
        self.ltb3_gridsizer.Add(self.ltb3_c1_panel, pos=(0, 0), flag=wx.EXPAND)
        self.ltb3_c2_panel = wx.Panel(self.lt_box3)
        self.ltb3_gridsizer.Add(self.ltb3_c2_panel, pos=(0, 1), flag=wx.EXPAND)
        # lt_c1_set
        self.ltb3c1_gridsizer = wx.GridBagSizer(7, 4)
        self.ltb3_c1_panel.SetSizer(self.ltb3c1_gridsizer)

        self.ltb3c1_title = wx.StaticText(self.ltb3_c1_panel,
                                          -1,
                                          label='start_channel',
                                          style=wx.ALIGN_CENTER)
        self.ltb3c1_title.SetFont(self.font1)
        self.ltb3c1_gridsizer.Add(self.ltb3c1_title,
                                  span=(1, 5),
                                  pos=(0, 0),
                                  flag=wx.EXPAND)

        self.ltb3c1_startdown_text = wx.StaticText(self.ltb3_c1_panel,
                                                   -1,
                                                   'down',
                                                   style=wx.ALIGN_CENTER)
        self.ltb3c1_startdown_text.SetFont(self.font1)
        self.ltb3c1_gridsizer.Add(self.ltb3c1_startdown_text,
                                  span=(1, 1),
                                  pos=(1, 0),
                                  flag=wx.EXPAND)
        self.ltb3c1_startdown = wx.TextCtrl(self.ltb3_c1_panel,
                                            -1,
                                            str(self.lt_start_l),
                                            style=wx.TE_CENTER)
        self.ltb3c1_gridsizer.Add(self.ltb3c1_startdown,
                                  span=(1, 1),
                                  pos=(1, 1),
                                  flag=wx.EXPAND)
        self.ltb3c1_startup_text = wx.StaticText(self.ltb3_c1_panel,
                                                 -1,
                                                 'up',
                                                 style=wx.ALIGN_CENTER)
        self.ltb3c1_startup_text.SetFont(self.font1)
        self.ltb3c1_gridsizer.Add(self.ltb3c1_startup_text,
                                  span=(1, 1),
                                  pos=(1, 2),
                                  flag=wx.EXPAND)
        self.ltb3c1_startup = wx.TextCtrl(self.ltb3_c1_panel,
                                          -1,
                                          str(self.lt_start_r),
                                          style=wx.TE_CENTER)
        self.ltb3c1_gridsizer.Add(self.ltb3c1_startup,
                                  span=(1, 1),
                                  pos=(1, 3),
                                  flag=wx.EXPAND)
        self.ltb3c1_startfrac_text = wx.StaticText(self.ltb3_c1_panel,
                                                   -1,
                                                   'fraction',
                                                   style=wx.ALIGN_CENTER)
        self.ltb3c1_startfrac_text.SetFont(self.font1)
        self.ltb3c1_gridsizer.Add(self.ltb3c1_startfrac_text,
                                  span=(1, 2),
                                  pos=(2, 0),
                                  flag=wx.EXPAND)
        self.ltb3c1_startfrac = wx.TextCtrl(self.ltb3_c1_panel,
                                            -1,
                                            str(self.start_fraction),
                                            style=wx.TE_CENTER)
        self.ltb3c1_gridsizer.Add(self.ltb3c1_startfrac,
                                  span=(1, 2),
                                  pos=(2, 2),
                                  flag=wx.EXPAND)

        self.ltb3c1_title = wx.StaticText(self.ltb3_c1_panel,
                                          -1,
                                          label='stop_channel',
                                          style=wx.ALIGN_CENTER)
        self.ltb3c1_title.SetFont(self.font1)
        self.ltb3c1_gridsizer.Add(self.ltb3c1_title,
                                  span=(1, 5),
                                  pos=(3, 0),
                                  flag=wx.EXPAND)

        self.ltb3c1_stopdown_text = wx.StaticText(self.ltb3_c1_panel,
                                                  -1,
                                                  'down',
                                                  style=wx.ALIGN_CENTER)
        self.ltb3c1_stopdown_text.SetFont(self.font1)
        self.ltb3c1_gridsizer.Add(self.ltb3c1_stopdown_text,
                                  span=(1, 1),
                                  pos=(4, 0),
                                  flag=wx.EXPAND)
        self.ltb3c1_stopdown = wx.TextCtrl(self.ltb3_c1_panel,
                                           -1,
                                           str(self.lt_stop_l),
                                           style=wx.TE_CENTER)
        self.ltb3c1_gridsizer.Add(self.ltb3c1_stopdown,
                                  span=(1, 1),
                                  pos=(4, 1),
                                  flag=wx.EXPAND)
        self.ltb3c1_stopup_text = wx.StaticText(self.ltb3_c1_panel,
                                                -1,
                                                'up',
                                                style=wx.ALIGN_CENTER)
        self.ltb3c1_stopup_text.SetFont(self.font1)
        self.ltb3c1_gridsizer.Add(self.ltb3c1_stopup_text,
                                  span=(1, 1),
                                  pos=(4, 2),
                                  flag=wx.EXPAND)
        self.ltb3c1_stopup = wx.TextCtrl(self.ltb3_c1_panel,
                                         -1,
                                         str(self.lt_stop_r),
                                         style=wx.TE_CENTER)
        self.ltb3c1_gridsizer.Add(self.ltb3c1_stopup,
                                  span=(1, 1),
                                  pos=(4, 3),
                                  flag=wx.EXPAND)
        self.ltb3c1_stopfrac_text = wx.StaticText(self.ltb3_c1_panel,
                                                  -1,
                                                  'fraction',
                                                  style=wx.ALIGN_CENTER)
        self.ltb3c1_stopfrac_text.SetFont(self.font1)
        self.ltb3c1_gridsizer.Add(self.ltb3c1_stopfrac_text,
                                  span=(1, 2),
                                  pos=(5, 0),
                                  flag=wx.EXPAND)
        self.ltb3c1_stopfrac = wx.TextCtrl(self.ltb3_c1_panel,
                                           -1,
                                           str(self.stop_fraction),
                                           style=wx.TE_CENTER)
        self.ltb3c1_gridsizer.Add(self.ltb3c1_stopfrac,
                                  span=(1, 2),
                                  pos=(5, 2),
                                  flag=wx.EXPAND)

        self.ltb3c1_but1 = wx.Button(self.ltb3_c1_panel,
                                     -1,
                                     'set',
                                     size=(200, 30))
        self.ltb3c1_but1.Bind(wx.EVT_BUTTON, self.lt_ch_set)
        self.ltb3c1_gridsizer.Add(self.ltb3c1_but1,
                                  span=(1, 2),
                                  pos=(6, 1),
                                  flag=wx.EXPAND)

        # lt_box3_c2
        self.ltb3c2_gridsizer = wx.GridBagSizer(7, 4)
        self.ltb3_c2_panel.SetSizer(self.ltb3c2_gridsizer)

        self.ltb3c2_title = wx.StaticText(self.ltb3_c2_panel,
                                          -1,
                                          label='lifetime_spectrum',
                                          style=wx.ALIGN_CENTER)
        self.ltb3c2_title.SetFont(self.font1)
        self.ltb3c2_gridsizer.Add(self.ltb3c2_title,
                                  span=(1, 5),
                                  pos=(0, 0),
                                  flag=wx.EXPAND)

        self.ltb3c2_sp_left_text = wx.StaticText(self.ltb3_c2_panel,
                                                 -1,
                                                 'sp_left',
                                                 style=wx.ALIGN_CENTER)
        self.ltb3c2_sp_left_text.SetFont(self.font1)
        self.ltb3c2_gridsizer.Add(self.ltb3c2_sp_left_text,
                                  span=(1, 1),
                                  pos=(1, 0),
                                  flag=wx.EXPAND)
        self.ltb3c2_sp_left = wx.TextCtrl(self.ltb3_c2_panel,
                                          -1,
                                          str(self.lt_l),
                                          style=wx.TE_CENTER)
        self.ltb3c2_gridsizer.Add(self.ltb3c2_sp_left,
                                  span=(1, 1),
                                  pos=(1, 1),
                                  flag=wx.EXPAND)
        self.ltb3c2_sp_right_text = wx.StaticText(self.ltb3_c2_panel,
                                                  -1,
                                                  'sp_right',
                                                  style=wx.ALIGN_CENTER)
        self.ltb3c2_sp_right_text.SetFont(self.font1)
        self.ltb3c2_gridsizer.Add(self.ltb3c2_sp_right_text,
                                  span=(1, 1),
                                  pos=(1, 2),
                                  flag=wx.EXPAND)
        self.ltb3c2_sp_right = wx.TextCtrl(self.ltb3_c2_panel,
                                           -1,
                                           str(self.lt_r),
                                           style=wx.TE_CENTER)
        self.ltb3c2_gridsizer.Add(self.ltb3c2_sp_right,
                                  span=(1, 1),
                                  pos=(1, 3),
                                  flag=wx.EXPAND)
        self.ltb3c2_bins_text = wx.StaticText(self.ltb3_c2_panel,
                                              -1,
                                              'bins',
                                              style=wx.ALIGN_CENTER)
        self.ltb3c2_bins_text.SetFont(self.font1)
        self.ltb3c2_gridsizer.Add(self.ltb3c2_bins_text,
                                  span=(1, 2),
                                  pos=(2, 0),
                                  flag=wx.EXPAND)
        self.ltb3c2_bins = wx.TextCtrl(self.ltb3_c2_panel,
                                       -1,
                                       str(self.lt_bins),
                                       style=wx.TE_CENTER)
        self.ltb3c2_gridsizer.Add(self.ltb3c2_bins,
                                  span=(1, 2),
                                  pos=(2, 2),
                                  flag=wx.EXPAND)
        self.ltb3c2_counts_text = wx.StaticText(self.ltb3_c2_panel,
                                                -1,
                                                'counts',
                                                style=wx.ALIGN_CENTER)
        self.ltb3c2_counts_text.SetFont(self.font1)
        self.ltb3c2_gridsizer.Add(self.ltb3c2_counts_text,
                                  span=(1, 2),
                                  pos=(3, 0),
                                  flag=wx.EXPAND)
        self.ltb3c2_counts = wx.TextCtrl(self.ltb3_c2_panel,
                                         -1,
                                         str(self.counts_set),
                                         style=wx.TE_CENTER)
        self.ltb3c2_gridsizer.Add(self.ltb3c2_counts,
                                  span=(1, 2),
                                  pos=(3, 2),
                                  flag=wx.EXPAND)

        self.ltb3c2_but1 = wx.Button(self.ltb3_c2_panel,
                                     -1,
                                     'set',
                                     size=(200, 30))
        self.ltb3c2_but1.Bind(wx.EVT_BUTTON, self.lt_sp_set)
        self.ltb3c2_gridsizer.Add(self.ltb3c2_but1,
                                  span=(1, 2),
                                  pos=(4, 1),
                                  flag=wx.EXPAND)

        # 参数
        self.m = 3.0
        self.energy_c1 = []
        self.amp_c1 = []
        self.energy_c2 = []
        self.amp_c2 = []
        self.lifetime = []
        self.wave0 = []
        self.wave1 = []
        self.lt_spe = []
        self.e_start_but = 0
        self.lt_start_but_switch = 0

    def start_but(self, event):
        if self.e_start_but == 0:
            self.dos_0.open()
            self.run_loop()
            self.e_start_but = 1

    def stop_but(self, event):
        self.dos_0.close()
        self.e_start_but = 0

    def energy_clear(self, event):
        e_c_box = wx.MessageDialog(None,
                                   u"是否真的要清除显示能谱?",
                                   u"请确认",
                                   style=wx.OK | wx.CANCEL)
        if e_c_box.ShowModal() == wx.ID_OK:
            self.energy_c1 = []
            self.amp_c1 = []
            self.energy_c2 = []
            self.amp_c2 = []
            self.drawHistF.clf()
            self.drawHistCanvas.draw()

    def lt_start_but(self, event):
        if self.e_start_but == 0:
            self.dos_0.open()
            self.run_loop_lt()
            self.e_start_but = 1

    def lt_stop_but(self, event):
        self.dos_0.close()
        self.e_start_but = 0

    def lt_clear(self, event):
        e_c_box = wx.MessageDialog(None,
                                   u"是否真的要清除显示寿命谱?",
                                   u"请确认",
                                   style=wx.OK | wx.CANCEL)
        if e_c_box.ShowModal() == wx.ID_OK:
            self.lifetime = []
            self.drawHistF_lt.clf()
            self.drawHistCanvas_lt.draw()
            self.total_counts = 0

    def e_c1_set_trlv(self, event):
        str0 = self.eb3c1_trlv.GetValue()
        self.para_0['C1_TRLV'] = float(str0)
        self.dos_0.setDSO('C1:TRLV ' + str(self.para_0['C1_TRLV']))

    def e_c1_set_range(self, event):
        str0 = float(self.eb3c1_erg_l.GetValue())
        str1 = float(self.eb3c1_erg_r.GetValue())
        str2 = float(self.eb3c1_amp_l.GetValue())
        str3 = float(self.eb3c1_amp_r.GetValue())
        if str0 >= str1 or str2 >= str3:
            e_c_box = wx.MessageBox("能谱范围左侧应小于右侧", "Error")
        else:
            self.e_rg['c1'][0] = str0
            self.e_rg['c1'][1] = str1
            self.e_rg['c1_amp'][0] = str2
            self.e_rg['c1_amp'][1] = str3

    def e_c2_set_trlv(self, event):
        str0 = self.eb3c2_trlv.GetValue()
        self.para_0['C2_TRLV'] = float(str0)
        self.dos_0.setDSO('C2:TRLV ' + str(self.para_0['C2_TRLV']))

    def e_c2_set_range(self, event):
        str0 = float(self.eb3c2_erg_l.GetValue())
        str1 = float(self.eb3c2_erg_r.GetValue())
        str2 = float(self.eb3c2_amp_l.GetValue())
        str3 = float(self.eb3c2_amp_r.GetValue())
        if str0 >= str1 or str2 >= str3:
            e_c_box = wx.MessageBox("能谱范围左侧应小于右侧", "Error")
        else:
            self.e_rg['c2'][0] = str0
            self.e_rg['c2'][1] = str1
            self.e_rg['c2_amp'][0] = str2
            self.e_rg['c2_amp'][1] = str3

    def lt_ch_set(self, event):
        str0 = float(self.ltb3c1_startdown.GetValue())
        str1 = float(self.ltb3c1_startup.GetValue())
        str2 = float(self.ltb3c1_stopdown.GetValue())
        str3 = float(self.ltb3c1_stopup.GetValue())
        str4 = float(self.ltb3c1_startfrac.GetValue())
        str5 = float(self.ltb3c1_stopfrac.GetValue())
        if str0 >= str1 or str2 >= str3 or str4 >= 1 or str4 <= 0 or str5 >= 1 or str5 <= 0:
            e_c_box = wx.MessageBox("下阈应小于上阈", "Error")
        else:
            self.lt_start_l = str0
            self.lt_start_r = str1
            self.lt_stop_l = str2
            self.lt_stop_r = str3
            self.start_fraction = str4
            self.stop_fraction = str5

    def lt_sp_set(self, event):
        str0 = float(self.ltb3c2_sp_left.GetValue())
        str1 = float(self.ltb3c2_sp_right.GetValue())
        str2 = int(self.ltb3c2_bins.GetValue())
        str3 = int(self.ltb3c2_counts.GetValue())
        if str0 >= str1 or str2 <= 0 or str3 <= 0:
            e_c_box = wx.MessageBox("下阈应小于上阈", "Error")
        else:
            self.lt_l = str0
            self.lt_r = str1
            self.lt_bins = str2
            self.counts_set = str3

    def run_loop(self):
        self.th1 = threading.Thread(target=self.loop_energy_test)
        self.th1.start()

    def run_loop_lt(self):
        self.th2 = threading.Thread(target=self.loop_lifetime_test)
        self.th2.start()

    def loop_test(self):
        while self.dos_0.isOpen():
            self.drawHistF.clf()
            self.a = self.drawHistF.add_subplot(111)
            self.t = np.arange(0.0, self.m, 0.01)
            self.s = np.sin(2 * np.pi * self.t)
            self.a.plot(self.t, self.s)
            self.a.semilogy()
            self.a.set_xlim((-1.5, 10.3))
            self.a.set_xlabel('asd')
            # drawHistCanvas = FigureCanvas(box1, -1, drawHistF)
            self.drawHistCanvas.draw()
            if self.m > 10.0:
                self.m = self.m - 7
            self.m = self.m + 0.1
            time.sleep(0.01)

    def loop_energy_test(self):
        self.c_num = 0
        while self.dos_0.isOpen():
            waveform0 = self.dos_0.get_wave()
            if operator.eq(self.wave0, waveform0['c1'][1]) == False:
                if self.para_0['SEQ'] == 'ON':
                    for i in range(0, self.para_0['SEQ_N']):
                        #c1
                        t1 = tools.Wavetools(waveform0['c1'][0][i],
                                             waveform0['c1'][1][i], 800)
                        e_1 = t1.get_energy(0.2)
                        amp_1 = t1.get_amplitude()
                        self.energy_c1.append(e_1)
                        self.amp_c1.append(amp_1)
                        #c2
                        t2 = tools.Wavetools(waveform0['c2'][0][i],
                                             waveform0['c2'][1][i], 800)
                        e_2 = t2.get_energy(0.2)
                        amp_2 = t2.get_amplitude()
                        self.energy_c2.append(e_2)
                        self.amp_c2.append(amp_2)

                        self.c_num = self.c_num + 1
                else:
                    #c1
                    t1 = tools.Wavetools(waveform0['c1'][0],
                                         waveform0['c1'][1])
                    e_1 = t1.get_energy(0.2)
                    amp_1 = t1.get_amplitude()
                    self.energy_c1.append(e_1)
                    self.amp_c1.append(amp_1)
                    #c2
                    t2 = tools.Wavetools(waveform0['c2'][0][i],
                                         waveform0['c2'][1][i])
                    e_2 = t2.get_energy(0.2)
                    amp_2 = t2.get_amplitude()
                    self.energy_c2.append(e_2)
                    self.amp_c2.append(amp_2)
                    self.c_num = self.c_num + 1
                if self.c_num % 100 == 0:
                    self.drawHistF.clf()
                    #c1
                    self.a = self.drawHistF.add_subplot(221)
                    self.h_energy_c1 = self.a.hist(self.energy_c1,
                                                   150,
                                                   range=(self.e_rg['c1'][0],
                                                          self.e_rg['c1'][1]))
                    #self.a.set_xlabel('energy')
                    self.b = self.drawHistF.add_subplot(222)
                    self.h_amp_c1 = self.b.hist(self.amp_c1,
                                                150,
                                                range=(self.e_rg['c1_amp'][0],
                                                       self.e_rg['c1_amp'][1]))
                    #self.b.set_xlabel('amp')
                    #c2
                    self.a_c2 = self.drawHistF.add_subplot(223)
                    self.h_energy_c2 = self.a_c2.hist(
                        self.energy_c2,
                        150,
                        range=(self.e_rg['c2'][0], self.e_rg['c2'][1]))
                    self.a_c2.set_xlabel('energy')
                    self.b_c2 = self.drawHistF.add_subplot(224)
                    self.h_amp_c2 = self.b_c2.hist(
                        self.amp_c2,
                        150,
                        range=(self.e_rg['c2_amp'][0], self.e_rg['c2_amp'][1]))
                    self.b_c2.set_xlabel('amp')
                    #self.a.semilogy()
                    self.drawHistCanvas.draw()
            self.wave0 = waveform0['c1'][1]

    def loop_lifetime_test(self):
        self.c_num_1 = 0
        t_01 = time.time()
        while self.dos_0.isOpen():
            c_num_2 = 0
            waveform0 = self.dos_0.get_wave()
            if operator.eq(self.wave1, waveform0['c1'][1]) == False:
                if self.para_0['SEQ'] == 'ON':
                    for i in range(0, self.para_0['SEQ_N']):
                        # c1
                        t1 = tools.Wavetools(waveform0['c1'][0][i],
                                             waveform0['c1'][1][i])
                        e_1 = t1.get_energy(0.2)
                        amp_1 = t1.get_amplitude()

                        # c2
                        t2 = tools.Wavetools(waveform0['c2'][0][i],
                                             waveform0['c2'][1][i])
                        e_2 = t2.get_energy(0.2)
                        amp_2 = t2.get_amplitude()
                        self.c_num_1 = self.c_num_1 + 1

                        if e_1 > self.lt_start_l and e_1 < self.lt_start_r \
                                and e_2 > self.lt_stop_l and e_2 < self.lt_stop_r :
                            # t_start = t1.get_time_cfd_poln(self.start_fraction, 4, 0.4)
                            # t_stop = t2.get_time_cfd_poln(self.stop_fraction, 4, 0.4)
                            t_start = t1.get_time_cfd_linear(
                                self.start_fraction)
                            t_stop = t2.get_time_cfd_linear(self.stop_fraction)
                            self.lifetime.append(t_stop - t_start)
                            #print(t_stop - t_start)
                            c_num_2 = c_num_2 + 1
                            self.total_counts = self.total_counts + 1

                else:
                    # c1
                    t1 = tools.Wavetools(waveform0['c1'][0],
                                         waveform0['c1'][1])
                    e_1 = t1.get_energy(0.2)
                    amp_1 = t1.get_amplitude()

                    # c2
                    t2 = tools.Wavetools(waveform0['c2'][0],
                                         waveform0['c2'][1])
                    e_2 = t2.get_energy(0.2)
                    amp_2 = t2.get_amplitude()

                    self.c_num_1 = self.c_num_1 + 1
                    if e_1 > self.lt_start_l and e_1 < self.lt_start_r and e_2 > self.lt_stop_l \
                            and e_2 < self.lt_stop_r:
                        # t_start = t1.get_time_cfd_poln(self.start_fraction, 4, 0.4)
                        # t_stop = t2.get_time_cfd_poln(self.stop_fraction, 4, 0.4)
                        t_start = t1.get_time_cfd_linear(self.start_fraction)
                        t_stop = t2.get_time_cfd_linear(self.stop_fraction)
                        self.lifetime.append(t_stop - t_start)
                        c_num_2 = c_num_2 + 1
                        self.total_counts = self.total_counts + 1
                if self.c_num_1 % 500 == 0:
                    self.drawHistF_lt.clf()
                    self.a_lt = self.drawHistF_lt.add_subplot(111)
                    self.h_lifetime = self.a_lt.hist(self.lifetime,
                                                     self.lt_bins,
                                                     range=(self.lt_l,
                                                            self.lt_r))
                    self.a_lt.semilogy()
                    self.drawHistCanvas_lt.draw()
                t_02 = time.time()
                self.cps = c_num_2 / (t_02 - t_01)
                self.lt_cps_text.SetValue(str(int(self.cps)))
                self.lt_counts_text.SetValue(str(self.total_counts))
                t_01 = time.time()

            self.wave1 = waveform0['c1'][1]
            if self.total_counts > self.counts_set:
                break

    def save_file(self, event):
        '''
        保存文件内容
        与菜单中的保存选项绑定
        '''
        self.dir_name = ''
        fd = wx.FileDialog(self, '把文件保存到何处', self.dir_name, 'out1.txt',
                           'TEXT file(*.txt)|*.txt', wx.FD_SAVE)
        if fd.ShowModal() == wx.ID_OK:
            self.file_name = fd.GetFilename()
            self.dir_name = fd.GetDirectory()
            try:
                with open(os.path.join(self.dir_name, self.file_name),
                          'w',
                          encoding='utf-8') as f:
                    text = plt.hist(self.lifetime,
                                    self.lt_bins,
                                    range=(self.lt_l, self.lt_r))
                    f.write('bin_width: ' +
                            str((self.lt_r - self.lt_l) / self.lt_bins) + '\n')
                    for i in range(0, len(text[0])):
                        f.write(str(int(text[0][i])) + '\n')
                    save_msg = wx.MessageDialog(self, '文件已保存', '提示')
            except FileNotFoundError:
                save_msg = wx.MessageDialog(self, '保存失败,无效的保存路径', '提示')
        else:
            save_msg = wx.MessageDialog(self, '未选择保存路径', '错误')

        save_msg.ShowModal()
        save_msg.Destroy()
Example #56
0
class SignificanceWindow(wx.Frame):
    """Window for significance analysis"""

    sbSignifText="  Keys: 'i'/'m' increase/lower no. of bins, '0' resets, 's' saves plot"

    def __init__(self,parent,id,title,dm):
        wx.Frame.__init__(self, parent, -1, title, size=signifWindowSize)
        
        if platform != "darwin":
            icon = wx.Icon("LogoIcon.ico", wx.BITMAP_TYPE_ICO)
            self.SetIcon(icon)

        self.signifNumBins=signifNumBins
        self.dm = dm
        
        self.Bind(wx.EVT_CLOSE,self.OnEnd)  
        
        self.WindowParent=parent
        sizer=wx.BoxSizer(wx.VERTICAL)

        panel = wx.Panel(self)

        # -------------- Begin of parameter selector

        sbParam = wx.StaticBox(panel, label="Parameter")
        sbParamSizer = wx.StaticBoxSizer(sbParam, wx.VERTICAL)
        sbParamSizer1 = wx.BoxSizer(wx.HORIZONTAL)
        sbParamSizer2 = wx.BoxSizer(wx.HORIZONTAL)
        
        AllBandsOrig = self.dm.GetVisibleBands()[0]
        AllBands=list(AllBandsOrig)
        AllBands.remove("Heart rate")

        bandsRB=[]

        for band in AllBands:
            if len(bandsRB)==0:
                tmp = wx.RadioButton(panel, label=band, style=wx.RB_GROUP)
                tmp.SetValue(True)
            else:
                tmp = wx.RadioButton(panel, label=band)
            bandsRB.append(tmp)
            if len(bandsRB)<=6:
                sbParamSizer1.Add(tmp, wx.EXPAND) 
            else:      
                sbParamSizer2.Add(tmp, wx.EXPAND) 
        
        sbParamSizer.Add(sbParamSizer1,flag=wx.EXPAND|wx.TOP|wx.LEFT|wx.RIGHT,border=borderBig)
        sbParamSizer.Add(sbParamSizer2,flag=wx.EXPAND|wx.TOP|wx.LEFT|wx.RIGHT,border=borderBig)
        sizer.Add(sbParamSizer,flag=wx.EXPAND|wx.TOP|wx.LEFT|wx.RIGHT,border=borderBig)

        for eachRB in bandsRB:
            self.Bind(wx.EVT_RADIOBUTTON,self.OnParam,eachRB)

        self.ActiveParam = AllBands[0]

        # -------------- End of parameter selector



        # -------------- Begin of tags selector

        sbTags = wx.StaticBox(panel, label="Episodes")
        sbTagsSizer = wx.StaticBoxSizer(sbTags, wx.HORIZONTAL)

        # tagsRB = []
        self.AllTags = self.dm.GetVisibleEpisodes()[0]
        self.ActiveTagLeft = self.AllTags[0]
        self.ActiveTagRight = None
        self.dm.SetSignifPlotParams(self.ActiveTagLeft,self.ActiveTagRight,self.ActiveParam)
        
        self.cbComboLeft=wx.ComboBox(panel,
            choices=self.AllTags,
            value=self.ActiveTagLeft,
            style=wx.CB_DROPDOWN|wx.CB_READONLY
            )
        sbTagsSizer.Add(self.cbComboLeft,flag=wx.ALL | wx.EXPAND, border=borderSmall)
        self.Bind(wx.EVT_COMBOBOX, self.OnComboLeft, id=self.cbComboLeft.GetId())
        

        sbTagsSizer.AddStretchSpacer(prop=1)

        ChoicesRight = ["Outside "+self.ActiveTagLeft]+self.AllTags
        ChoicesRight.remove(self.ActiveTagLeft)

        self.cbComboRight=wx.ComboBox(panel,
            choices=ChoicesRight, 
            value="Outside "+self.ActiveTagLeft, 
            style=wx.CB_DROPDOWN|wx.CB_READONLY
            )
        sbTagsSizer.Add(self.cbComboRight,flag=wx.ALL | wx.EXPAND, border=borderSmall)
        self.Bind(wx.EVT_COMBOBOX, self.OnComboRight, id=self.cbComboRight.GetId())


        sizer.Add(sbTagsSizer,flag=wx.EXPAND|wx.TOP|wx.LEFT|wx.RIGHT,border=borderBig)

        # -------------- End of tags selector


        # -------------- Begin of figure
        if ColoredBGPlots:
            self.fig = matplotlib.figure.Figure((5.0, 4.0),facecolor=SignifBGColor)
        else:
            self.fig = matplotlib.figure.Figure((5.0, 4.0))
            
        self.fig.subplots_adjust(left=0.05, bottom=0.18, right=0.98, top=0.92, wspace=0.20, hspace=0.15)
        self.canvas = FigureCanvas(panel, -1, self.fig)
        
        self.axes = self.fig.add_subplot(111)

        sizer.Add(self.canvas, 1, wx.LEFT | wx.TOP | wx.GROW)

        # -------------- End of figure

        # -------------- Begin of textbox and buttons

        hbox = wx.BoxSizer(wx.HORIZONTAL)   


        self.textOutput = wx.TextCtrl(panel, id, 'Information', size=(400, 75), style=wx.TE_READONLY|wx.TE_MULTILINE|wx.TE_RICH2)
        self.textOutput.SetFont(wx.Font(11, wx.FONTFAMILY_SWISS, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL));
        hbox.Add(self.textOutput, 1, wx.LEFT | wx.TOP | wx.GROW)

        endButton = wx.Button(panel, -1, "Close", size=buttonSizeSignif)
        self.Bind(wx.EVT_BUTTON, self.OnEnd, id=endButton.GetId())
        endButton.SetToolTip(wx.ToolTip("Click to close window"))
        hbox.Add(endButton, 0, border=borderBig, flag=wx.LEFT|wx.ALIGN_BOTTOM)
                
        sizer.Add(hbox, 0, flag=wx.EXPAND|wx.ALL, border=borderBig)

        # -------------- End of textbox and buttons

        panel.SetSizer(sizer)

        self.SetMinSize(signifWindowMinSize)

#        self.sb = self.CreateStatusBar()
#        self.sb.SetStatusText(self.sbSignifText)

#        self.canvas.Bind(wx.EVT_KEY_DOWN, self.OnKeyPress)

        self.Show(True)
        self.Layout()
        self.Refresh()



    def ErrorWindow(self,messageStr,captionStr="ERROR"):
        """Generic error window"""
        dial = wx.MessageDialog(self, caption=captionStr, message=messageStr, style=wx.OK | wx.ICON_ERROR)
        result = dial.ShowModal()
        dial.Destroy()
        self.canvas.SetFocus()

    def OnEnd(self,event):
        self.WindowParent.OnSignifEnded()
        self.Destroy()

    def OnParam(self,event):
        (ATL,ATR,AP) = self.dm.GetSignifPlotParams()
        self.ActiveParam = event.GetEventObject().GetLabel()
        self.dm.SetSignifPlotParams(ATL,ATR,self.ActiveParam)
        self.Refresh()

    def OnComboLeft(self,event):
        (ATL,ATR,AP) = self.dm.GetSignifPlotParams()
        self.ActiveTagLeft = self.cbComboLeft.GetValue()
        self.cbComboRight.Clear()
        ChoicesRight = ["Outside "+self.ActiveTagLeft]+self.AllTags
        ChoicesRight.remove(self.ActiveTagLeft)
        for item in ChoicesRight:
            self.cbComboRight.Append(item)
        self.cbComboRight.SetValue("Outside "+self.ActiveTagLeft)
        self.ActiveTagRight = None
        self.dm.SetSignifPlotParams(self.ActiveTagLeft,self.ActiveTagRight,AP)
        self.Refresh()

    def OnComboRight(self,event):
        (ATL,ATR,AP) = self.dm.GetSignifPlotParams()
        self.ActiveTagRight = self.cbComboRight.GetValue()
        if self.ActiveTagRight[0:7] == "Outside":
            self.ActiveTagRight=None
        self.dm.SetSignifPlotParams(ATL,self.ActiveTagRight,AP)
        self.Refresh()
        
        
    def Refresh(self):
        valuesLeft,valuesRight = self.dm.CreatePlotSignifEmbedded(self.fig)
        numValuesLeft=len(valuesLeft)
        numValuesRight=len(valuesRight)

        cad = ""
        if self.ActiveTagRight:
            cad = cad + "%s: %s (%d points) vs. %s  (%d points)\n" % (self.ActiveParam, self.ActiveTagLeft, numValuesLeft, self.ActiveTagRight, numValuesRight)
        else: 
            cad = cad + "%s: %s  -  inside (%d points) vs. outside  (%d points)\n" % (self.ActiveParam, self.ActiveTagLeft, numValuesLeft, numValuesRight)

        if (numValuesLeft>signifNumMinValues) and (numValuesRight>signifNumMinValues):
            if self.ActiveTagRight:
                cad=cad+ u"%s: %g\u00b1%g, %s: %g\u00b1%g\n" % (self.ActiveTagLeft,np.mean(valuesLeft),np.std(valuesLeft,ddof=1),self.ActiveTagRight,np.mean(valuesRight),np.std(valuesRight,ddof=1))
            else:
                cad=cad+ u"Inside: %g\u00b1%g, Outside: %g\u00b1%g\n" % (np.mean(valuesLeft),np.std(valuesLeft,ddof=1),np.mean(valuesRight),np.std(valuesRight,ddof=1))

            # from scipy.stats import normaltest   
            # z,pval = normaltest(valuesLeft)
            # if(pval < 0.055):
            #     print self.ActiveTagLeft, "- not normal distribution"
            # else:
            #     print self.ActiveTagLeft, "- Ok!"
            # z,pval = normaltest(valuesRight)
            # if(pval < 0.055):
            #     print self.ActiveTagRight, "- not normal distribution"
            # else:
            #     print self.ActiveTagRight, "- Ok!"

            from scipy.stats import ks_2samp

            pvalue = ks_2samp(valuesLeft,valuesRight)[1]

            cad=cad+ "KS test: "
            if pvalue<signifPMaxValue:
                cad=cad+ "significative differences found!!" 
                cad=cad+"  (p-value=%g < %g)" % (pvalue, signifPMaxValue)
            else:
                cad=cad+ "significative differences not found"
                cad=cad+"  (p-value=%g >= %g)" % (pvalue, signifPMaxValue)
            
#            
        else:
            cad=cad+"Not enough data: minimum no. of points is "+str(signifNumMinValues)
#            
        self.textOutput.SetValue(cad)
        self.canvas.draw()
Example #57
0
class TopPanel(BasePanel):
  def __init__(self, parent):
    BasePanel.__init__(self, parent=parent)

    self.parent = parent
    self.img_filename = None
    self.input_phil = None
    self.sparams = None
    self.coord_filename = None
    self.mtz_filename = None
    self.stol_filename = None
    self.ref_img_filename = None
    self.dblclick = False


    self.project_folder = ct.InputCtrl(self,
                                       label='Project Folder: ',
                                       label_size=(150, -1),
                                       label_style='bold',
                                       value=os.path.abspath(os.curdir),
                                       buttons=True)

    self.project_title = ct.InputCtrl(self,
                                      label='Description',
                                      label_size=(150, -1),
                                      label_style='normal')

    self.splitter = wx.SplitterWindow(self, style=wx.SP_LIVE_UPDATE |
                                                  wx.SP_3DSASH |
                                                  wx.SP_NOBORDER)
    self.file_panel = wx.Panel(self.splitter, size=(-1, 200))
    self.file_sizer = wx.BoxSizer(wx.VERTICAL)
    self.file_panel.SetSizer(self.file_sizer)
    self.preview_panel = wx.Panel(self.splitter, size=(-1, 500))
    self.preview_sizer = wx.BoxSizer(wx.VERTICAL)
    self.preview_panel.SetSizer(self.preview_sizer)
    self.splitter.SplitHorizontally(self.file_panel, self.preview_panel, 200)

    self.input = FileListCtrl(self.file_panel)
    self.file_sizer.Add(self.input, 1, flag=wx.ALL | wx.EXPAND, border=10)

    # Image preview box w/ options
    prev_box = wx.GridBagSizer(5, 15)

    # self.opt_knb_start = ct.KnobCtrl(self.preview_panel,
    #                                  label='start',
    #                                  label_size=(40, -1),
    #                                  spin_ctr_size=(50, -1),
    #                                  knob_size=(120, 120),
    #                                  values_start=0,
    #                                  values_end=360,
    #                                  values_step=1,
    #                                  value=0)
    #
    # self.opt_knb_end = ct.KnobCtrl(self.preview_panel,
    #                                label='end',
    #                                label_size=(40, -1),
    #                                spin_ctr_size=(50, -1),
    #                                knob_size=(120, 120),
    #                                values_start=0,
    #                                values_end=360,
    #                                values_step=1,
    #                                value=360)

    self.opt_spc_start = ct.SpinCtrl(self.preview_panel,
                                     label='start:',
                                     label_size=(50, -1),
                                     ctrl_size=(60, -1),
                                     ctrl_value='0',
                                     ctrl_max=360,
                                     ctrl_min=0,
                                   ctrl_step=0.1,
                                   ctrl_digits=1)

    self.opt_spc_end = ct.SpinCtrl(self.preview_panel,
                                   label='finish:',
                                   label_size=(50, -1),
                                   ctrl_size=(60, -1),
                                   ctrl_value='360',
                                   ctrl_max=360,
                                   ctrl_min=0,
                                   ctrl_step=0.1,
                                   ctrl_digits=1)

    self.opt_spc_osc = ct.SpinCtrl(self.preview_panel,
                                   label='step:',
                                   label_size=(50, -1),
                                   ctrl_size=(60, -1),
                                   ctrl_value='1.0',
                                   ctrl_max=360,
                                   ctrl_min=0,
                                   ctrl_step=0.1,
                                   ctrl_digits=2)

    self.opt_btn_prev = wx.Button(self.preview_panel,
                                  label='PREVIEW IMAGE')

    self.opt_chk_bkg = wx.CheckBox(self.preview_panel, label='Add Background')
    self.opt_chk_bkg.SetValue(True)
    self.opt_chk_noise = wx.CheckBox(self.preview_panel, label='Add Noise')
    self.opt_chk_noise.SetValue(True)
    self.opt_chk_rand = wx.CheckBox(self.preview_panel,
                                    label='Randomize Orientation')
    self.opt_chk_rand.SetValue(True)

    self.opt_spc_scale = ct.SpinCtrl(self.preview_panel,
                                     label='Crystal size (um): ',
                                     label_size=(120, -1),
                                     ctrl_size=(100, -1),
                                     ctrl_min = 1,
                                     ctrl_max = 1000,
                                     ctrl_step = 1,
                                     ctrl_value = 30)

    self.img_figure = Figure(figsize=(3, 3))
    self.img_axes = self.img_figure.add_subplot(111)

    self.img_axes.set_frame_on(False)
    self.img_axes.axis('off')
    self.img_axes.set_aspect('equal')

    self.img_figure.patch.set_visible(False)
    self.img_canvas = FigureCanvas(self.preview_panel, -1, self.img_figure)

    prev_box.Add(self.opt_spc_start, pos=(0, 0))
    prev_box.Add(self.opt_spc_end, pos=(0, 1))
    prev_box.Add(self.opt_spc_osc, pos=(1, 0))
    prev_box.Add(self.opt_chk_bkg, flag=wx.EXPAND, pos=(4, 0), span=(1, 2))
    prev_box.Add(self.opt_chk_noise, flag=wx.EXPAND, pos=(5, 0), span=(1, 2))
    prev_box.Add(self.opt_chk_rand, flag=wx.EXPAND, pos=(6, 0), span=(1, 2))
    prev_box.Add(self.opt_spc_scale, flag=wx.EXPAND, pos=(7, 0), span=(1, 2))
    prev_box.Add(self.opt_btn_prev, flag=wx.EXPAND, pos=(8,0), span=(1, 2))
    prev_box.Add(self.img_canvas, pos=(0, 2), span=(9, 1),
                 flag=wx.EXPAND)
    prev_box.AddGrowableCol(2)
    prev_box.AddGrowableRow(8)

    self.preview_sizer.Add(prev_box, 1, flag=wx.EXPAND | wx.ALL, border=10)

    self.main_sizer.Add(self.project_title, flag=wx.EXPAND | wx.ALL, border=10)
    self.main_sizer.Add(self.project_folder, flag=wx.EXPAND | wx.ALL, border=10)
    self.main_sizer.Add(self.splitter, 1, flag=wx.EXPAND)

    # Button bindings
    self.Bind(wx.EVT_BUTTON, self.onRunPreview, self.opt_btn_prev)

    # Thread bindings
    self.Bind(thr.EVT_NBDONE, self.onFinishedSimThread)

    # Image bindings
    xid = self.img_canvas.mpl_connect('button_press_event', self.on_button_press)
    xid = self.img_canvas.mpl_connect('button_release_event',
                                      self.on_button_release)

  def onRunPreview(self, e):
    e.Skip()

  def generate_phil(self):

    coord_path = None
    FCalc_path = None
    bkg_path = None
    img_path = None

    # Grab inputs (if any) from file list control
    idxs = self.input.ctr.GetItemCount()
    inputs = [self.input.ctr.GetItemData(i) for i in range(idxs)]

    for idx in range(idxs):
      item = self.input.ctr.GetItemData(idx)
      item_type_sel = item.type_selection
      item_type = item.type.type.GetString(item_type_sel)

      if item_type == 'coordinates':
        coord_path = item.path
      elif item_type == 'structure factors':
        FCalc_path = item.path
      elif item_type == 'background':
        bkg_path = item.path
      elif item_type == 'raw image file':
        img_path = item.path

    simtbx_phil_string = '\n'.join([
    'description = {}'.format(noneset(self.project_title.ctr.GetValue())),
    'output = {}'.format(noneset(self.project_folder.ctr.GetValue())),
    'reference_coordinates = {}'.format(coord_path),
    'reference_FCalc = {}'.format(FCalc_path),
    'reference_image = {}'.format(img_path),
    'radial_average_background = {}'.format(bkg_path),
    'dataset',
    '{',
    '  start_phi = {}'.format(str(self.opt_spc_start.ctr.GetValue())),
    '  finish_phi = {}'.format(str(self.opt_spc_end.ctr.GetValue())),
    '  oscillation = {}'.format(str(self.opt_spc_osc.ctr.GetValue())),
    '  }'
    ])

    self.input_phil = ip.parse(simtbx_phil_string)

  def run_simulator(self, init=None):
    pass

  def run_preview(self):
    img_filename = 'test_image.{}'.format(self.sparams.image_format)
    self.img_filename = os.path.join(self.sparams.output, img_filename)
    self.start_timer = time.time()
    self.sim = thr.nanoBraggThread(self,
                                   params=self.sparams,
                                   add_background=self.opt_chk_bkg.GetValue(),
                                   add_noise=self.opt_chk_noise.GetValue(),
                                   randomize=self.opt_chk_rand.GetValue(),
                                   pixel_scale=self.opt_spc_scale.ctr.GetValue(),
                                   preview=True)
    self.sim.start()

  def onFinishedSimThread(self, e):
    pixels = e.GetValue()
    self.display_image(pixels=pixels)
    print('TOTAL TIME = ', time.time() - self.start_timer)

  def display_image(self, pixels=None):
    if pixels is None:
      pixels = np.random.randint(low=0, high=1500000, size=(2576, 2576))
    else:
      pixels = pixels.as_numpy_array()

    clim = (pixels.min(), np.percentile(pixels, 99))

    self.img_axes.imshow(pixels,
                         #interpolation='nearest',
                         cmap='gray_r',
                         clim=clim)
    self.img_figure.subplots_adjust(left=0, bottom=0, right=1, top=1)

    self.preview_panel.Layout()
    print('DEBUG: AVERAGE PIXEL VALUE = ', np.mean(pixels))
    print('DONE!')

  def on_button_press(self, e):
    if e.button == 1 and e.dblclick:
      self.dblclick = True
    else:
      self.dblclick = False

  def on_button_release(self, e):
    if e.button == 1 and self.dblclick:
      self.view_image()

  def view_image(self):
    viewer = thr.ImageViewerThread(self,
                                   file_string=self.img_filename)
    viewer.start()
Example #58
0
  def __init__(self, parent):
    BasePanel.__init__(self, parent=parent)

    self.parent = parent
    self.img_filename = None
    self.input_phil = None
    self.sparams = None
    self.coord_filename = None
    self.mtz_filename = None
    self.stol_filename = None
    self.ref_img_filename = None
    self.dblclick = False


    self.project_folder = ct.InputCtrl(self,
                                       label='Project Folder: ',
                                       label_size=(150, -1),
                                       label_style='bold',
                                       value=os.path.abspath(os.curdir),
                                       buttons=True)

    self.project_title = ct.InputCtrl(self,
                                      label='Description',
                                      label_size=(150, -1),
                                      label_style='normal')

    self.splitter = wx.SplitterWindow(self, style=wx.SP_LIVE_UPDATE |
                                                  wx.SP_3DSASH |
                                                  wx.SP_NOBORDER)
    self.file_panel = wx.Panel(self.splitter, size=(-1, 200))
    self.file_sizer = wx.BoxSizer(wx.VERTICAL)
    self.file_panel.SetSizer(self.file_sizer)
    self.preview_panel = wx.Panel(self.splitter, size=(-1, 500))
    self.preview_sizer = wx.BoxSizer(wx.VERTICAL)
    self.preview_panel.SetSizer(self.preview_sizer)
    self.splitter.SplitHorizontally(self.file_panel, self.preview_panel, 200)

    self.input = FileListCtrl(self.file_panel)
    self.file_sizer.Add(self.input, 1, flag=wx.ALL | wx.EXPAND, border=10)

    # Image preview box w/ options
    prev_box = wx.GridBagSizer(5, 15)

    # self.opt_knb_start = ct.KnobCtrl(self.preview_panel,
    #                                  label='start',
    #                                  label_size=(40, -1),
    #                                  spin_ctr_size=(50, -1),
    #                                  knob_size=(120, 120),
    #                                  values_start=0,
    #                                  values_end=360,
    #                                  values_step=1,
    #                                  value=0)
    #
    # self.opt_knb_end = ct.KnobCtrl(self.preview_panel,
    #                                label='end',
    #                                label_size=(40, -1),
    #                                spin_ctr_size=(50, -1),
    #                                knob_size=(120, 120),
    #                                values_start=0,
    #                                values_end=360,
    #                                values_step=1,
    #                                value=360)

    self.opt_spc_start = ct.SpinCtrl(self.preview_panel,
                                     label='start:',
                                     label_size=(50, -1),
                                     ctrl_size=(60, -1),
                                     ctrl_value='0',
                                     ctrl_max=360,
                                     ctrl_min=0,
                                   ctrl_step=0.1,
                                   ctrl_digits=1)

    self.opt_spc_end = ct.SpinCtrl(self.preview_panel,
                                   label='finish:',
                                   label_size=(50, -1),
                                   ctrl_size=(60, -1),
                                   ctrl_value='360',
                                   ctrl_max=360,
                                   ctrl_min=0,
                                   ctrl_step=0.1,
                                   ctrl_digits=1)

    self.opt_spc_osc = ct.SpinCtrl(self.preview_panel,
                                   label='step:',
                                   label_size=(50, -1),
                                   ctrl_size=(60, -1),
                                   ctrl_value='1.0',
                                   ctrl_max=360,
                                   ctrl_min=0,
                                   ctrl_step=0.1,
                                   ctrl_digits=2)

    self.opt_btn_prev = wx.Button(self.preview_panel,
                                  label='PREVIEW IMAGE')

    self.opt_chk_bkg = wx.CheckBox(self.preview_panel, label='Add Background')
    self.opt_chk_bkg.SetValue(True)
    self.opt_chk_noise = wx.CheckBox(self.preview_panel, label='Add Noise')
    self.opt_chk_noise.SetValue(True)
    self.opt_chk_rand = wx.CheckBox(self.preview_panel,
                                    label='Randomize Orientation')
    self.opt_chk_rand.SetValue(True)

    self.opt_spc_scale = ct.SpinCtrl(self.preview_panel,
                                     label='Crystal size (um): ',
                                     label_size=(120, -1),
                                     ctrl_size=(100, -1),
                                     ctrl_min = 1,
                                     ctrl_max = 1000,
                                     ctrl_step = 1,
                                     ctrl_value = 30)

    self.img_figure = Figure(figsize=(3, 3))
    self.img_axes = self.img_figure.add_subplot(111)

    self.img_axes.set_frame_on(False)
    self.img_axes.axis('off')
    self.img_axes.set_aspect('equal')

    self.img_figure.patch.set_visible(False)
    self.img_canvas = FigureCanvas(self.preview_panel, -1, self.img_figure)

    prev_box.Add(self.opt_spc_start, pos=(0, 0))
    prev_box.Add(self.opt_spc_end, pos=(0, 1))
    prev_box.Add(self.opt_spc_osc, pos=(1, 0))
    prev_box.Add(self.opt_chk_bkg, flag=wx.EXPAND, pos=(4, 0), span=(1, 2))
    prev_box.Add(self.opt_chk_noise, flag=wx.EXPAND, pos=(5, 0), span=(1, 2))
    prev_box.Add(self.opt_chk_rand, flag=wx.EXPAND, pos=(6, 0), span=(1, 2))
    prev_box.Add(self.opt_spc_scale, flag=wx.EXPAND, pos=(7, 0), span=(1, 2))
    prev_box.Add(self.opt_btn_prev, flag=wx.EXPAND, pos=(8,0), span=(1, 2))
    prev_box.Add(self.img_canvas, pos=(0, 2), span=(9, 1),
                 flag=wx.EXPAND)
    prev_box.AddGrowableCol(2)
    prev_box.AddGrowableRow(8)

    self.preview_sizer.Add(prev_box, 1, flag=wx.EXPAND | wx.ALL, border=10)

    self.main_sizer.Add(self.project_title, flag=wx.EXPAND | wx.ALL, border=10)
    self.main_sizer.Add(self.project_folder, flag=wx.EXPAND | wx.ALL, border=10)
    self.main_sizer.Add(self.splitter, 1, flag=wx.EXPAND)

    # Button bindings
    self.Bind(wx.EVT_BUTTON, self.onRunPreview, self.opt_btn_prev)

    # Thread bindings
    self.Bind(thr.EVT_NBDONE, self.onFinishedSimThread)

    # Image bindings
    xid = self.img_canvas.mpl_connect('button_press_event', self.on_button_press)
    xid = self.img_canvas.mpl_connect('button_release_event',
                                      self.on_button_release)
    def __init__(self,
                 parent,
                 style=wx.DEFAULT_FRAME_STYLE | wx.NO_FULL_REPAINT_ON_RESIZE
                 | wx.FRAME_FLOAT_ON_PARENT):
        global graphFrame_enabled
        global mplImported
        global mpl_version

        self.legendFix = False

        if not graphFrame_enabled:
            pyfalog.warning(
                "Matplotlib is not enabled. Skipping initialization.")
            return

        try:
            cache_dir = mpl._get_cachedir()
        except:
            cache_dir = os.path.expanduser(os.path.join("~", ".matplotlib"))

        cache_file = os.path.join(cache_dir, 'fontList.cache')

        if os.access(cache_dir,
                     os.W_OK | os.X_OK) and os.path.isfile(cache_file):
            # remove matplotlib font cache, see #234
            os.remove(cache_file)
        if not mplImported:
            mpl.use('wxagg')

        graphFrame_enabled = True
        if int(mpl.__version__[0]) < 1:
            pyfalog.warning(
                "pyfa: Found matplotlib version {} - activating OVER9000 workarounds"
                .format(mpl.__version__))
            pyfalog.warning(
                "pyfa: Recommended minimum matplotlib version is 1.0.0")
            self.legendFix = True

        mplImported = True

        wx.Frame.__init__(self,
                          parent,
                          title="pyfa: Graph Generator",
                          style=style,
                          size=(520, 390))

        i = wx.Icon(BitmapLoader.getBitmap("graphs_small", "gui"))
        self.SetIcon(i)
        self.mainFrame = gui.mainFrame.MainFrame.getInstance()
        self.CreateStatusBar()

        self.mainSizer = wx.BoxSizer(wx.VERTICAL)
        self.SetSizer(self.mainSizer)

        sFit = Fit.getInstance()
        fit = sFit.getFit(self.mainFrame.getActiveFit())
        self.fits = [fit] if fit is not None else []
        self.fitList = FitList(self)
        self.fitList.SetMinSize((270, -1))

        self.fitList.fitList.update(self.fits)

        self.graphSelection = wx.Choice(self, wx.ID_ANY, style=0)
        self.mainSizer.Add(self.graphSelection, 0, wx.EXPAND)

        self.figure = Figure(figsize=(4, 3))

        rgbtuple = wx.SystemSettings.GetColour(wx.SYS_COLOUR_BTNFACE).Get()
        clr = [c / 255. for c in rgbtuple]
        self.figure.set_facecolor(clr)
        self.figure.set_edgecolor(clr)

        self.canvas = Canvas(self, -1, self.figure)
        self.canvas.SetBackgroundColour(wx.Colour(*rgbtuple))

        self.subplot = self.figure.add_subplot(111)
        self.subplot.grid(True)

        self.mainSizer.Add(self.canvas, 1, wx.EXPAND)
        self.mainSizer.Add(
            wx.StaticLine(self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize,
                          wx.LI_HORIZONTAL), 0, wx.EXPAND)

        self.gridPanel = wx.Panel(self)
        self.mainSizer.Add(self.gridPanel, 0, wx.EXPAND)

        dummyBox = wx.BoxSizer(wx.VERTICAL)
        self.gridPanel.SetSizer(dummyBox)

        self.gridSizer = wx.FlexGridSizer(0, 4, 0, 0)
        self.gridSizer.AddGrowableCol(1)
        dummyBox.Add(self.gridSizer, 0, wx.EXPAND)

        for view in Graph.views:
            view = view()
            self.graphSelection.Append(view.name, view)

        self.graphSelection.SetSelection(0)
        self.fields = {}
        self.select(0)
        self.sl1 = wx.StaticLine(self, wx.ID_ANY, wx.DefaultPosition,
                                 wx.DefaultSize, wx.LI_HORIZONTAL)
        self.mainSizer.Add(self.sl1, 0, wx.EXPAND)
        self.mainSizer.Add(self.fitList, 0, wx.EXPAND)

        self.fitList.fitList.Bind(wx.EVT_LEFT_DCLICK, self.removeItem)
        self.mainFrame.Bind(GE.FIT_CHANGED, self.draw)
        self.Bind(wx.EVT_CLOSE, self.close)

        self.Fit()
        self.SetMinSize(self.GetSize())
Example #60
0
class ControlFrame(wx.Frame):
    def __init__(self, parent, id, title):
        wx.Frame.__init__(self, parent, id, title, wx.DefaultPosition,
                          wx.Size(640, 500))

        self.initdone = 0
        self.create_menu()
        #-------------------------------------------
        ##### Create Sizers and Panels: #####
        #-------------------------------------------
        mainbox = wx.BoxSizer(wx.VERTICAL)
        perfbox = wx.BoxSizer(wx.HORIZONTAL)
        rightbox = wx.BoxSizer(wx.VERTICAL)
        firstbox = wx.BoxSizer(wx.HORIZONTAL)

        flagpanel = wx.Panel(self, -1, size=(500, 110))
        envpanel = wx.Panel(self, -1, size=(230, 120))
        speedpanel = wx.Panel(self, -1, size=(230, 100))
        energypanel = wx.Panel(self, -1, size=(230, 90))
        # panel colors:
        #envpanel.SetBackgroundColour('green')
        #speedpanel.SetBackgroundColour('yellow')
        #flagpanel.SetBackgroundColour('blue')
        #energypanel.SetBackgroundColour('magenta')

        #-------------------------------------------
        ##### Set Timer: #####
        #-------------------------------------------
        self.timer = wx.Timer(self)
        self.Bind(wx.EVT_TIMER, self.OnUpdate, self.timer)

        fatfont = wx.Font(10, wx.DEFAULT, wx.NORMAL, wx.BOLD)
        title = wx.StaticText(self, 1, 'Control Panel')
        title.SetFont(fatfont)
        line = wx.StaticLine(self, -1, (10, 10), (560, 1))
        #line3 = wx.StaticLine(self, -1,(10,10),(560,1))

        mainbox.Add((0, 20), 0)
        mainbox.Add(title, 0, wx.ALIGN_CENTER, 20)
        mainbox.Add(line, 0, wx.ALIGN_CENTER | wx.ALL, 10)

        #-------------------------------------------
        ##### Fill Panels: #####
        #-------------------------------------------
        #self.fill_flagpanel(flagpanel)
        #self.fill_envpanel(envpanel)
        #self.fill_speedpanel(speedpanel)
        #self.fill_energypanel(energypanel)

        ##### Add to sizers: #####
        perfbox.Add(speedpanel)

        rightbox.Add(envpanel)
        rightbox.Add(energypanel)
        firstbox.Add(flagpanel, 0, wx.ALIGN_CENTER)
        firstbox.Add(rightbox, 0, wx.ALIGN_CENTER)

        #mainbox.Add(firstbox,0,wx.ALIGN_CENTER | wx.RIGHT | wx.LEFT, 15)
        #mainbox.Add(line3,0,wx.ALIGN_CENTER | wx.TOP ,5)

        #-----------------------------------------------------------
        ##### Create Plots:
        #-----------------------------------------------------------
        self.speeddata = [0]
        self.pos_longitude = []
        self.pos_latitude = []
        self.wyp_longitude = [0.0]
        self.wyp_latitude = [0.0]
        self.logtime = [0]

        self.plot_count = 0

        #self.create_speed_plot()
        self.create_wyp_plot()

        #perfbox.Add(self.speed_panel, 1, wx.TOP | wx.LEFT | wx.GROW, 10)
        #mainbox.Add(perfbox, 0, wx.ALIGN_CENTER | wx.ALL , 20)

        mainbox.Add(self.canvas, 1, wx.CENTER)

        self.SetSizer(mainbox)

    def fill_energypanel(self, energypanel):
        energybox = wx.StaticBox(energypanel,
                                 -1,
                                 'Energy Management', (5, 5),
                                 size=(220, 60))

        wx.StaticText(energypanel, -1, 'Voltage:', pos=(20, 30))
        self.voltage = wx.TextCtrl(energypanel,
                                   46,
                                   'DEFAULT',
                                   pos=(110, 26),
                                   size=(60, -1))
        wx.StaticText(energypanel, -1, 'Volts', pos=(175, 30))

    def fill_envpanel(self, envpanel):
        envbox = wx.StaticBox(envpanel,
                              -1,
                              'Environment', (5, 5),
                              size=(220, 95))

        wx.StaticText(envpanel, -1, 'Wind Speed:', pos=(20, 30))
        self.wind_speed = wx.TextCtrl(envpanel,
                                      44,
                                      'DEFAULT',
                                      pos=(110, 26),
                                      size=(60, -1))
        wx.StaticText(envpanel, -1, 'knots', pos=(175, 30))
        wx.StaticText(envpanel, -1, 'Direction:', pos=(20, 60))
        self.wind_direction = wx.TextCtrl(envpanel,
                                          45,
                                          'DEFAULT',
                                          pos=(110, 56),
                                          size=(60, -1))
        wx.StaticText(envpanel, -1, 'degree', pos=(175, 60))

    def fill_speedpanel(self, speedpanel):
        speedbox = wx.StaticBox(speedpanel,
                                -1,
                                'Performance', (5, 5),
                                size=(220, 200))

        wx.StaticText(speedpanel, -1, 'Speed:', pos=(20, 30))
        self.speed = wx.TextCtrl(speedpanel,
                                 41,
                                 'DEFAULT',
                                 pos=(100, 26),
                                 size=(60, -1))
        wx.StaticText(speedpanel, -1, 'knots', pos=(170, 30))
        wx.StaticText(speedpanel, -1, 'desired HD:', pos=(20, 60))
        self.des_heading = wx.TextCtrl(speedpanel,
                                       42,
                                       'DEFAULT',
                                       pos=(100, 56),
                                       size=(60, -1))
        wx.StaticText(speedpanel, -1, 'degree', pos=(170, 60))
        wx.StaticText(speedpanel, -1, 'current HD:', pos=(20, 90))
        self.cur_heading = wx.TextCtrl(speedpanel,
                                       43,
                                       'DEFAULT',
                                       pos=(100, 86),
                                       size=(60, -1))
        wx.StaticText(speedpanel, -1, 'degree', pos=(170, 90))

        wx.StaticLine(speedpanel, -1, (20, 130), (180, 1))

        wx.StaticText(speedpanel, -1, 'Drift:', pos=(20, 140))
        self.drift = wx.TextCtrl(speedpanel,
                                 48,
                                 'DEFAULT',
                                 pos=(100, 136),
                                 size=(60, -1))
        wx.StaticText(speedpanel, -1, 'knots', pos=(170, 140))
        wx.StaticText(speedpanel, -1, 'Roll:', pos=(20, 170))
        self.roll = wx.TextCtrl(speedpanel,
                                49,
                                'DEFAULT',
                                pos=(100, 166),
                                size=(60, -1))
        wx.StaticText(speedpanel, -1, 'degree', pos=(170, 170))

    def fill_flagpanel(self, flagpanel):
        statbox = wx.StaticBox(flagpanel,
                               -1,
                               'Boat Controller Information', (5, 5),
                               size=(390, 160))

        self.joystick = wx.CheckBox(flagpanel, 35, 'Joystick', pos=(20, 30))
        self.sailor = wx.CheckBox(flagpanel, 36, 'Sailor', pos=(100, 30))
        self.autonomous = wx.CheckBox(flagpanel,
                                      37,
                                      'Fully Autonomous',
                                      pos=(180, 30))
        self.txtsailingmode = wx.StaticText(flagpanel,
                                            -1,
                                            'Sailing Mode:',
                                            pos=(20, 70))
        #self.txtsailingmode.SetForegroundColour('white')
        self.sailMode = wx.TextCtrl(flagpanel,
                                    40,
                                    'DEFAULT',
                                    pos=(150, 66),
                                    size=(200, -1))

        smallline = wx.StaticLine(flagpanel, -1, (20, 100), (350, 1))
        wx.StaticText(flagpanel, -1, 'RudderState Right:', pos=(20, 110))
        wx.StaticText(flagpanel, -1, 'RudderState Left:', pos=(20, 135))
        self.rudderright = wx.TextCtrl(flagpanel,
                                       60,
                                       'DFLT',
                                       pos=(150, 105),
                                       size=(80, -1))
        self.rudderleft = wx.TextCtrl(flagpanel,
                                      61,
                                      'DFLT',
                                      pos=(150, 130),
                                      size=(80, -1))
        wx.StaticText(flagpanel, -1, 'degree', pos=(260, 110))
        wx.StaticText(flagpanel, -1, 'degree', pos=(260, 135))

        #statbox.SetForegroundColour('white')
        #flagpanel.SetBackgroundColour('black')
        #self.joystick.SetForegroundColour('white')
        #self.sailor.SetForegroundColour('white')
        #self.autonomous.SetForegroundColour('white')

    def create_wyp_plot(self):
        self.wypfigure = Figure((6.0, 3.5), dpi=110, facecolor='w')

        self.wypfigure.subplots_adjust(top=0.93,
                                       bottom=0.04,
                                       left=0.06,
                                       right=0.95,
                                       wspace=None,
                                       hspace=None)
        self.wypplot = self.wypfigure.add_subplot(111)  #, aspect = 'equal')

        pylab.setp(self.wypplot.get_xticklabels(), fontsize=6)
        pylab.setp(self.wypplot.get_yticklabels(), fontsize=6)
        self.wypplot.set_title('navigated path', size=8)

        self.plot_posdata = self.wypplot.plot(
            array(self.pos_longitude),
            array(self.pos_latitude),
            linewidth=1,
            color=(1, 0, 0),
            label='AVALON',
        )[0]

        self.plot_wypdata = self.wypplot.plot(
            array(self.wyp_longitude),
            array(self.wyp_latitude),
            linewidth=1,
            color=(0, 0, 1),
            label='calculated',
        )[0]

        myprop = matplotlib.font_manager.FontProperties(size=10)
        self.wypplot.legend(loc=4, shadow=True, prop=myprop)
        self.wypplot.set_axis_bgcolor('white')
        self.canvas = FigureCanvas(self, -1, self.wypfigure)

    def create_speed_plot(self):
        self.speed_panel = wx.Panel(self)
        self.dpi = 100
        self.fig = Figure((3.8, 1.95), dpi=self.dpi, facecolor='w')
        self.fig.subplots_adjust(top=0.95, right=0.97, bottom=0.07)

        self.speedplot = self.fig.add_subplot(111)
        self.speedplot.set_axis_bgcolor('black')
        #self.speedplot.set_title('AVALON Speed History', size=10)
        self.speedplot.set_ylabel('[knots]', size=8)

        pylab.setp(self.speedplot.get_xticklabels(), fontsize=8)
        pylab.setp(self.speedplot.get_yticklabels(), fontsize=8)

        # plot the data as a line series, and save the reference
        # to the plotted line series
        #
        self.plot_data = self.speedplot.plot(
            self.speeddata,
            linewidth=1,
            color=(1, 1, 0),
        )[0]

        self.speed_canvas = FigureCanvas(self.speed_panel, -1, self.fig)

    def UpdatePosPlot(self):
        # ---------------------------------------
        # redraws the position plot:
        # ---------------------------------------
        #delta_long = max(max(self.pos_longitude),max(self.wyp_longitude)) - min(min(self.pos_longitude), min(self.wyp_longitude))
        #long_m = 0.5*(max(max(self.pos_longitude), max(self.wyp_longitude)) + min(min(self.pos_longitude), min(self.wyp_longitude)))
        #delta_lat = max(max(self.pos_latitude), max(self.wyp_latitude)) - min(min(self.pos_latitude), min(self.wyp_latitude))
        #lat_m = 0.5*(max(max(self.pos_latitude), max(self.wyp_latitude)) + min(min(self.pos_latitude), min(self.wyp_latitude)))
        delta_long = max(self.pos_longitude) - min(self.pos_longitude)
        long_m = 0.5 * (max(self.pos_longitude)) + min(self.pos_longitude)
        delta_lat = max(self.pos_latitude) - min(self.pos_latitude)
        lat_m = 0.5 * (max(self.pos_latitude)) + min(self.pos_latitude)

        delta_long_calc = 6.0 / 3.5 * delta_lat
        delta_lat_calc = 3.5 / 6.0 * delta_long

        # --- set axes boundaries ---
        if delta_lat_calc > delta_lat:
            xmax = (long_m + 0.5 * delta_long + 0.0005)
            xmin = (long_m - 0.5 * delta_long - 0.0005)
            ymax = (lat_m + 0.5 * delta_lat_calc + 0.0005)
            ymin = (lat_m - 0.5 * delta_lat_calc - 0.0005)
        elif delta_long_calc > delta_long:
            xmax = (long_m + 0.5 * delta_long_calc + 0.0005)
            xmin = (long_m - 0.5 * delta_long_calc - 0.0005)
            ymax = (lat_m + 0.5 * delta_lat + 0.0005)
            ymin = (lat_m - 0.5 * delta_lat - 0.0005)
        else:
            # --- not 1:1 ratio ---
            xmax = max(self.pos_longitude) + 0.0005
            xmin = min(self.pos_longitude) - 0.0005
            ymax = max(self.pos_latitude) + 0.0005
            ymin = min(self.pos_latitude) - 0.0005

        #print long_m

        #self.wypplot.set_xbound(lower=xmin, upper=xmax)
        #self.wypplot.set_ybound(lower=ymin, upper=ymax)
        self.wypplot.set_xbound(lower=-150, upper=150)
        self.wypplot.set_ybound(lower=-300, upper=0)

        #grid on:
        self.wypplot.grid(True, color='gray')

        self.plot_posdata.set_xdata(array(self.pos_longitude))
        self.plot_posdata.set_ydata(array(self.pos_latitude))

        #self.plot_wypdata.set_xdata(array(self.wyp_longitude))
        #self.plot_wypdata.set_ydata(array(self.wyp_latitude))

        self.canvas.draw()

    def UpdateSpeedPlot(self):
        """ Redraws the plot
		"""
        # define the range of the axes
        xmax = self.logtime[30] if len(self.logtime) > 30 else 60
        xmin = self.logtime[0]
        ymin = round(min(self.speeddata), 0) - 1
        ymax = round(max(self.speeddata), 0) + 1

        self.speedplot.set_xbound(lower=xmin, upper=xmax)
        self.speedplot.set_ybound(lower=ymin, upper=ymax)

        ## grid on:
        self.speedplot.grid(True, color='gray')

        pylab.setp(self.speedplot.get_xticklabels(), visible=True)
        self.plot_data.set_xdata(array(self.logtime))
        self.plot_data.set_ydata(array(self.speeddata))

        self.speed_canvas.draw()

    def create_menu(self):
        menubar = wx.MenuBar()
        file = wx.Menu()
        file.Append(101, '&Open', 'not working momentarely')
        file.AppendSeparator()
        quit = wx.MenuItem(file, 102, '&Quit\tCtrl+Q', 'Quit the Application')
        file.AppendItem(quit)

        menudata = wx.Menu()
        menudata.Append(301, '&Initialize\tCtrl+I', 'Initialize Store-Data')
        menudata.Append(302, '&Start\tCtrl+S', 'Start reading Data')
        menudata.Append(303, '&Stop\tCtrl+E', 'Stop reading Data')
        menudata.Append(304, '&Plot WYP\tCtrl+W', 'fill wyps to vector')

        menuplot = wx.Menu()
        menuplot.Append(401, '&Clear Plot\tCtrl+C',
                        'Clear the Navigation plot')

        menubar.Append(file, '&File')
        menubar.Append(menudata, '&Data')
        menubar.Append(menuplot, '&Plot')
        self.SetMenuBar(menubar)
        self.Bind(wx.EVT_MENU, self.OnQuit, id=102)
        self.Bind(wx.EVT_MENU, self.OnInitData, id=301)
        self.Bind(wx.EVT_MENU, self.OnStartStop, id=302)
        self.Bind(wx.EVT_MENU, self.OnStartStop, id=303)
        self.Bind(wx.EVT_MENU, self.OnWypFill, id=304)
        self.Bind(wx.EVT_MENU, self.OnClearPlot, id=401)
        self.Centre()

    def OnClearPlot(self, event):
        # clear the data-arrays:
        del self.pos_longitude[:]
        del self.pos_latitude[:]
        del self.wyp_longitude[:]
        del self.wyp_latitude[:]

        self.wyp_latitude[0]
        self.wyp_longitude[0]

        msg = wx.MessageDialog(None, 'Plot data cleared!', 'Info', wx.OK)
        msg.ShowModal()

    def OnInitData(self, event):

        #-----------------------------------------------------------
        # initialize Store connection and define variables
        #-----------------------------------------------------------

        store = ddxInterface.ddxStore()
        self.IMUData = store.variable("imu")
        #self.FLAGData = store.variable("flags")
        #self.WINDData = store.variable("cleanwind")
        #self.DHData = store.variable("desiredheading")
        self.WypData = store.variable("wypData")
        self.DESTData = store.variable("destData")
        #self.RDRData = store.variable("rudderstateright")
        #self.RDLData = store.variable("rudderstateleft")

        #flag:
        self.initdone = 1

    def OnUpdate(self, event):
        ###read DDX variables and write to GUI: ####
        self.IMUData.read()
        #self.FLAGData.read()
        #self.WINDData.read()
        #self.DHData.read()
        self.DESTData.read()
        #self.RDRData.read()
        #self.RDLData.read()

        ###sailing mode: ####
        #mode = {
        #		1: 'IDLE',
        #		2: 'DOCK',
        #		3: 'NORMAL SAILING',
        #		4: 'TACK',
        #		5: 'JIBE',
        #		6: 'UPWIND',
        #		7: 'DOWNWIND',
        #		8: 'MAX ENERGY SAVING',
        #		9: 'HEADING CHANGE',
        #		0: 'ERROR',
        #		#}[8]
        #		}[int(self.FLAGData.state)]
        #
        #self.sailMode.SetValue(mode)
        ####radio buttons: ####

        #joystick_bool = {1: False, 2: True, 0: False}[int(self.FLAGData.man_in_charge)]
        #sailor_bool = {1: True, 2: False, 0: False}[int(self.FLAGData.man_in_charge)]
        #autonomous_bool = {0: False, 1: True}[int(self.FLAGData.autonom_navigation)]
        ##print self.FLAGData.man_in_charge
        ##joystick_bool = {1: False, 2: True}[1]
        ##sailor_bool = {1: True, 2: False}[1]
        ##autonomous_bool = {0: False, 1: True}[1]
        #self.joystick.SetValue(joystick_bool)
        #self.sailor.SetValue(sailor_bool)
        #self.autonomous.SetValue(autonomous_bool)

        ##self.rudderright.SetValue(' %1.3f') % (float(self.RDRData.degrees_rudder))
        #self.rudderright.SetValue(str(float(self.RDRData.degrees_rudder)))
        #self.rudderleft.SetValue(str(float(self.RDLData.degrees_rudder)))
        #
        ##### performance information: ####
        ##self.speed.SetValue(str(6.34))
        ##self.des_heading.SetValue(str(130))
        ##self.cur_heading.SetValue(str(120))
        ##self.drift.SetValue(str(0.1))
        ##self.roll.SetValue(str(16))
        #self.speed.SetValue(str(float(self.IMUData.speed)))
        #self.des_heading.SetValue(str(float(self.DHData.heading)))
        #self.cur_heading.SetValue(str(float(self.IMUData.attitude.yaw)))
        #self.drift.SetValue(str(float(self.IMUData.velocity.y)))
        #self.roll.SetValue(str(float(self.IMUData.attitude.roll)))

        ##### environment information: ####
        #self.wind_speed.SetValue(str(float(self.WINDData.speed_long)))
        #self.wind_direction.SetValue(str(float(self.WINDData.global_direction_real_long)))

        ##### energy panel information: ####
        #self.voltage.SetValue('--')

        # ------------------------------------------------------------------------------
        # plots:
        # ------------------------------------------------------------------------------
        #sp_length = len(self.logtime)
        #self.logtime.append((self.logtime[sp_length-1])+2)
        #self.speeddata.append(float(self.IMUData.speed))
        #if sp_length > 30:
        #	self.logtime.pop(0)
        #	self.speeddata.pop(0)

        #self.UpdateSpeedPlot()

        # ---- position decoding (every 10 seconds)------
        if self.plot_count > 1:
            self.plot_count = 0

            #pos_x = float (EARTH_RAD * (math.pi/180)
            #	*(float(self.IMUData.position.latitude) - float(self.DESTData.latitude)))
            #pos_y = float (EARTH_RAD
            #	*math.cos((float(self.DESTData.latitude) * math.pi/180.0))*(math.pi/180.0)
            #	*(float(self.IMUData.position.longitude) - float(self.DESTData.longitude)))
            pos_x = float(
                EARTH_RAD * (math.pi / 180) *
                (float(47.29853) - float(self.IMUData.position.latitude)))
            pos_y = float(
                EARTH_RAD * math.cos(
                    (float(47.29853) * math.pi / 180.0)) * (math.pi / 180.0) *
                (float(8.566133) - float(self.IMUData.position.longitude)))

            self.pos_longitude.append(
                pos_y)  #(float(self.IMUData.position.longitude))
            self.pos_latitude.append(
                pos_x)  #(float(self.IMUData.position.latitude))

            print pos_x
            print pos_y
            #if len(self.pos_longitude) > 60:
            #	self.pos_longitude.pop(0)
            #	self.pos_latitude.pop(0)

            self.UpdatePosPlot()

        self.plot_count += 1
        #print self.plot_count

        ###debug:
        print 'updated control panel'

    def OnWypFill(self, event):

        self.WypData.read()

        del self.wyp_longitude[:]
        del self.wyp_latitude[:]

        for i in range(0, 18):
            self.wyp_longitude.append(float(self.WypData.Data[i].y))
            self.wyp_latitude.append(float(self.WypData.Data[i].x))

            print self.wyp_longitude
            print self.wyp_latitude
            if int(self.WypData.Data[i].wyp_type) == 1:
                # --- stop ---
                break

        self.UpdatePosPlot()
        print self.wyp_longitude
        print 'Wyp Data filled'

    def OnStartStop(self, event):
        if self.initdone == 0:
            msg = wx.MessageDialog(
                None, 'Store not initialized. Please press Ctrl-I', 'Error',
                wx.OK | wx.ICON_EXCLAMATION)
            msg.ShowModal()
            return

        if self.timer.IsRunning():
            self.timer.Stop()
            #self.startBtn.SetLabel("Restart")
            #self.fileHandle.close()
            print "timer stopped"
        else:
            print "starting timer"
            self.timer.Start(2000)
            #os.remove('position.txt')
            #self.fileHandle = open('position.txt','a')
            #self.startBtn.SetLabel("Stop")

    def OnQuit(self, event):
        self.Destroy()