我正在尝试制作散点图的动画,其中点的颜色和大小在动画的不同阶段会发生变化。对于数据,我有两个带有x值和y值的numpy ndarray:
data.shape = (ntime, npoint)
x.shape = (npoint)
y.shape = (npoint)
现在我想绘制一个散点图
pylab.scatter(x,y,c=data[i,:])
并在索引上创建动画i
。我该怎么做呢?
我正在尝试制作散点图的动画,其中点的颜色和大小在动画的不同阶段会发生变化。对于数据,我有两个带有x值和y值的numpy ndarray:
data.shape = (ntime, npoint)
x.shape = (npoint)
y.shape = (npoint)
现在我想绘制一个散点图
pylab.scatter(x,y,c=data[i,:])
并在索引上创建动画i
。我该怎么做呢?
Answers:
假设您有一个散点图scat = ax.scatter(...)
,则可以
改变立场
scat.set_offsets(array)
其中array
是N x 2
x和y坐标的形状数组。
改变大小
scat.set_sizes(array)
其中array
是以点为单位的一维尺寸数组。
改变颜色
scat.set_array(array)
其中array
是一维值数组,将对其进行颜色映射。
这是一个使用animation模块的简单示例。
它比必须的要复杂一些,但是这应该为您提供一个做奇特的事情的框架。
(代码编辑于2019年4月以与当前版本兼容。有关旧代码,请参阅修订历史记录)
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
为。OSX后端不完全支持blitting。性能会受到影响,但是示例应在禁用blitting的情况下在OSX上正确运行。blit=False
FuncAnimation
对于一个仅更新颜色的简单示例,请查看以下内容:
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=range(numframes),
fargs=(color_data, scat))
plt.show()
def update_plot(i, data, scat):
scat.set_array(data[i])
return scat,
main()
.set_array()
会更新点色?
self.Scat.set_offsets(data[:2, :])
为 self.scat.set_offsets(data[:2, :].reshape(self.numpoints, 2))
我写了赛璐to,以使其更容易。可能最容易举例说明:
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
在引擎盖下使用。camera.snap
捕获图形的当前状态,该状态用于在动画中创建帧。
编辑:为了量化使用多少内存,我通过memory_profiler运行了它。
Line # Mem usage Increment Line Contents
================================================
11 65.2 MiB 65.2 MiB @profile
12 def main():
13 65.2 MiB 0.0 MiB numpoints = 10
14 65.2 MiB 0.0 MiB points = np.random.random((2, numpoints))
15 65.2 MiB 0.1 MiB colors = cm.rainbow(np.linspace(0, 1, numpoints))
16 65.9 MiB 0.6 MiB fig = plt.figure()
17 65.9 MiB 0.0 MiB camera = Camera(fig)
18 67.8 MiB 0.0 MiB for _ in range(100):
19 67.8 MiB 0.0 MiB points += 0.1 * (np.random.random((2, numpoints)) - .5)
20 67.8 MiB 1.9 MiB plt.scatter(*points, c=colors, s=100)
21 67.8 MiB 0.0 MiB camera.snap()
22 70.1 MiB 2.3 MiB anim = camera.animate(blit=True)
23 72.1 MiB 1.9 MiB anim.save('scatter.mp4')
总结一下:
FuncAnimation
?有什么区别?
这是东西。我曾经是Qt和Matlab的用户,但对matplotlib上的动画系统不太熟悉。
但是我确实找到了一种方法,可以像制作matlab一样制作任何想要的动画。它真的很强大。无需检查模块引用,就可以绘制所需的任何东西。因此,我希望它能有所帮助。
基本思想是在PyQt内部使用时间事件(我确定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)
我就像您想使用“动画散点图”制作排序动画一样。但是我只是找不到所谓的“设置”功能。所以我刷新了整个画布。
希望能帮助到你..
self.startTimer
值,刷新率没有任何变化。关于此的任何提示?(是的,我知道已经有一段时间了……)
为什么不试试这个
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()