当图中包含多个子图时,matplotlib.widgets.TextBox交互很慢

2024-04-26 00:27:59 发布

您现在位置:Python中文网/ 问答频道 /正文

下面是演示该问题的python代码。
例如,如果有两行两列的图像,在文本框中键入/擦除的速度相当快。但是,如果有5行5列,则在文本框中键入/擦除的速度相当慢。如果绘制了XTick和Ytick,交互速度会更慢。因此,似乎每次击键后都会重新绘制整个图形。
是否有解决方案(除了将文本框放在单独的图形上)?
(我的开发平台是MacOS Mojave,Python 3.7.5。)

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.gridspec as gridspec
from matplotlib.widgets import TextBox

class Textbox_Demo(object):
    def __init__(self):
        self.fig = plt.figure(figsize=(8,8))
        self.string = 'label'

        self.rows = 5   # reducing rows speeds up textbox interaction
        self.cols = 5   # reducing cols speeds up textbox interaction
        self.plot_count = self.rows * self.cols
        self.gs = gridspec.GridSpec(self.rows, self.cols,
            left=0.05, right=1-0.02, top=1-.02,  bottom=0.10, wspace=0.3, hspace=0.4)
        for k in range(self.plot_count):
            ax = self.fig.add_subplot(self.gs[k])
            #ax.set_xticks([])  # showing axes slows textbox interaction
            #ax.set_yticks([])  # showing axes slows textbox interaction
            data = np.atleast_2d(np.sin(np.linspace(1,255,255) * 50))
            ax.imshow(data, aspect="auto", cmap='ocean')

        # this is the user-input textbox
        tb_axis = plt.axes([0.125, 0.02, 0.8, 0.05])
        self.tb = TextBox(tb_axis, 'Enter label:', initial=self.string, label_pad=0.01)
        self.tb.on_submit(self.on_submit)

        plt.show()

    def on_submit(self, text):
        pass

if __name__ == "__main__":
    Textbox_Demo()

Tags: importselfmatplotlibasnppltaxtb
1条回答
网友
1楼 · 发布于 2024-04-26 00:27:59

Matplotlib的TextBox天生就很慢,因为它使用Matplotlib本身提供的绘图工具,因此在更改时会重新绘制整个图形

我建议改为使用GUI工具包的文本框。例如,对于PyQt,这可能如下所示:

enter image description here

import numpy as np
import sys
from matplotlib.backends.backend_qt5agg import (
        FigureCanvas, NavigationToolbar2QT as NavigationToolbar)
from matplotlib.backends.qt_compat import QtCore, QtWidgets
import matplotlib.gridspec as gridspec
from matplotlib.figure import Figure


class Textbox_Demo(QtWidgets.QMainWindow):
    def __init__(self):
        super().__init__()
        self._main = QtWidgets.QWidget()
        self.setCentralWidget(self._main)
        layout = QtWidgets.QVBoxLayout(self._main)
        layout.setContentsMargins(0,0,0,0)
        layout.setSpacing(0)

        self.fig = Figure(figsize=(8,8))
        self.canvas = FigureCanvas(self.fig)
        layout.addWidget(self.canvas)
        self.addToolBar(NavigationToolbar(self.canvas, self))

        self._textwidget = QtWidgets.QWidget()
        textlayout = QtWidgets.QHBoxLayout(self._textwidget)
        self.textbox = QtWidgets.QLineEdit(self)
        self.textbox.editingFinished.connect(self.on_submit)
        # or, if wanting to have changed apply directly:
        # self.textbox.textEdited.connect(self.on_submit)
        textlayout.addWidget(QtWidgets.QLabel("Enter Text: "))
        textlayout.addWidget(self.textbox)
        layout.addWidget(self._textwidget)

        self.fill_figure()

    def fill_figure(self):
        self.string = 'label'

        self.rows = 5   # reducing rows speeds up textbox interaction
        self.cols = 5   # reducing cols speeds up textbox interaction
        self.plot_count = self.rows * self.cols
        self.gs = gridspec.GridSpec(self.rows, self.cols,
            left=0.05, right=1-0.02, top=1-.02,  bottom=0.10, wspace=0.3, hspace=0.4)
        for k in range(self.plot_count):
            ax = self.fig.add_subplot(self.gs[k])
            #ax.set_xticks([])  # showing axes slows textbox interaction
            #ax.set_yticks([])  # showing axes slows textbox interaction
            data = np.atleast_2d(np.sin(np.linspace(1,255,255) * 50))
            ax.imshow(data, aspect="auto", cmap='ocean')

    def on_submit(self):
        text = self.textbox.text()
        print(text)
        pass


if __name__ == "__main__":
    qapp = QtWidgets.QApplication(sys.argv)
    app = Textbox_Demo()
    app.show()
    qapp.exec_()

相关问题 更多 >