2013-04-20 64 views
6

我想动画matplotlib内的fill_between形状,我不知道如何更新PolyCollection的数据。以这个简单的例子:我有两条线,我总是在它们之间填充。当然,这些线条会变化并且是动态的。Matplotlib动画fill_between形状

这里是一个虚拟的例子:

import matplotlib.pyplot as plt 

# Init plot: 
f_dummy = plt.figure(num=None, figsize=(6, 6)); 
axes_dummy = f_dummy.add_subplot(111); 

# Plotting: 
line1, = axes_dummy.plot(X, line1_data, color = 'k', linestyle = '--', linewidth=2.0, animated=True); 
line2, = axes_dummy.plot(X, line2_data, color = 'Grey', linestyle = '--', linewidth=2.0, animated=True); 
fill_lines = axes_dummy.fill_between(X, line1_data, line2_data, color = '0.2', alpha = 0.5, animated=True); 

f_dummy.show(); 
f_dummy.canvas.draw(); 
dummy_background = f_dummy.canvas.copy_from_bbox(axes_dummy.bbox); 

# [...]  

# Update plot data: 
def update_data(): 
    line1_data = # Do something with data 
    line2_data = # Do something with data 
    f_dummy.canvas.restore_region(dummy_background); 
    line1.set_ydata(line1_data); 
    line2.set_ydata(line2_data); 

    # Update fill data too 

    axes_dummy.draw_artist(line1); 
    axes_dummy.draw_artist(line2); 

    # Draw fill too 

    f_dummy.canvas.blit(axes_dummy.bbox); 

的问题是如何更新基于line1_data的fill_between聚数据和line2_data每次update_data()被调用和块传输之前吸引他们(“#更新填充数据太“&”#绘制填充太“)。我试图fill_lines.set_verts()没有成功,并找不到示例...

谢谢!

+1

您可能需要删除并完全重新绘制每一帧。 '* collection'对象在更新时不起作用。原因是他们抛弃了所有可以让你在数据空间和绘图空间之间进行映射的元数据,并且只保留一张要绘制的内容列表。这是一个权衡以迅速呈现它们。 – tacaswell 2013-04-21 06:13:22

+0

你的意思是在update_data中使用f_dummy.canvas.draw()吗?我从此开始,但不幸的是我需要快速绘图,因为我正在处理和实时播放信号,并且需要绘图不会影响播放(调用draw()会阻止播放)。如果你在播放声音时知道一个快速的线程技巧来重绘所有的东西,那就好了 - 我用threading.start(...)调用draw。我知道还有其他更快的绘图库,但我更愿意坚持使用matplotlib,并且恢复/ blit技巧对我来说足够快。 – Sebastian 2013-04-23 13:27:18

回答

3

好吧,正如有人指出的,我们在这里处理一个集合,所以我们将不得不删除并重新绘制

给这个轴对象 axes_dummy = f_dummy.add_subplot(111);

所以在update_data()的某处:你会的。 。

删除与相关联的所有藏品它

for coll in (axes_dummy.collections): 
    axes_dummy.collections.remove(coll) 

绘制新“filled_between” Polycollection

axes_dummy.fill_between(x,y-sigma,y+sigma, 
        facecolor='yellow', alpha=0.5) 

对填充一个顶部覆盖的未填充等值线图相似的​​技巧是必需的,因为一个未填充的轮廓图是一个集合以及(我认为的线)

+1

如果你只想删除一个集合,你可以使用'coll.get_label()'来获得正确的集合,只要你先标记集合。 – Sardathrion 2015-04-23 08:29:17

1

这不是我的答案,但我发现它最有用:

http://matplotlib.1069221.n5.nabble.com/animation-of-a-fill-between-region-td42814.html

您好毛, 补丁对象是比较困难的具有比线对象的工作,因为不像线对象是从由用户提供的输入数据中移除的步骤。有一个类似于你想在这里做的例子:http://matplotlib.org/examples/animation/histogram.html

基本上,你需要修改每一帧的路径的顶点。它可能看起来像这样:

from matplotlib import animation 
import numpy as np 
import matplotlib.pyplot as plt 

fig, ax = plt.subplots() 
ax.set_xlim([0,10000]) 

x = np.linspace(6000.,7000., 5) 
y = np.ones_like(x) 

collection = plt.fill_between(x, y) 

def animate(i): 
    path = collection.get_paths()[0] 
    path.vertices[:, 1] *= 0.9 

animation.FuncAnimation(fig, animate, 
         frames=25, interval=30) 

看看path.vertices看看它们是如何布局的。 希望帮助, 杰克

1

如果你不想使用anitmation,或者从你的身材删除一切只更新填充,你可以用我的方式:

呼叫fill_lines.remove(),然后再次调用axes_dummy.fill_between()画新的。为我工作。