Replot figure only at the end of a panel resize event

孤者浪人 提交于 2020-01-30 06:30:07

问题


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.

To sum up, here is the context:

Matplotlib performance is fine for our plotting needs, however, resizing our wxpython main frame is resizing wx panels that contains matplotlib canvas.

(At each step or the resizing, and not only at the end)

Resizing panels if fast, but matplotlib is also redrawing canvas and figures at each steps of the resizing, creating visual freezes and some lag.

To sum up, the problem:

I'm wondering if there is a way to disable (temporary) matplotlib events/auto-redrawing stuff, during our WX Frame resize event, then apply a redraw at the end of it.

Any ideas ?


回答1:


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.



来源:https://stackoverflow.com/questions/42555877/replot-figure-only-at-the-end-of-a-panel-resize-event

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!