Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/295.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 在函数内部调用FuncAnimation()_Python_Matplotlib_Animation_Pyqt_Pyqt5 - Fatal编程技术网

Python 在函数内部调用FuncAnimation()

Python 在函数内部调用FuncAnimation(),python,matplotlib,animation,pyqt,pyqt5,Python,Matplotlib,Animation,Pyqt,Pyqt5,我试图在调用特定函数时执行FuncAnimation()。然而,我的阴谋没有得到任何结果 如果FuncAnimation不在函数内部(或在_init__()内部),则它可以正常工作 我尝试了所有已经发布的与该问题相关的解决方案,但它们在我的代码中不起作用 我的简化代码是: import sys import os from datetime import datetime import matplotlib from PyQt5 import QtCore, QtWidgets from PyQ

我试图在调用特定函数时执行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_())

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

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

从日期时间导入日期时间
随机输入
导入操作系统
导入系统
从PyQt5导入QtCore、QtWidgets
将numpy作为np导入
从matplotlib.backends.backend_qt5agg导入FigureCanvas qtagg as FigureCanvas
从matplotlib.figure导入图形
从matplotlib.animation导入FuncAnimation
类MyMplCanvas(FigureCanvas):
def u uu init uu uuuu(self,parent=None,width=5,height=4,dpi=100):
图=图(图尺寸=(宽度、高度),dpi=dpi)
self.ax=fig.add_子批次(1,1,1)
FigureCanvas.\uuuuu init\uuuuu(self,图)
self.setParent(父级)
图Canvas.setSizePolicy(
self,qtwidts.QSizePolicy.expansing,qtwidts.QSizePolicy.expansing
)
图CAVAS.updateGeometry(自我)
类ApplicationWindow(QtWidgets.QMainWindow):
定义初始化(自):
qtwidts.QMainWindow.\uuuu init\uuuuu(self)
self.main_widget=qtwidts.QWidget(self)
self.canvas=mymplnavas(self.main_小部件,宽度=6,高度=6,dpi=100)
self.xdata=[]
self.ydata=[]
vbox=qtwidts.QVBoxLayout(self.main_小部件)
self.start_button=qtwidts.QPushButton(text=“start”)
#self.outer\u ani=self.start\u按钮。单击。连接(self.start\u函数动画)
self.start_按钮。单击。连接(self.start_函数动画)
vbox.addWidget(self.canvas)
vbox.addWidget(self.start_按钮)
#self.setLayout(vbox)
self.main_widget.setFocus()
self.setCentralWidget(self.main_小部件)
def start_func_动画(自):
(self.line,)=self.canvas.ax.plot\u日期(
self.xdata,self.ydata,linestyle=“-”,线宽=0.6,标记大小=2.5
)
self.canvas.draw()
self.ani=FuncAnimation(self.canvas.figure,self.update\u行,间隔=1000)
#或
#self.ani=FuncAnimation(self.canvas.figure,self.update\u行,间隔=1000,blit=True)
#返回self.ani
def更新_行(自我,i):
self.xdata.append(datetime.now())
self.ydata.append(1+np.random.randint(-3,3))
self.line.set_数据(self.xdata、self.ydata)
self.canvas.figure.gca().relim()
self.canvas.figure.gca().autoscale_view()
self.canvas.ax.tick_参数(axis=“x”,旋转=50)
返回(self.line,)
如果名称=“\uuuuu main\uuuuuuuu”:
App=qtwidts.QApplication(sys.argv)
aw=应用程序窗口()
aw.show()
#App.exit()
sys.exit(App.exec_())

函数
update\u line
中没有对绘图的调用,该函数由
FuncAnimation
调用。很抱歉,我不太明白您的意思。你能再详细解释一下吗?我错了<代码>设置数据应该绘制。好的,非常感谢您的帮助!我看到它现在起作用了。但是,对于使用self.canvas.draw()的解决方案,动画不应足以在没有这条线的情况下进行动画打印?。对于第二个选项(使用blit),当我在mac上运行它时,它的右下方显示为剪切(这里是gif:),但当我使用windows时,它工作得非常好。你知道这可能是什么原因吗?1)将艺术家添加到画布中作为“self.line”并不意味着它是自动绘制的(我怀疑matplotlib这样做是为了提高效率),因此你应该使用draw函数。2) 我不知道为什么在Mac OS中会出现这种行为,在Linux中,它可以正确地使用blit=True。好的!最后,我注意到将{self.canvas.draw()}放在FuncAnimation()之后会返回更好的结果,因为在FuncAnimation()之前使用它时,会绘制一些意外的点。你也一样吗?