在显示所有点之前冻结具有颜色的3d动画

时间:2018-07-11 07:52:40

标签: python python-3.x animation matplotlib

我想拥有一个类,该类使我可以通过以下方式轻松绘制4或5个变量的数据集: 3D位置的3个变量 1个颜色变量 1个变量,直到显示动画的下一个点为止的时间

如果仅给出四个输入,则第四个输入应同时具有颜色和间隔长度。

我尝试了许多不同的尝试,最终得到了下面指定的代码。

我遇到的问题是动画实际上并没有到达终点,但是在那之前停滞了。查看系统监视器,它也会占用大量CPU,但是大多数情况是在冻结之后。您知道为什么会出现此问题以及如何解决该问题吗?经过几天的研究,我仍然没有找到令人满意的解决方案。

import numpy as np
from matplotlib import pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.animation
import matplotlib.colors as colors

# Test data from random Generation
a = np.random.rand(200, 3)*10
x=a[:,0]
y=a[:,1]
z=a[:,2]
t0 = [i for i in range(200)]


class AnimateIn3D:        
    def __init__(self, x ,y ,z, t, c = None, plotmargin=0.1, animation_speed=100, msize=11):
        """Simple Animator class for 4-dimensional datasets. 
        The parameter c can be any array of the seme length as x, y or z.
        The values of x, y and z are displayed by location, the values for c are displayed by a color gradient. If not specified,
        c takes tha value of t. The values in t are used for the time interval between different frames and can be multiplied by
        any number (specifiable in animation_speed).
        Additionally, a plotmargin (in percent) can be specified and is applied to the graph in all directions (x,y,z).
        """

        #plotting constants
        self.c = t if c == None else True
        self.x, self.y, self.z, self.t = x, y, z, t
        self.plotmargin = plotmargin
        self.msize=msize

        #animation constants
        self.pause = False
        self.animation_speed = animation_speed
        self.t_normal = [float(i)/max(self.t) for i in self.t]

        self.normalized_cvec = [float(i)/max(self.t) for i in self.c]
        self.color_list = self.generate_color_sequence(self.c)

        #plottting
        self.fig = plt.figure()
        self.fig.canvas.mpl_connect('key_press_event', self.onKey) #space-key binding
        self.ax = self.fig.add_subplot(111, projection='3d')
        self.title = self.ax.set_title('3D Lightning plot')

        margins=[]
        for dataset in [self.x, self.y, self.z]:
            margins.append((max(dataset)-min(dataset))*plotmargin)

        self.ax.set_xlim(min(self.x)-margins[0], max(self.x)+margins[0])
        self.ax.set_ylim(min(self.y)-margins[1], max(self.y)+margins[1])
        self.ax.set_zlim(min(self.z)-margins[2], max(self.z)+margins[2])

        self.content=self.ax.plot([self.x[0]],[self.y[0]],[self.z[0]], color=self.color_list[0], marker='o', markersize=self.msize)

        #animation
        self.ani = matplotlib.animation.FuncAnimation(self.fig, self.update_graph,
                    len(self.t),interval = np.ceil(self.t_normal[0]*self.animation_speed), blit=False, repeat = True)
        plt.show()    

    def generate_color_sequence(self,floatlist, cmapname="viridis"):
        """ generates a color sequence with color-seperations according to
        the seperation of values in the input floatlist"""
        cmap=plt.get_cmap(cmapname)
        return cmap(floatlist)

    def update_graph(self, num):
        """updates 3D-plot with next frame"""
        if not self.pause:
            self.content = self.ax.plot([self.x[num]],[self.y[num]],[self.z[num]],
                    color=self.color_list[num], marker='o', markersize=self.msize)
            self.ani.event_source.interval = self.t_normal[num]*self.animation_speed
        return self.content

    def onKey(self, event):
        """pauses the animation by space-key trigger"""
        if (event.key == " "):
            self.pause ^= True

AnimateIn3D(x,y,z,t0, plotmargin=0.1, msize=1)

(我正在使用ubuntu 18.04和Python 3)

0 个答案:

没有答案