Python:使用mplot3d和动画制作矢量动画

时间:2016-09-23 17:48:05

标签: python qt animation matplotlib

我正在尝试使用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行)。谁能帮我这个?我已经坚持了好几天了!

2 个答案:

答案 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

通过运行我得到的代码

enter image description here

(这两张图片组合在一起显示相同的过程)

我在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那样。

如果有任何问题或建议需要改进,请询问/发帖。