class Plot(wx.Frame): def __init__(self, parent, id=-1, dpi=None, **kwargs): # begin wxGlade: MyFrame.__init__ kwargs["style"] = wx.DEFAULT_FRAME_STYLE kwargs["size"] = (600, 600) wx.Frame.__init__(self, parent, id=id, **kwargs) # create figure self.figure = mpl.figure.Figure(dpi=dpi, figsize=(2, 2)) self.canvas = Canvas(self, -1, self.figure) #self.toolbar = Toolbar(self.canvas) #self.toolbar.Realize() self.add_toolbar() #self.axes = self.figure.gca() self.PNL_AXES = wx.Panel(parent=self) # additional controls xAxisDataLabel = wx.StaticText(parent=self.PNL_AXES, label='X data:') yAxisDataLabel = wx.StaticText(parent=self.PNL_AXES, label='Y data:') self.xAxisData = wx.Choice(self.PNL_AXES) self.yAxisData = wx.Choice(self.PNL_AXES) self.xAxisScale = wx.Choice(self.PNL_AXES) self.xAxisScale.AppendItems(["linear scale", "log10 scale"]) self.xAxisScale.Select(0) self.yAxisScale = wx.Choice(self.PNL_AXES) self.yAxisScale.AppendItems(["linear scale", "log10 scale"]) self.yAxisScale.Select(0) axesPanelSizer = wx.FlexGridSizer(rows=0, cols=3, vgap=0, hgap=0) axesPanelSizer.Add(xAxisDataLabel, 0, wx.LEFT) axesPanelSizer.Add(self.xAxisData, 0, wx.LEFT) axesPanelSizer.Add(self.xAxisScale, 0, wx.LEFT) axesPanelSizer.Add(yAxisDataLabel, 0, wx.LEFT) axesPanelSizer.Add(self.yAxisData, 0, wx.LEFT) axesPanelSizer.Add(self.yAxisScale, 0, wx.LEFT) self.PNL_AXES.SetSizer(axesPanelSizer) self.PNL_AXES.SetAutoLayout(True) axesPanelSizer.Fit(self.PNL_AXES) axesPanelSizer.SetSizeHints(self.PNL_AXES) sizer = wx.BoxSizer(wx.VERTICAL) sizer.Add(self.canvas, 1, wx.EXPAND) sizer.Add(self.toolbar, 0, wx.LEFT | wx.EXPAND) sizer.Add(self.PNL_AXES, 0, wx.LEFT | wx.EXPAND) self.SetSizer(sizer) self.Layout() #self.__set_properties() # couple the EVENTS # self.Bind(wx.EVT_CHECKBOX, self.stop, self.check_run) self.Bind(event=wx.EVT_CLOSE, handler=self.OnClose) self.Bind(event=wx.EVT_CHOICE, handler=self.OnSetXlabel, source=self.xAxisData) self.Bind(event=wx.EVT_CHOICE, handler=self.OnSetYlabel, source=self.yAxisData) self.Bind(event=wx.EVT_CHOICE, handler=self.OnSetXScale, source=self.xAxisScale) self.Bind(event=wx.EVT_CHOICE, handler=self.OnSetYScale, source=self.yAxisScale) self.acquizitionRunning = True # create queue instance for the plot handling: self.plottingThread = Queue.Queue(1) # create redrawing deamon who will eat the queue self.backgndDraw = threading.Thread(target=self._redrawPlot) self.backgndDraw.setDaemon(True) self.backgndDraw.start() self.getPoints = threading.Thread(target=self._checkData) self.getPoints.setDaemon(True) return def add_toolbar(self): self.toolbar = Toolbar(self.canvas) self.toolbar.Realize() if wx.Platform == '__WXMAC__': # Mac platform (OSX 10.3, MacPython) does not seem to cope with # having a toolbar in a sizer. This work-around gets the buttons # back, but at the expense of having the toolbar at the top self.SetToolBar(self.toolbar) else: # On Windows platform, default window size is incorrect, so set # toolbar width to figure width. tw, th = self.toolbar.GetSizeTuple() fw, fh = self.canvas.GetSizeTuple() # By adding toolbar in sizer, we are able to put it at the bottom # of the frame - so appearance is closer to GTK version. # As noted above, doesn't work for Mac. self.toolbar.SetSize(wx.Size(fw, th)) #self.sizer.Add(self.toolbar, 0, wx.LEFT | wx.EXPAND) # update the axes menu on the toolbar self.toolbar.update() def set_my_title(self, title): # begin wxGlade: MyFrame.__set_properties self.SetTitle(title) axes = self.figure.gca() axes.set_title(title, visible=True) # end wxGlade def bind_data(self, datastore): self.datagram = datastore.get_datagram() self.graphTitle = datastore.dataFileName[-50:] self.set_my_title(self.graphTitle) self.lastDataRow = 0 self.xAxisData.Clear() self.xAxisData.AppendItems(self.datagram.extract_header()) self.xAxisData.Select(0) self.xIndex = self.xAxisData.GetStringSelection() self.yAxisData.Clear() self.yAxisData.AppendItems(self.datagram.extract_header()) self.yAxisData.Select(0) self.yIndex = self.yAxisData.GetStringSelection() #self.timer.start() # update the axis label axes = self.figure.gca() axes.set_ylabel(self.yIndex, visible=True) axes.set_xlabel(self.xIndex, visible=True) def start_acquizition(self): self.acquizitionRunning = True self.getPoints.start() def _checkData(self): """ periodically check for new data acquired """ while self.acquizitionRunning: currentRow = self.datagram.get_current_data_row() if currentRow > self.lastDataRow: xFrom = 0 xTo = currentRow try: self.plottingThread.put(item=(xFrom, xTo), block=False, timeout=0) except: pass time.sleep(0.1) def reloadData(self, xFrom=0, xTo=None): # which axes to plot in? axes = self.figure.gca() axes.clear() # get data: index = self.datagram.extract_data(key=self.xIndex, from_to=(xFrom, xTo)) # check the scales: xScale = self.xAxisScale.GetStringSelection() if xScale == "log10 scale": index = log10(abs(index)) axes.set_xlabel(('(log10(abs( %s ))' % self.xIndex), visible=True) if xScale == "linear scale": axes.set_xlabel(self.xIndex, visible=True) values = self.datagram.extract_data(key=self.yIndex, from_to=(xFrom, xTo)) # check the scales: yScale = self.yAxisScale.GetStringSelection() if yScale == "log10 scale": values = log10(abs(values)) axes.set_ylabel(('(log10(abs( %s ))' % self.yIndex), visible=True) if yScale == "linear scale": axes.set_ylabel(self.yIndex, visible=True) # plot and show the graph axes.set_title(self.graphTitle, visible=True) axes.scatter( index, values, s=10, c='r', marker='+', ) axes.autoscale_view() self.canvas.draw() def _redrawPlot(self): while self.acquizitionRunning: (xFrom, xTo) = self.plottingThread.get(block=True) # obtain data to plot self.reloadData(xFrom, xTo) #self.timer.start() time.sleep(0.1) def OnClose(self, event): self.Show(False) return def OnPaint(self, event): self.canvas.draw() return def OnSetXlabel(self, event): self.xIndex = event.GetString() # update the axis label #axes = self.figure.gca() #axes.set_xlabel(self.xIndex,visible=True) if not self.acquizitionRunning: self.reloadData() return def OnSetYlabel(self, event): self.yIndex = event.GetString() # update the axis label #axes = self.figure.gca() #axes.set_ylabel(self.yIndex,visible=True) if not self.acquizitionRunning: self.reloadData() return def OnSetXScale(self, event): scale = event.GetString() # update the axis label #axes = self.figure.gca() #axes.set_xlabel(self.xIndex,visible=True) if not self.acquizitionRunning: self.reloadData() return def OnSetYScale(self, event): scale = event.GetString() # update the axis label #axes = self.figure.gca() #axes.set_ylabel(self.yIndex,visible=True) if not self.acquizitionRunning: self.reloadData() return