当图形包含多个轴时,如何提高matplotlib中的滚动速度?

时间:2016-01-25 22:19:05

标签: python matplotlib

我有一个带有许多轴的matplotlib图形,滚动/缩放变得非常慢。反正有加速吗?

例如,尝试滚动使用此代码生成的其中一个轴:

import matplotlib.pyplot as plt
fig,plts = plt.subplots(10,10)
plt.show()

(我在Mac上,使用macosx后端.QT4Agg后端似乎同样迟钝。)

1 个答案:

答案 0 :(得分:1)

我认为减速来自于matplotlib重绘整个图形,而不仅仅是你想要缩放的子图。我发现你可以通过创建多个数字并将它们嵌入到PyQt小部件中来加快速度。

这是使用'figure_enter_event'和一些丑陋的hackery的快速概念证明,允许在所有数字中使用单个导航工具栏。请注意,我只是尝试使平移和缩放功能正常工作。通过窥探NavigationToolbar2backend_bases.py的来源,我确信您可以根据自己的需要调整它。

import sys
from PyQt5 import QtCore, QtWidgets
from PyQt5.QtCore import pyqtSlot

import matplotlib
matplotlib.use('Qt5Agg')
matplotlib.rcParams['backend.qt5'] = 'PyQt5'
matplotlib.rcParams.update({'figure.autolayout': True})
from matplotlib.figure import Figure
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.backends.backend_qt5agg import NavigationToolbar2QT as NavigationToolbar

import numpy as np

class MainWindow(QtWidgets.QMainWindow):
    def __init__(self, **kwargs):
        super(MainWindow, self).__init__(**kwargs)

        # Construct the plots
        playout = QtWidgets.QGridLayout()
        playout.setContentsMargins(0, 0, 0, 0)
        for row in range(0, 10):
            for col in range(0, 10):
                fig = Figure()
                ax = fig.add_subplot(111)
                canvas = FigureCanvas(fig)
                canvas.mpl_connect('figure_enter_event', self.enterFigure)
                playout.addWidget(canvas, row, col, 1, 1)

                t = np.arange(-2*np.pi, 2*np.pi, step=0.01)
                ax.plot(t, np.sin(row*t) + np.cos(col*t))

        # Assign toolbar to first plot
        self.navbar = NavigationToolbar(playout.itemAtPosition(0, 0).widget(), self)

        cwidget = QtWidgets.QWidget()
        layout = QtWidgets.QVBoxLayout(cwidget)
        layout.setContentsMargins(0, 0, 0, 0)
        layout.addWidget(self.navbar)
        layout.addLayout(playout)
        self.setCentralWidget(cwidget)

    def enterFigure(self, event):
        self.navbar.canvas = event.canvas
        event.canvas.toolbar = self.navbar
        self.navbar._idDrag = event.canvas.mpl_connect('motion_notify_event', self.navbar.mouse_move)

        # Toggle control off and then on again for the current canvas
        if self.navbar._active:
            if self.navbar._active == 'PAN':
                self.navbar.pan()
                self.navbar.pan()
            elif self.navbar._active == 'ZOOM':
                self.navbar.zoom()
                self.navbar.zoom()


app = QtWidgets.QApplication(sys.argv)
win = MainWindow()
win.show()
app.exec_()