我正在尝试制作散点图的动画,其中点的颜色和大小在动画的不同阶段发生变化。对于数据,我有两个numpy ndarray,其中包含x值和y值:
data.shape = (ntime, npoint)
x.shape = (npoint)
y.shape = (npoint)
现在我想绘制一个
类型的散点图pylab.scatter(x,y,c=data[i,:])
并在索引i
上创建动画。我该怎么做?
答案 0 :(得分:83)
假设您有散点图scat = ax.scatter(...)
,那么您可以
更改职位
scat.set_offsets(array)
其中array
是N x 2
形状的x和y坐标。
更改尺寸
scat.set_sizes(array)
其中array
是以点为单位的1D数组。
更改颜色
scat.set_array(array)
其中array
是将进行色彩映射的一维数组值。
以下是使用animation module的简单示例 它稍微复杂一点,但这应该给你一个框架来做更好的事情。
(2019年4月编辑的代码与当前版本兼容。对于较旧的代码,请参阅revision history)
import matplotlib.pyplot as plt
import matplotlib.animation as animation
import numpy as np
class AnimatedScatter(object):
"""An animated scatter plot using matplotlib.animations.FuncAnimation."""
def __init__(self, numpoints=50):
self.numpoints = numpoints
self.stream = self.data_stream()
# Setup the figure and axes...
self.fig, self.ax = plt.subplots()
# Then setup FuncAnimation.
self.ani = animation.FuncAnimation(self.fig, self.update, interval=5,
init_func=self.setup_plot, blit=True)
def setup_plot(self):
"""Initial drawing of the scatter plot."""
x, y, s, c = next(self.stream).T
self.scat = self.ax.scatter(x, y, c=c, s=s, vmin=0, vmax=1,
cmap="jet", edgecolor="k")
self.ax.axis([-10, 10, -10, 10])
# For FuncAnimation's sake, we need to return the artist we'll be using
# Note that it expects a sequence of artists, thus the trailing comma.
return self.scat,
def data_stream(self):
"""Generate a random walk (brownian motion). Data is scaled to produce
a soft "flickering" effect."""
xy = (np.random.random((self.numpoints, 2))-0.5)*10
s, c = np.random.random((self.numpoints, 2)).T
while True:
xy += 0.03 * (np.random.random((self.numpoints, 2)) - 0.5)
s += 0.05 * (np.random.random(self.numpoints) - 0.5)
c += 0.02 * (np.random.random(self.numpoints) - 0.5)
yield np.c_[xy[:,0], xy[:,1], s, c]
def update(self, i):
"""Update the scatter plot."""
data = next(self.stream)
# Set x and y data...
self.scat.set_offsets(data[:, :2])
# Set sizes...
self.scat.set_sizes(300 * abs(data[:, 2])**1.5 + 100)
# Set colors..
self.scat.set_array(data[:, 3])
# We need to return the updated artist for FuncAnimation to draw..
# Note that it expects a sequence of artists, thus the trailing comma.
return self.scat,
if __name__ == '__main__':
a = AnimatedScatter()
plt.show()
如果您使用OSX并使用OSX后端,则需要在下面的blit=True
初始化中将blit=False
更改为FuncAnimation
。 OSX后端不完全支持blitting。性能将受到影响,但该示例应该在OSX上正确运行且禁用blit。
有关更新颜色的简单示例,请查看以下内容:
import matplotlib.pyplot as plt
import numpy as np
import matplotlib.animation as animation
def main():
numframes = 100
numpoints = 10
color_data = np.random.random((numframes, numpoints))
x, y, c = np.random.random((3, numpoints))
fig = plt.figure()
scat = plt.scatter(x, y, c=c, s=100)
ani = animation.FuncAnimation(fig, update_plot, frames=xrange(numframes),
fargs=(color_data, scat))
plt.show()
def update_plot(i, data, scat):
scat.set_array(data[i])
return scat,
main()
答案 1 :(得分:3)
这是事情。我曾经是Qt和Matlab的用户,我对matplotlib上的动画系统并不熟悉。
但我确实找到了一种可以制作任何类型动画的方法,就像在matlab中一样。它真的很强大。无需检查模块参考,您可以根据需要绘制任何内容。所以我希望它可以提供帮助。
基本的想法是在PyQt中使用time事件(我确信Python上的其他Gui系统就像wxPython和TraitUi具有相同的内部机制来进行事件响应。但我只是不知道如何)。每次调用PyQt的Timer事件时,我都会刷新整个画布并重新绘制整个画面,我知道速度和性能可能会受到慢慢影响,但并不是那么多。
以下是一个小例子:
import sys
from PyQt4 import QtGui
from matplotlib.figure import Figure
from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas
import numpy as np
class Monitor(FigureCanvas):
def __init__(self):
self.fig = Figure()
self.ax = self.fig.add_subplot(111)
FigureCanvas.__init__(self, self.fig)
self.x = np.linspace(0,5*np.pi,400)
self.p = 0.0
self.y = np.sin(self.x+self.p)
self.line = self.ax.scatter(self.x,self.y)
self.fig.canvas.draw()
self.timer = self.startTimer(100)
def timerEvent(self, evt):
# update the height of the bars, one liner is easier
self.p += 0.1
self.y = np.sin(self.x+self.p)
self.ax.cla()
self.line = self.ax.scatter(self.x,self.y)
self.fig.canvas.draw()
if __name__ == "__main__":
app = QtGui.QApplication(sys.argv)
w = Monitor()
w.setWindowTitle("Convergence")
w.show()
sys.exit(app.exec_())
您可以在
中调整刷新速度self.timer = self.startTimer(100)
我就像你想要使用动画散点图来制作排序动画一样。但我只是找不到所谓的“设置”功能。所以我刷新了整个canva。
希望有所帮助......
答案 2 :(得分:3)
我写了celluloid来简化这个过程。可能最容易通过示例显示:
int second = decomposedPortion(baz);
TypeR result = foo(first, second);
它在引擎盖下使用import matplotlib.pyplot as plt
from matplotlib import cm
import numpy as np
from celluloid import Camera
numpoints = 10
points = np.random.random((2, numpoints))
colors = cm.rainbow(np.linspace(0, 1, numpoints))
camera = Camera(plt.figure())
for _ in range(100):
points += 0.1 * (np.random.random((2, numpoints)) - .5)
plt.scatter(*points, c=colors, s=100)
camera.snap()
anim = camera.animate(blit=True)
anim.save('scatter.mp4')
。 ArtistAnimation
捕获图形的当前状态,该状态用于在动画中创建帧。
编辑:为了量化使用的内存量,我将其运行到memory_profiler。
camera.snap
总结一下:
答案 3 :(得分:-1)
为什么不尝试此操作
import numpy as np
import matplotlib.pyplot as plt
x=np.random.random()
y=np.random.random()
fig, ax = plt.subplots()
ax.scatter(x,y,color='teal')
ax.scatter(y,x,color='crimson')
ax.set_xlim([0,1])
ax.set_ylim([0,1])
for i in np.arange(50):
x=np.random.random()
y=np.random.random()
bha=ax.scatter(x,y)
plt.draw()
plt.pause(0.5)
bha.remove()
plt.show()