我正在尝试使用Matplotlib和matplotlib的动画包制作3D图。此外,动画应该是使用PyQt和Qt-Designer生成的Gui的一部分。目前我坚持正确使用“animation.Funcnimation()”,至少我是这么认为的...... 所以这是我的代码:
import sys
from PyQt4.uic import loadUiType
from PyQt4 import QtGui
from matplotlib import pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib import animation
import numpy as np
import Quaternion as qt
Ui_MainWindow, QMainWindow = loadUiType('Newsphere.ui')
class Kinematic(Ui_MainWindow, QMainWindow):
def __init__(self):
super(Kinematic, self).__init__()
self.setupUi(self)
self.fig = plt.figure()
self.ax = self.fig.add_subplot(111,projection = '3d')
self.fig.tight_layout()
self.ani = animation.FuncAnimation(self.fig, self.update,
init_func=self.setup_plot, blit=True)
self.canvas = FigureCanvas(self.fig)
self.mplvl.addWidget(self.canvas)
self.canvas.draw()
def setup_plot(self):
self.ax.view_init(40, 45)
self.ax.set_xlabel('X')
self.ax.set_ylabel('Y')
self.ax.set_zlabel('Z')
self.ax.set_xlim3d(-1,1)
self.ax.set_ylim3d(-1,1)
self.ax.set_zlim3d(-1,1)
g_x = np.matrix([[1.0],[0.0],[0.0]])
g_y = np.matrix([[0.0],[1.0],[0.0]])
g_z = np.matrix([[0.0],[0.0],[1.0]])
self.ax.plot([0,g_x[0]], [0,g_x[1]], [0,g_x[2]], label='$X_0$')
self.ax.plot([0,g_y[0]], [0,g_y[1]], [0,g_y[2]], label='$Y_0$')
self.ax.plot([0,g_z[0]], [0,g_z[1]], [0,g_z[2]], label='$Z_0$')
self.vek, = self.ax.plot([0,-1], [0,0], [0,0], label='$g \cdot R$', animated=True)
self.ax.legend(loc='best')
self.ax.scatter(0,0,0, color='k')
return self.vek,
def update(self, i):
b = self.bslider.value() / 100
g = np.matrix([[1.0],[0.0],[0.0]])
q = np.array([0,b,0.5,0])
R = qt.QtoR(q)
x, y, z = R*g
self.vek, = self.ax.plot([0,x], [0,y], [0,z], label='$g \cdot R$', animated=True) #the rotated vector
return self.vek,
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
main = Kinematic()
main.show()
sys.exit(app.exec_())
您将无法通过复制粘贴运行它,因为您没有文件“Newsphere.ui”(第13行)和Quaternion.py(第11行)。因此,当我运行它时,我会得到以下内容(实际上就像我希望的那样!): Coordinate system
我的目标是使用从Gui滑块获得的数据(第58行)绘制一个矢量(第50行)并为其设置动画(第66行)。谁能帮我这个?我已经坚持了好几天了!
答案 0 :(得分:2)
由于你的问题在于动画部分,下面你可以看到一个片段,它为正在旋转的箭头设置动画。
import numpy as np
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
import matplotlib.animation as animation
def data_gen(num):
"""Data generation"""
angle = num * np.pi/36
vx, vy, vz = np.cos(angle), np.sin(angle), 1
ax.cla()
ax.quiver(0, 0, 0, vx, vy, vz, pivot="tail", color="black")
ax.quiver(0, 0, 0, vx, vy, 0, pivot="tail", color="black",
linestyle="dashed")
ax.set_xlim(-1, 1)
ax.set_ylim(-1, 1)
ax.set_zlim(-1, 1)
ax.view_init(elev=30, azim=60)
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
data_gen(0)
ani = animation.FuncAnimation(fig, data_gen, range(72), blit=False)
plt.show()
有关动画的文档可能不是最好的。但是有几个例子,例如,这个例子动画Lorenz attractor。
答案 1 :(得分:0)
因此,如果有人对上述问题的解决方案感兴趣,请转到:(再次,它不是复制粘贴的代码,因为缺少' Newsphere.ui',但我尝试解释重要的片段)
die
通过运行我得到的代码
(这两张图片组合在一起显示相同的过程)
我在this tutorial之后生成了一个名为import sys
from PyQt4.uic import loadUiType
from PyQt4 import QtGui
from matplotlib import pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib import animation
import numpy as np
Ui_MainWindow, QMainWindow = loadUiType('Newsphere.ui')
class Kinematic(Ui_MainWindow, QMainWindow):
def __init__(self):
super(Kinematic, self).__init__()
self.setupUi(self)
self.fig = plt.figure()
self.ax = self.fig.add_subplot(111,projection = '3d')
self.fig.tight_layout()
self.ax.view_init(40, -45)
# dashed coordinate system
self.ax.plot([0,1], [0,0], [0,0], label='$X_0$', linestyle="dashed")
self.ax.plot([0,0], [0,-1], [0,0], label='$Y_0$', linestyle="dashed")
self.ax.plot([0,0], [0,0], [0,1], label='$Z_0$', linestyle="dashed")
self.ax.set_xlim3d(-1,1)
self.ax.set_ylim3d(-1,1)
self.ax.set_zlim3d(-1,1)
self.ax.set_xlabel('X')
self.ax.set_ylabel('Y')
self.ax.set_zlabel('Z')
self.ax.scatter(0,0,0, color='k') # black origin dot
self.canvas = FigureCanvas(self.fig)
self.mplvl.addWidget(self.canvas)
self.ani = animation.FuncAnimation(self.fig, self.data_gen, init_func=self.setup_plot, blit=True)
def setup_plot(self):
self.ax.legend(loc='best')
self.vek = self.ax.quiver(0, 0, 0, 0, 0, 0, label='$g \cdot R$', pivot="tail", color="black")
return self.vek,
def data_gen(self, i):
b = self.bslider.value() / 100
vx, vy, vz = np.cos(b), np.sin(b), 0
self.vek = self.ax.quiver(0, 0, 0, vx, vy, vz, label='$g \cdot R$', pivot="tail", color="black")
self.canvas.draw()
return self.vek,
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
main = Kinematic()
main.show()
sys.exit(app.exec_())
的GUI文件。基本上它只包含一个Widget,一个QSlider和一个QSpinBox。 Widget具有布局名称" mplvl",它出现在第41行。这将生成的图形添加到窗口小部件(我想是这样......)。 QSlider与QSpinBox连接(在QtDesigner中完成)并且名称为" bslider",第55行。因此,在此行中,滑块值除以100,因为我没有找到滑块这会产生一个浮动值。对我来说,关键是第61行,绘制画布。现在Newsphere.ui
(第43行)在我更改滑块值时绘制一个新向量,比较图片。同样重要的是将变化的向量绘制为animation.FuncAnimation
,而不是像我之前尝试的ax.quiver
那样。
如果有任何问题或建议需要改进,请询问/发帖。