python - 将 matplotlib 图嵌入 pyqt5
问题描述
我已经尝试使用示例代码片段使用来自 matplotlib 的 pyplot 的 _update_plot 将我的火星和地球绕太阳运行的动画图嵌入到 PyQt5 GUI 中。没有使用 pyplot 的例子,我真的很挣扎。我在这里没有错:(?)
试图:
import sys
import time
import numpy as np
from matplotlib.backends.qt_compat import QtCore, QtWidgets, is_pyqt5
if is_pyqt5():
from matplotlib.backends.backend_qt5agg import (
FigureCanvas, NavigationToolbar2QT as NavigationToolbar)
else:
from matplotlib.backends.backend_qt4agg import (
FigureCanvas, NavigationToolbar2QT as NavigationToolbar)
from matplotlib.figure import Figure
class ApplicationWindow(QtWidgets.QMainWindow):
def __init__(self):
super().__init__()
self._main = QtWidgets.QWidget()
self.setCentralWidget(self._main)
layout = QtWidgets.QVBoxLayout(self._main)
static_canvas = FigureCanvas(Figure(figsize=(5, 3)))
layout.addWidget(static_canvas)
self.addToolBar(NavigationToolbar(static_canvas, self))
dynamic_canvas = FigureCanvas(Figure(figsize=(5, 3)))
layout.addWidget(dynamic_canvas)
self.addToolBar(QtCore.Qt.BottomToolBarArea,
NavigationToolbar(dynamic_canvas, self))
self._static_ax = static_canvas.figure.subplots()
t = np.linspace(0, 10, 501)
self._static_ax.plot(t, np.tan(t), ".")
self._dynamic_ax = dynamic_canvas.figure.subplots()
self._timer = dynamic_canvas.new_timer(
100, [(self._update_canvas, (), {})])
self._timer.start()
def _update_canvas(self):
scat = scat.set_offsets(([math.cos(math.radians(i))*7.5, math.sin(math.radians(i))*7.5], [math.cos(math.radians(i/2))*9, math.sin(math.radians(i/2))*9], [0, 0]))
anim = self.animation.FuncAnimation(fig, scat, fargs = (fig, scat, l,l2),
frames = 720, interval = 10)
if __name__ == "__main__":
qapp = QtWidgets.QApplication(sys.argv)
app = ApplicationWindow()
app.show()
qapp.exec_()
我试图嵌入的原始代码是这样的:
import math
import matplotlib.pyplot as plt
import matplotlib.animation as animation
import numpy as np
def _update_plot(i, fig, scat):
M = ((math.sin(math.radians(i))*7.5)-(math.sin(math.radians(i/2))*9))/((math.cos(math.radians(i))*7.5)-(math.cos(math.radians(i/2))*9))
g = M*(15-(math.cos(math.radians(i/2))*9))+(math.sin(math.radians(i/2))*9)
scat.set_offsets(([math.cos(math.radians(i))*7.5, math.sin(math.radians(i))*7.5], [math.cos(math.radians(i/2))*9, math.sin(math.radians(i/2))*9], [0, 0]))
return [scat]
fig = plt.figure()
x = [0]
y = [0]
ax = fig.add_subplot(111)
ax.set_aspect('equal')
ax.grid(True, linestyle = '-', color = '0.10')
ax.set_xlim([-15, 15])
ax.set_ylim([-15, 15])
scat = plt.scatter(x, y, c = x, zorder=3)
scat.set_alpha(0.8)
anim = animation.FuncAnimation(fig, _update_plot, fargs = (fig, scat),
frames = 720, interval = 10)
plt.show()
非常感谢任何帮助/建议。
解决方案
如果您嵌入自定义 GUI,这个想法确实是不使用 pyplot。否则,您的图形将由 pyplot 和 GUI 管理。
您的示例的改编可能如下所示:
import sys
import numpy as np
from matplotlib.backends.qt_compat import QtWidgets
from matplotlib.backends.backend_qt5agg import (
FigureCanvas, NavigationToolbar2QT as NavigationToolbar)
from matplotlib.figure import Figure
from matplotlib import animation
class ApplicationWindow(QtWidgets.QMainWindow):
def __init__(self):
super().__init__()
self._main = QtWidgets.QWidget()
self.setCentralWidget(self._main)
layout = QtWidgets.QVBoxLayout(self._main)
self.fig = Figure(figsize=(5, 3))
self.canvas = FigureCanvas(self.fig)
layout.addWidget(self.canvas)
self.addToolBar(NavigationToolbar(self.canvas, self))
self.setup()
def setup(self):
self.ax = self.fig.subplots()
self.ax.set_aspect('equal')
self.ax.grid(True, linestyle = '-', color = '0.10')
self.ax.set_xlim([-15, 15])
self.ax.set_ylim([-15, 15])
self.scat = self.ax.scatter([], [], zorder=3)
self.scat.set_alpha(0.8)
self.anim = animation.FuncAnimation(self.fig, self.update,
frames = 720, interval = 10)
def update(self, i):
self.scat.set_offsets(([np.cos(np.radians(i))*7.5, np.sin(np.radians(i))*7.5],
[np.cos(np.radians(i/2))*9, np.sin(np.radians(i/2))*9]))
if __name__ == "__main__":
qapp = QtWidgets.QApplication(sys.argv)
app = ApplicationWindow()
app.show()
qapp.exec_()
推荐阅读
- c# - 如何避免两个 foreach 循环并有条件地将属性值从一个分配给另一个?
- javascript - 我们可以在使用 typescript (ts,tsx) 构建的现有项目中使用 javascript 文件吗?
- javascript - [IP 错误]MongooseServerSelectionError:无法连接到 MongoDB Atlas 集群中的任何服务器
- antlr - 使用 antlr 和 python 解析 VB 代码的抽象语法树
- android - 溢出菜单项中的标题未出现
- css - SASS/SCSS:将另一个 CSS 或 SCSS 文件的内容包含(不导入)到现有文件中?
- python - Python lambda 不是从函数中获取变量
- swift - 根据 Xcode 中选择的目标将图像加载到 uiimageview
- angular - Angular 11 可以根据 HTTP 请求的结果激活 Guard
- python - 比较两个大小不等的numpy数组并用nan填充排除元素