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