Replot figure only at the end of a panel resize event

前端 未结 1 454
眼角桃花
眼角桃花 2021-01-21 14:24

I\'m currently trying to improve plotting part of a software.

We are using WXPython and Matplotlib in order to show user many plots with various controls over them.

1条回答
  •  囚心锁ツ
    2021-01-21 14:54

    This is only half of an answer, because (1) I use PyQt here instead of WX, and (2) it only shows how to prevent the resizing from happening, such that it can later be done manually.

    The idea is to subclass the FigureCanvas and take over the resizeEvent method. In this method only store the resize event, but don't let it happen.
    Later manually trigger the event.

    import sys
    from PyQt4 import QtGui, QtCore
    from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas
    from matplotlib.figure import Figure
    import numpy as np
    
    class MyFigureCanvas(FigureCanvas):
        """ Subclass canvas to catch the resize event """
        def __init__(self, figure):
            self.lastEvent = False # store the last resize event's size here
            FigureCanvas.__init__(self, figure)
    
        def resizeEvent(self, event):
            if not self.lastEvent:
                # at the start of the app, allow resizing to happen.
                super(MyFigureCanvas, self).resizeEvent(event)
            # store the event size for later use
            self.lastEvent = (event.size().width(),event.size().height())
            print "try to resize, I don't let you."
    
        def do_resize_now(self):
            # recall last resize event's size
            newsize = QtCore.QSize(self.lastEvent[0],self.lastEvent[1] )
            # create new event from the stored size
            event = QtGui.QResizeEvent(newsize, QtCore.QSize(1, 1))
            print "Now I let you resize."
            # and propagate the event to let the canvas resize.
            super(MyFigureCanvas, self).resizeEvent(event)
    
    
    class ApplicationWindow(QtGui.QMainWindow):
        def __init__(self):
            QtGui.QMainWindow.__init__(self)
            self.main_widget = QtGui.QWidget(self)
            l = QtGui.QVBoxLayout(self.main_widget)
            self.fig = Figure()
            # use subclassed FigureCanvas
            self.canvas = MyFigureCanvas(self.fig)
            self.button = QtGui.QPushButton("Manually Resize")        
            l.addWidget(self.button)
            l.addWidget(self.canvas)
            self.setCentralWidget(self.main_widget)
            self.button.clicked.connect(self.action)     
            self.plot()
    
        def action(self):
            # when button is clicked, resize the canvas.
            self.canvas.do_resize_now()
    
        def plot(self):
            # just some random plots
            self.axes = []
            for i in range(4):
                ax = self.fig.add_subplot(2,2,i+1)
                a = np.random.rand(100,100)
                ax.imshow(a)
                self.axes.append(ax)
            self.fig.tight_layout()
    
    
    qApp = QtGui.QApplication(sys.argv)
    aw = ApplicationWindow()
    aw.show()
    sys.exit(qApp.exec_())
    

    It could be that doing this in WX is not too different.

    0 讨论(0)
提交回复
热议问题