2012-07-07 18 views
10

here yayınlanmış 2d scatterplot animasyonu ve here no'lu iletilen 3B çizgi grafiğinden yola çıkarak, matplotlib'de bir scatterplot'un 3 boyutlu bir animasyonunu almaya çalışıyorum.Matplotlib'de 3d dağılım grafiği Animasyon

set_data ve set_offsets'dan kaynaklanan sorunlar, 3B'de çalışmaz, bu nedenle, set_3d_properties'u z bilgilerinin üzerine yazmak için kullanmanız gerekir. Bununla oynamak, genellikle boğaz, ancak aşağıda yayınlanan kodu ile çalışır. Bununla birlikte, saydamlık, noktaların birkaç kareden sonra ortadan kaybolmasına yetecek kadar artar. Burada neyi yanlış yapıyorum? Bir süreliğine kutuların sınırları içinde kalmasını istiyorum. Adım boyutunu çok küçük bir şeye ayarlamak bile saydamlığı yavaşlatmaz.

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

o dışarı yeniden başlatma renkleri ile birlikte set_3d_properties yapılır, eğer buna ihtiyaç varsa. set_offsets ve set_3d_properties ile ilgili tüm satırları kaldırın ve sadece şunu kullanın: self.scat._offsets3d = (x, y, z), bu kodda veriden x, y ve z çıkarıyor. –

+0

Plot(), dağılım grafiği yerine noktalarla kullanılabilir mi? Bu arada çözümün benim için çalıştı. –

+1

@ericp Çözümünüzü yanıt olarak göndermelisiniz ... –

cevap

3

bunu buldum ve daha genel, çözüm ettik: Koleksiyona veri takmadan önce np.ma.ravel(x_data) ... eklemek shold.

Ancak, dağılım grafiği animasyonlar için tasarlanmamış gibi görünmektedir; çok yavaş. Burada

son olarak çözelti Bulunan
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

, dokunmadan renkler o/w noktaları güncellemek için nasıl:

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

bu dahili

İlgili konular