⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 plot.py

📁 这是用python语言写的一个数字广播的信号处理工具包。利用它
💻 PY
📖 第 1 页 / 共 5 页
字号:
        #save for next erase        self.last_PointLabel = mDataDict    # event handlers **********************************    def OnMotion(self, event):        if self._zoomEnabled and event.LeftIsDown():            if self._hasDragged:                self._drawRubberBand(self._zoomCorner1, self._zoomCorner2) # remove old            else:                self._hasDragged= True            self._zoomCorner2[0], self._zoomCorner2[1] = self.GetXY(event)            self._drawRubberBand(self._zoomCorner1, self._zoomCorner2) # add new    def OnMouseLeftDown(self,event):        self._zoomCorner1[0], self._zoomCorner1[1]= self.GetXY(event)    def OnMouseLeftUp(self, event):        if self._zoomEnabled:            if self._hasDragged == True:                self._drawRubberBand(self._zoomCorner1, self._zoomCorner2) # remove old                self._zoomCorner2[0], self._zoomCorner2[1]= self.GetXY(event)                self._hasDragged = False  # reset flag                minX, minY= _numpy.minimum( self._zoomCorner1, self._zoomCorner2)                maxX, maxY= _numpy.maximum( self._zoomCorner1, self._zoomCorner2)                self.last_PointLabel = None        #reset pointLabel                if self.last_draw != None:                    self.Draw(self.last_draw[0], xAxis = (minX,maxX), yAxis = (minY,maxY), dc = None)            #else: # A box has not been drawn, zoom in on a point            ## this interfered with the double click, so I've disables it.            #    X,Y = self.GetXY(event)            #    self.Zoom( (X,Y), (self._zoomInFactor,self._zoomInFactor) )    def OnMouseDoubleClick(self,event):        if self._zoomEnabled:            self.Reset()            def OnMouseRightDown(self,event):        if self._zoomEnabled:            X,Y = self.GetXY(event)            self.Zoom( (X,Y), (self._zoomOutFactor, self._zoomOutFactor) )    def OnPaint(self, event):        # All that is needed here is to draw the buffer to screen        if self.last_PointLabel != None:            self._drawPointLabel(self.last_PointLabel) #erase old            self.last_PointLabel = None        dc = wx.BufferedPaintDC(self, self._Buffer)    def OnSize(self,event):        # The Buffer init is done here, to make sure the buffer is always        # the same size as the Window        Size  = self.GetClientSize()        # Make new offscreen bitmap: this bitmap will always have the        # current drawing in it, so it can be used to save the image to        # a file, or whatever.        self._Buffer = wx.EmptyBitmap(Size[0],Size[1])        self._setSize()        self.last_PointLabel = None        #reset pointLabel        if self.last_draw is None:            self.Clear()        else:            graphics, xSpec, ySpec = self.last_draw            self.Draw(graphics,xSpec,ySpec)    def OnLeave(self, event):        """Used to erase pointLabel when mouse outside window"""        if self.last_PointLabel != None:            self._drawPointLabel(self.last_PointLabel) #erase old            self.last_PointLabel = None            # Private Methods **************************************************    def _setSize(self, width=None, height=None):        """DC width and height."""        if width == None:            (self.width,self.height) = self.GetClientSize()        else:            self.width, self.height= width,height            self.plotbox_size = 0.97*_numpy.array([self.width, self.height])        xo = 0.5*(self.width-self.plotbox_size[0])        yo = self.height-0.5*(self.height-self.plotbox_size[1])        self.plotbox_origin = _numpy.array([xo, yo])        def _setPrinterScale(self, scale):        """Used to thicken lines and increase marker size for print out."""        # line thickness on printer is very thin at 600 dot/in. Markers small        self.printerScale= scale         def _printDraw(self, printDC):        """Used for printing."""        if self.last_draw != None:            graphics, xSpec, ySpec= self.last_draw            self.Draw(graphics,xSpec,ySpec,printDC)    def _drawPointLabel(self, mDataDict):        """Draws and erases pointLabels"""        width = self._Buffer.GetWidth()        height = self._Buffer.GetHeight()        tmp_Buffer = wx.EmptyBitmap(width,height)        dcs = wx.MemoryDC()        dcs.SelectObject(tmp_Buffer)        dcs.Clear()        dcs.BeginDrawing()        self._pointLabelFunc(dcs,mDataDict)  #custom user pointLabel function        dcs.EndDrawing()        dc = wx.ClientDC( self )        #this will erase if called twice        dc.Blit(0, 0, width, height, dcs, 0, 0, wx.EQUIV)  #(NOT src) XOR dst            def _drawLegend(self,dc,graphics,rhsW,topH,legendBoxWH, legendSymExt, legendTextExt):        """Draws legend symbols and text"""        # top right hand corner of graph box is ref corner        trhc= self.plotbox_origin+ (self.plotbox_size-[rhsW,topH])*[1,-1]        legendLHS= .091* legendBoxWH[0]  # border space between legend sym and graph box        lineHeight= max(legendSymExt[1], legendTextExt[1]) * 1.1 #1.1 used as space between lines        dc.SetFont(self._getFont(self._fontSizeLegend))        for i in range(len(graphics)):            o = graphics[i]            s= i*lineHeight            if isinstance(o,PolyMarker):                # draw marker with legend                pnt= (trhc[0]+legendLHS+legendSymExt[0]/2., trhc[1]+s+lineHeight/2.)                o.draw(dc, self.printerScale, coord= _numpy.array([pnt]))            elif isinstance(o,PolyLine):                # draw line with legend                pnt1= (trhc[0]+legendLHS, trhc[1]+s+lineHeight/2.)                pnt2= (trhc[0]+legendLHS+legendSymExt[0], trhc[1]+s+lineHeight/2.)                o.draw(dc, self.printerScale, coord= _numpy.array([pnt1,pnt2]))            else:                raise TypeError, "object is neither PolyMarker or PolyLine instance"            # draw legend txt            pnt= (trhc[0]+legendLHS+legendSymExt[0], trhc[1]+s+lineHeight/2.-legendTextExt[1]/2)            dc.DrawText(o.getLegend(),pnt[0],pnt[1])        dc.SetFont(self._getFont(self._fontSizeAxis)) # reset    def _titleLablesWH(self, dc, graphics):        """Draws Title and labels and returns width and height for each"""        # TextExtents for Title and Axis Labels        dc.SetFont(self._getFont(self._fontSizeTitle))        title= graphics.getTitle()        titleWH= dc.GetTextExtent(title)        dc.SetFont(self._getFont(self._fontSizeAxis))        xLabel, yLabel= graphics.getXLabel(),graphics.getYLabel()        xLabelWH= dc.GetTextExtent(xLabel)        yLabelWH= dc.GetTextExtent(yLabel)        return titleWH, xLabelWH, yLabelWH        def _legendWH(self, dc, graphics):        """Returns the size in screen units for legend box"""        if self._legendEnabled != True:            legendBoxWH= symExt= txtExt= (0,0)        else:            # find max symbol size            symExt= graphics.getSymExtent(self.printerScale)            # find max legend text extent            dc.SetFont(self._getFont(self._fontSizeLegend))            txtList= graphics.getLegendNames()            txtExt= dc.GetTextExtent(txtList[0])            for txt in graphics.getLegendNames()[1:]:                txtExt= _numpy.maximum(txtExt,dc.GetTextExtent(txt))            maxW= symExt[0]+txtExt[0]                maxH= max(symExt[1],txtExt[1])            # padding .1 for lhs of legend box and space between lines            maxW= maxW* 1.1            maxH= maxH* 1.1 * len(txtList)            dc.SetFont(self._getFont(self._fontSizeAxis))            legendBoxWH= (maxW,maxH)        return (legendBoxWH, symExt, txtExt)    def _drawRubberBand(self, corner1, corner2):        """Draws/erases rect box from corner1 to corner2"""        ptx,pty,rectWidth,rectHeight= self._point2ClientCoord(corner1, corner2)        # draw rectangle        dc = wx.ClientDC( self )        dc.BeginDrawing()                         dc.SetPen(wx.Pen(wx.BLACK))        dc.SetBrush(wx.Brush( wx.WHITE, wx.TRANSPARENT ) )        dc.SetLogicalFunction(wx.INVERT)        dc.DrawRectangle( ptx,pty, rectWidth,rectHeight)        dc.SetLogicalFunction(wx.COPY)        dc.EndDrawing()    def _getFont(self,size):        """Take font size, adjusts if printing and returns wx.Font"""        s = size*self.printerScale        of = self.GetFont()        # Linux speed up to get font from cache rather than X font server        key = (int(s), of.GetFamily (), of.GetStyle (), of.GetWeight ())        font = self._fontCache.get (key, None)        if font:            return font                 # yeah! cache hit        else:            font =  wx.Font(int(s), of.GetFamily(), of.GetStyle(), of.GetWeight())            self._fontCache[key] = font            return font    def _point2ClientCoord(self, corner1, corner2):        """Converts user point coords to client screen int coords x,y,width,height"""        c1= _numpy.array(corner1)        c2= _numpy.array(corner2)        # convert to screen coords        pt1= c1*self._pointScale+self._pointShift        pt2= c2*self._pointScale+self._pointShift        # make height and width positive        pul= _numpy.minimum(pt1,pt2) # Upper left corner        plr= _numpy.maximum(pt1,pt2) # Lower right corner        rectWidth, rectHeight= plr-pul        ptx,pty= pul        return ptx, pty, rectWidth, rectHeight         def _axisInterval(self, spec, lower, upper):        """Returns sensible axis range for given spec"""        if spec == 'none' or spec == 'min':            if lower == upper:                return lower-0.5, upper+0.5            else:                return lower, upper        elif spec == 'auto':            range = upper-lower            # if range == 0.:            if abs(range) < 1e-36:                return lower-0.5, upper+0.5            log = _numpy.log10(range)            power = _numpy.floor(log)            fraction = log-power            if fraction <= 0.05:                power = power-1            grid = 10.**power            lower = lower - lower % grid            mod = upper % grid            if mod != 0:                upper = upper - mod + grid            return lower, upper        elif type(spec) == type(()):            lower, upper = spec            if lower <= upper:                return lower, upper            else:                return upper, lower        else:            raise ValueError, str(spec) + ': illegal axis specification'    def _drawAxes(self, dc, p1, p2, scale, shift, xticks, yticks):                penWidth= self.printerScale        # increases thickness for printing only        dc.SetPen(wx.Pen(wx.NamedColour('BLACK'), penWidth))                # set length of tick marks--long ones make grid        if self._gridEnabled:            x,y,width,height= self._point2ClientCoord(p1,p2)            yTickLength= width/2.0 +1            xTickLength= height/2.0 +1        else:            yTickLength= 3 * self.printerScale  # lengthens lines for printing            xTickLength= 3 * self.printerScale                if self._xSpec is not 'none':            lower, upper = p1[0],p2[0]            text = 1            for y, d in [(p1[1], -xTickLength), (p2[1], xTickLength)]:   # miny, maxy and tick lengths                a1 = scale*_numpy.array([lower, y])+shift                a2 = scale*_numpy.array([upper, y])+shift                dc.DrawLine(a1[0],a1[1],a2[0],a2[1])  # draws upper and lower axis line                for x, label in xticks:                    pt = scale*_numpy.array([x, y])+shift                    dc.DrawLine(pt[0],pt[1],pt[0],pt[1] + d) # draws tick mark d units                    if text:                        dc.DrawText(label,pt[0],pt[1])                text = 0  # axis values not drawn on top side        if self._ySpec is not 'none':            lower, upper = p1[1],p2[1]            text = 1            h = dc.GetCharHeight()            for x, d in [(p1[0], -yTickLength), (p2[0], yTickLength)]:                a1 = scale*_numpy.array([x, lower])+shift                a2 = scale*_numpy.array([x, upper])+shift                dc.DrawLine(a1[0],a1[1],a2[0],a2[1])                for y, label in yticks:                    pt = scale*_numpy.array([x, y])+shift                    dc.DrawLine(pt[0],pt[1],pt[0]-d,pt[1])                    if text:                        dc.DrawText(label,pt[0]-dc.GetTextExtent(label)[0],                                    pt[1]-0.5*h)                text = 0    # axis values not drawn on right side    def _ticks(self, lower, upper, step=None):        ideal = (upper-lower)/7.        log = _numpy.log10(ideal)        power = _numpy.floor(log)        fraction = log-power        factor = 1.        error = fraction        for f, lf in self._multiples:            e = _numpy.fabs(fraction-lf)            if e < error:                error = e                factor = f        grid = factor * 10.**power        if power > 4 or power < -4:            format = '%+7.1e'                elif power >= 0:            digits = max(1, int(power))            format = '%' + `digits`+'.0f'        else:            digits = -int(power)            format = '%'+`digits+2`+'.'+`digits`+'f'        #force grid when step is not None        if step is not None: grid = step        ticks = []        t = -grid*_numpy.floor(-lower/grid)        while t <= upper:            if t == -0: t = 0 #remove neg zero condition            ticks.append( (t, format % (t,)) )            t = t + grid        return ticks    def _scope_ticks (self, lower, upper):        '''Always 10 divisions, no labels'''        grid = (upper - lower) / 10.0        ticks = []        t = lower        while t <= upper:

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -