在matplotlib动画3d scatterplot
问题描述:
我想要获得matplotlib散点图的3d动画,基于2d scatterplot动画发布here和3d线图张贴here。在matplotlib动画3d scatterplot
问题出在set_data
和set_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()
答
我发现这一点,更通用的,解决方法: 您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()
答
找到了解决办法。最后,这里是如何更新点W/O触摸颜色:
from mpl_toolkits.mplot3d.art3d import juggle_axes
scat._offsets3d = juggle_axes(xs, ys, zs, 'z')
这是由set_3d_properties与重新初始化颜色
想通了沿着内部完成,如果有人需要这个。删除关于set_offsets和set_3d_properties的所有行,并使用下面的代码:self.scat._offsets3d =(x,y,z),在这段代码中明显地从数据中提取x,y和z。 – 2012-07-08 03:47:31
是否可以使用plot()而不是散点图?顺便说一句,你的解决方案为我工作。 – 2013-10-18 13:27:25
@ericp您应该发布您的解决方案作为答案... – 2014-04-05 18:54:00