[英]Calling FuncAnimation() when it is inside a function
我試圖在調用特定的 function 時執行 FuncAnimation()。 但是,我在 plot 中沒有得到任何結果。
當 FuncAnimation 不在 function 內(或在 __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
。
除了上面你還有一個錯誤是假設一個信號和一個槽之間的連接返回了被調用的 function 的結果,這是錯誤的,連接返回一個變量,表明連接是否成功。 另一個錯誤是您在 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_())
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.