コード例 #1
0
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