[在函数内部时调用FuncAnimation()

问题描述 投票:1回答:1

我试图在调用特定函数时执行FuncAnimation()。但是,我的绘图没有任何结果。

当FuncAnimation不在函数内部(或__init __()内时,则可以正常工作。

我尝试了所有已发布的与该问题相关的解决方案,但它们在我的代码中不起作用。

我的简化代码是:

import sys
import os
from datetime import datetime
import matplotlib
from PyQt5 import QtCore, QtWidgets
from PyQt5.QtWidgets import QApplication, QMainWindow, QVBoxLayout, QSizePolicy, QWidget
import numpy as np
import random
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.figure import Figure
from matplotlib.animation import FuncAnimation

class MyMplCanvas(FigureCanvas):
    def __init__(self, parent=None, width=5, height=4, dpi=100):
        fig = Figure(figsize=(width, height), dpi=dpi)

        self.ax = fig.add_subplot(1,1,1)

        FigureCanvas.__init__(self, fig)
        self.setParent(parent)
        FigureCanvas.setSizePolicy(self,
                                   QtWidgets.QSizePolicy.Expanding,
                                   QtWidgets.QSizePolicy.Expanding)
        FigureCanvas.updateGeometry(self)

class ApplicationWindow(QtWidgets.QMainWindow):
    def __init__(self):
        QtWidgets.QMainWindow.__init__(self)
        self.main_widget = QtWidgets.QWidget(self)
        self.canvas =  MyMplCanvas( self.main_widget,width=6, height=6, dpi=100) 

        self.xdata = []
        self.ydata = []

        vbox = QtWidgets.QVBoxLayout(self.main_widget)

        self.start_button = QtWidgets.QPushButton(text="START")
        self.outer_ani = self.start_button.clicked.connect(self.start_func_animation)

        vbox.addWidget(self.canvas)
        vbox.addWidget(self.start_button)
        self.setLayout(vbox)
        self.main_widget.setFocus()
        self.setCentralWidget(self.main_widget)

    def start_func_animation(self):
        self.line, = self.canvas.ax.plot_date(self.xdata, self.ydata, linestyle='-', linewidth=0.6, markersize=2.5)
        self.ani = FuncAnimation(self.canvas.figure, self.update_line, interval=1000)

        return self.ani

    def update_line(self, i):
        self.xdata.append(datetime.now())
        self.ydata.append(1+np.random.randint(-3,3))

        self.line.set_data(self.xdata, self.ydata)
        self.canvas.figure.gca().relim()
        self.canvas.figure.gca().autoscale_view()
        self.canvas.ax.tick_params(axis='x', rotation=50)

        return self.line,


if __name__ == "__main__":
    App = QApplication(sys.argv)
    aw = ApplicationWindow()
    aw.show()
    App.exit()
    sys.exit(App.exec_())
python function matplotlib animation pyqt
1个回答
0
投票

解决方案是为其更新绘画,有2个选项:使用self.canvas.draw()或在blit=True中设置FuncAnimation

除上述内容外,您还有另一个错误是假定信号和插槽之间的连接返回调用函数的结果,并且该结果为false,则连接返回一个变量,该变量指示连接是否成功。另一个错误是您不必要在QMainWindow中设置布局,这是不可能的,因为QMainWindow已经具有默认布局。最后,使用quit()没有任何意义。

from datetime import datetime
import random
import os
import sys

from PyQt5 import QtCore, QtWidgets

import numpy as np

from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.figure import Figure
from matplotlib.animation import FuncAnimation


class MyMplCanvas(FigureCanvas):
    def __init__(self, parent=None, width=5, height=4, dpi=100):
        fig = Figure(figsize=(width, height), dpi=dpi)

        self.ax = fig.add_subplot(1, 1, 1)

        FigureCanvas.__init__(self, fig)
        self.setParent(parent)
        FigureCanvas.setSizePolicy(
            self, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding
        )
        FigureCanvas.updateGeometry(self)


class ApplicationWindow(QtWidgets.QMainWindow):
    def __init__(self):
        QtWidgets.QMainWindow.__init__(self)
        self.main_widget = QtWidgets.QWidget(self)
        self.canvas = MyMplCanvas(self.main_widget, width=6, height=6, dpi=100)

        self.xdata = []
        self.ydata = []

        vbox = QtWidgets.QVBoxLayout(self.main_widget)

        self.start_button = QtWidgets.QPushButton(text="START")
        # self.outer_ani = self.start_button.clicked.connect(self.start_func_animation)
        self.start_button.clicked.connect(self.start_func_animation)

        vbox.addWidget(self.canvas)
        vbox.addWidget(self.start_button)
        # self.setLayout(vbox)
        self.main_widget.setFocus()
        self.setCentralWidget(self.main_widget)

    def start_func_animation(self):
        (self.line,) = self.canvas.ax.plot_date(
            self.xdata, self.ydata, linestyle="-", linewidth=0.6, markersize=2.5
        )
        self.canvas.draw()
        self.ani = FuncAnimation(self.canvas.figure, self.update_line, interval=1000)
        # or
        # self.ani = FuncAnimation(self.canvas.figure, self.update_line, interval=1000, blit=True)
        return self.ani

    def update_line(self, i):
        self.xdata.append(datetime.now())
        self.ydata.append(1 + np.random.randint(-3, 3))

        self.line.set_data(self.xdata, self.ydata)
        self.canvas.figure.gca().relim()
        self.canvas.figure.gca().autoscale_view()
        self.canvas.ax.tick_params(axis="x", rotation=50)

        return (self.line,)


if __name__ == "__main__":
    App = QtWidgets.QApplication(sys.argv)
    aw = ApplicationWindow()
    aw.show()
    # App.exit()
    sys.exit(App.exec_())
© www.soinside.com 2019 - 2024. All rights reserved.