【问题标题】:Python: Animating a vector using mplot3d and animationPython:使用 mplot3d 和动画制作矢量动画
【发布时间】:2016-09-23 17:48:05
【问题描述】:

我正在尝试使用 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 行)。谁能帮我这个?我被这个问题困扰了好几天!

【问题讨论】:

    标签: python qt animation matplotlib


    【解决方案1】:

    由于您的问题在于动画部分,因此您可以在下面看到一个 sn-p,它为旋转的箭头设置动画。

    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

    【讨论】:

      【解决方案2】:

      因此,如果有人对上述问题的解决方案感兴趣,我们就开始吧:(同样,由于缺少“Newsphere.ui”,这不是复制粘贴的代码,但我尝试解释重要的 sn- ps)

      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_())
      

      通过运行我得到的代码

      (这是两张图片合二为一,显示相同的过程)

      我在this tutorial 之后生成了一个名为Newsphere.ui 的GUI 文件。基本上它只包含一个小部件、一个 QSlider 和一个 QSpinBox。 Widget 的布局名称为“mplvl”,出现在第 41 行。这会将生成的图形添加到小部件中(我认为是这样......)。 QSlider 与 QSpinBox 连接(在 QtDesigner 中完成)并具有名称“bslider”,第 55 行。所以在这一行中,滑块值除以 100,因为我没有找到生成浮点值的滑块.对我来说,关键线是画布的第 61 行。现在,animation.FuncAnimation(第 43 行)在我更改滑块值时绘制了一个新矢量,比较图片。此外,将变化的矢量绘制为 ax.quiver 而不是像我之前的尝试那样绘制为 ax.plot 也很重要。

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-09-24
        • 1970-01-01
        相关资源
        最近更新 更多