2012-07-07 114 views
10

我想要获得matplotlib散点图的3d动画,基于2d scatterplot动画发布here和3d线图张贴here在matplotlib动画3d scatterplot

问题出在set_dataset_offsets不能用3D工作,所以你应该使用set_3d_properties来处理z信息。玩弄它通常会窒息,但随着下面的代码发布它运行。然而,透明度的增加足够让点数在几帧后消失。我在这里做错了什么?我想要点在盒子的边界内跳过一段时间。即使将步长调整为非常小也不会减慢透明度。

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

FLOOR = -10 
CEILING = 10 

class AnimatedScatter(object): 
    def __init__(self, numpoints=5): 
     self.numpoints = numpoints 
     self.stream = self.data_stream() 
     self.angle = 0 

     self.fig = plt.figure() 
     self.ax = self.fig.add_subplot(111,projection = '3d') 
     self.ani = animation.FuncAnimation(self.fig, self.update, interval=100, 
              init_func=self.setup_plot, blit=True) 

    def change_angle(self): 
     self.angle = (self.angle + 1)%360 

    def setup_plot(self): 
     x, y, z = next(self.stream) 
     c = ['b', 'r', 'g', 'y', 'm'] 
     self.scat = self.ax.scatter(x, y, z,c=c, s=200, animated=True) 

     self.ax.set_xlim3d(FLOOR, CEILING) 
     self.ax.set_ylim3d(FLOOR, CEILING) 
     self.ax.set_zlim3d(FLOOR, CEILING) 

     return self.scat, 

    def data_stream(self): 
     data = np.zeros((3, self.numpoints)) 
     xyz = data[:3, :] 
     while True: 
      xyz += 2 * (np.random.random((3, self.numpoints)) - 0.5) 
      yield data 

    def update(self, i): 
     data = next(self.stream) 
     data = np.transpose(data) 

     self.scat.set_offsets(data[:,:2]) 
     #self.scat.set_3d_properties(data) 
     self.scat.set_3d_properties(data[:,2:],'z') 

     self.change_angle() 
     self.ax.view_init(30,self.angle) 
     plt.draw() 
     return self.scat, 

    def show(self): 
     plt.show() 

if __name__ == '__main__': 
    a = AnimatedScatter() 
    a.show() 
+3

想通了沿着内部完成,如果有人需要这个。删除关于set_offsets和set_3d_properties的所有行,并使用下面的代码:self.scat._offsets3d =(x,y,z),在这段代码中明显地从数据中提取x,y和z。 – 2012-07-08 03:47:31

+0

是否可以使用plot()而不是散点图?顺便说一句,你的解决方案为我工作。 – 2013-10-18 13:27:25

+1

@ericp您应该发布您的解决方案作为答案... – 2014-04-05 18:54:00

回答

3

我发现这一点,更通用的,解决方法: 您shold集合中插入数据之前加np.ma.ravel(x_data) ...

但散点图似乎并不适用于动画;它太慢了。

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

FLOOR = -10 
CEILING = 10 

class AnimatedScatter(object): 
    def __init__(self, numpoints=5): 
     self.numpoints = numpoints 
     self.stream = self.data_stream() 
     self.angle = 0 

     self.fig = plt.figure() 
     self.ax = self.fig.add_subplot(111,projection = '3d') 
     self.ani = animation.FuncAnimation(self.fig, self.update, interval=100, 
              init_func=self.setup_plot, blit=True) 

    def change_angle(self): 
     self.angle = (self.angle + 1)%360 

    def setup_plot(self): 
     X = next(self.stream) 
     c = ['b', 'r', 'g', 'y', 'm'] 
     self.scat = self.ax.scatter(X[:,0], X[:,1], X[:,2] , c=c, s=200, animated=True) 

     self.ax.set_xlim3d(FLOOR, CEILING) 
     self.ax.set_ylim3d(FLOOR, CEILING) 
     self.ax.set_zlim3d(FLOOR, CEILING) 

     return self.scat, 

    def data_stream(self): 
     data = np.zeros((self.numpoints , 3)) 
     xyz = data[:,:3] 
     while True: 
      xyz += 2 * (np.random.random((self.numpoints,3)) - 0.5) 
      yield data 

    def update(self, i): 
     data = next(self.stream) 
     data = np.transpose(data) 

     self.scat._offsets3d = (np.ma.ravel(data[:,0]) , np.ma.ravel(data[:,0]) , np.ma.ravel(data[:,0])) 

     self.change_angle() 
     self.ax.view_init(30,self.angle) 
     plt.draw() 
     return self.scat, 

    def show(self): 
     plt.show() 

if __name__ == '__main__': 
    a = AnimatedScatter() 
    a.show() 
4

找到了解决办法。最后,这里是如何更新点W/O触摸颜色:

from mpl_toolkits.mplot3d.art3d import juggle_axes 
scat._offsets3d = juggle_axes(xs, ys, zs, 'z') 

这是由set_3d_properties与重新初始化颜色