如何在一个 PyQt5 窗口上应用 2 个动画(带有旋转扇区和轨迹的圆)?这是一段代码,这些函数分别工作,轨迹取自 JSON 文件。我尝试将 2 个动画组合成更新函数,但没有任何效果,因为我不明白如何使用“FuncAnimation”以及要传递给它的参数。如果你能帮助我,我会很高兴。
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.figure import Figure
class MyFigurePolar(FigureCanvas):
def __init__(self,width=5, height=4, dpi=100, fig = None, ax = None):
if fig == None:
self.fig = Figure(figsize=(width, height), dpi=dpi)
self.axes = self.fig.add_subplot(111, projection='polar')
else:
self.fig = fig
self.axes = ax
super(MyFigurePolar, self).__init__(self.fig)
def anim_2d(self):
data = self.file
fig, ax = plt.subplots(subplot_kw={'projection': 'polar'})
ax.set_xlabel("X")
ax.set_ylabel("Y")
ax.grid(True)
points = make_points_between(data['trajectory']).T
def update(num, points, ln):
ln.set_data(np.arctan2(points[0, :num], points[1, :num]),
np.sqrt(points[0, :num] ** 2 + points[1, :num] ** 2))
return ln,
def update1(frame):
ax.clear()
r = 7
period = np.pi / 64
sector = ax.fill_between([], [], [], alpha=0.5, facecolor='red') # Начинать с красного цвета
theta = np.linspace(0, 2 * np.pi, 100)
ax.set_theta_zero_location("N")
ax.set_theta_direction(-1)
ax.plot(theta, np.ones(100) * r, linestyle='-', color='black')
start = frame * np.pi / 180
end = start - period
sector = ax.fill_between([start, end], 0, r, alpha=0.5, facecolor='red')
ax.set_yticklabels([5000, 10000, 15000, 20000, 25000])
return sector,
ln, = ax.plot(np.arctan2(points[0, 0:1], points[1, 0:1]), np.sqrt(points[0, 0:1] ** 2 + points[1, 0:1] ** 2))
ax.set_xlim([np.min(points[0, :]), np.max(points[0, :])])
ax.set_xlabel('X')
ax.set_ylim([np.min(points[1, :]), np.max(points[1, :])])
ax.set_ylabel('Y')
self.anim = FuncAnimation(fig, update, len(points[0]), fargs=(points, ln, None), interval=10000 / len(points[0]),
blit=False)
self.anim0 = FuncAnimation(fig, update1, frames=360, fargs=(points, ln, None), interval=15, blit=True)
return MyFigurePolar(fig=fig, ax=ax)
def myfunc(self):
F = self.anim_2d()
self.gridlayout = QGridLayout(self.groupBox)
self.gridlayout.addWidget(F, 0, 1)
我试图在互联网上查找信息,但一直没有找到。
要使用 FuncAnimation 将两个动画合并到一个 PyQt5 窗口中,您需要创建一个更新函数来同时更新两个动画。您可以通过以下方式修改代码来实现此目的:
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.figure import Figure
from PyQt5.QtWidgets import QWidget, QVBoxLayout
import json
class MyFigurePolar(FigureCanvas):
def __init__(self, width=5, height=4, dpi=100, fig=None, ax=None):
if fig is None:
self.fig = Figure(figsize=(width, height), dpi=dpi)
self.axes = self.fig.add_subplot(111, projection='polar')
else:
self.fig = fig
self.axes = ax
super(MyFigurePolar, self).__init__(self.fig)
def make_points_between(trajectory):
# Dummy function for demonstration
# You should implement this according to your JSON data structure
return np.array([[0, 1, 2, 3, 4], [0, 1, 2, 1, 0]])
class MyWidget(QWidget):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
self.setWindowTitle('Animation Demo')
layout = QVBoxLayout(self)
self.figure_canvas = MyFigurePolar()
layout.addWidget(self.figure_canvas)
self.anim_2d()
self.anim_sector()
self.show()
def anim_2d(self):
with open('trajectory.json') as f:
data = json.load(f)
points = make_points_between(data['trajectory']).T
self.ln, = self.figure_canvas.axes.plot(np.arctan2(points[0, 0:1], points[1, 0:1]),
np.sqrt(points[0, 0:1] ** 2 + points[1, 0:1] ** 2))
def update(num):
self.ln.set_data(np.arctan2(points[0, :num], points[1, :num]),
np.sqrt(points[0, :num] ** 2 + points[1, :num] ** 2))
self.update_sector(num)
return self.ln,
self.anim = FuncAnimation(self.figure_canvas.fig, update, frames=len(points[0]), interval=10000 / len(points[0]))
def update_sector(self, frame):
r = 7
period = np.pi / 64
self.sector.remove() if hasattr(self, 'sector') else None
start = frame * np.pi / 180
end = start - period
self.sector = self.figure_canvas.axes.fill_between([start, end], 0, r, alpha=0.5, facecolor='red')
self.figure_canvas.draw()
def anim_sector(self):
self.anim0 = FuncAnimation(self.figure_canvas.fig, self.update_sector, frames=360, interval=15)
if __name__ == '__main__':
import sys
from PyQt5.QtWidgets import QApplication
app = QApplication(sys.argv)
widget = MyWidget()
sys.exit(app.exec_())
在此代码中:
此代码应创建一个 PyQt5 窗口,其中两个动画同时运行。根据您的应用程序的需要调整文件路径和动画参数。