Пример #1
0
class wxMatplotPanel(scrolled.ScrolledPanel):
    """
    The PlotPanel has a Figure and a Canvas.

    OnSize events simply set a flag, and the actually redrawing of the
    figure is triggered by an Idle event.
    """
    def __init__(self, renderPanel, color=None, dpi=None, **kwargs):
        from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg
        from matplotlib.figure import Figure

        # initialize Panel
        if 'id' not in list(kwargs.keys()):
            kwargs['id'] = wx.ID_ANY
        if 'style' not in list(kwargs.keys()):
            kwargs['style'] = wx.NO_FULL_REPAINT_ON_RESIZE

        scrolled.ScrolledPanel.__init__(self, renderPanel, **kwargs)
        self.renderPanel = renderPanel

        # initialize matplotlib stuff
        self.figure = Figure(None, dpi)
        #self.canvas = NoRepaintCanvas( self, -1, self.figure )

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

        self.canvas.mpl_connect('button_press_event', self.onMousePress)
        self.canvas.mpl_connect('pick_event', self.onPick)

        sizer = wx.BoxSizer()
        sizer.Add(self.canvas, 1, wx.EXPAND)
        self.SetSizer(sizer)
        # self.SetAutoLayout(1)
        # self.SetupScrolling()

        self.SetColor(color)
        self._refresh = False
        self._updateDraw = False

        self.toolBar_ = None

        self.canvasZoomWidth = 1.0

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

        self.resfreshCounter = 0
        self.needUpdateHack_ = False
        self.needDrawing = False
        self.refresh()

    def onPick(self, event):
        pass

    def onMousePress(self, event):
        pass

    def onZoomChanged(self):
        pass

    def onPanChanged(self):
        pass

    def getToolBar(self, parent=None):
        if not self.toolBar_:
            self.toolBar_ = wxAUIMatplotPanelToolbar(self, self.canvas, parent)

        return self.toolBar_

    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._refresh = True

    def _onIdle(self, evt):
        if self.IsShownOnScreen():

            if self.needDrawing:
                self.redraw()

            if self._refresh:
                self.refresh()
                self._refresh = False

            if self._updateDraw:
                swatch = Stopwatch(True)

                self.canvas.draw()
                if self.needUpdateHack_:
                    self.needUpdateHack()
                    self.needUpdateHack_ = False
                self._updateDraw = False

                if self.canvasZoomWidth == 1.0:
                    self.SetupScrolling(False, False)
                print("draw: ", swatch.duration())

    def updateDrawOnIdle(self):
        self._updateDraw = True

    def resizeOnIdle(self):
        self._refresh = True

    def refresh(self):
        swatch = Stopwatch(True)
        #pixels = tuple( self.GetParent().GetClientSize() )
        self.resfreshCounter += 1

        pixels = tuple([
            int(self.GetSize()[0] * self.canvasZoomWidth),
            int(self.GetSize()[1] * 1.0)
        ])
        #    print self, self.resfreshCounter, pixels

        if self.canvas.GetMinSize(  )[0] != pixels[0] \
                or self.canvas.GetMinSize()[1] != pixels[1]:
            # print "resize canvas"
            # print "parent-size", self.renderPanel.GetSize()
            # print "self-size", self.GetSize()
            # print "tupel-size", pixels
            # to avoid _onSize loop under linux
            # if self.GetSize() != self.parent.GetClientSize():
            # if self.GetSize() != pixels:
            #self.SetSize( pixels )

            #self.canvas.SetSize( pixels )
            self.canvas.SetMinSize(pixels)

            self.figure.set_size_inches(
                float(pixels[0]) / self.figure.get_dpi(),
                float(pixels[1]) / self.figure.get_dpi())

            adjust = True
            if hasattr(self, 'cbar'):
                if self.cbar.active:
                    adjust = False

            if pixels[0] > 50 and adjust:
                self.figure.subplotpars.update(left=50.0 / pixels[0],
                                               right=(pixels[0] - 20.0) /
                                               pixels[0])

                for a in self.figure.axes:
                    if hasattr(a, "update_params"):
                        a.update_params()
                        #a.set_position( a.figbox, which = 'original' )
                        a.set_position(a.figbox, which='both')

                #self.figure.subplots_adjust( left = 50.0 / pixels[ 0 ] )
                #self.figure.subplots_adjust( right = ( pixels[ 0 ] - 20.0 ) / pixels[ 0 ] )

        # self.canvas.draw()
        self.updateDrawOnIdle()
        self.needUpdateHack_ = True
        # print "refresh: ",  swatch.duration()

    def draw(self):
        pass  # abstract, to be overridden by child classes

    def needUpdateHack(self):
        pass