Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Matplotlib animate fill_between shape

I am trying to animate a fill_between shape inside matplotlib and I don't know how to update the data of the PolyCollection. Take this simple example: I have two lines and I am always filling between them. Of course, the lines change and are animated.

Here is a dummy example:

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 );

The question is how to update the fill_between Poly data based on line1_data and line2_data each time update_data() is called and draw them before blit ("# Update fill data too" & "# Draw fill too"). I tried fill_lines.set_verts() without success and could not find an example...

Thanks!

like image 280
Sebastian Avatar asked Apr 20 '13 13:04

Sebastian


People also ask

How do you fill between two curves in Python?

fill_between() is used to fill area between two horizontal curves. Two points (x, y1) and (x, y2) define the curves. this creates one or more polygons describing the filled areas.

What is Blit in FuncAnimation?

blit=True means only re-draw the parts that have changed. anim = animation. FuncAnimation(fig, animate, init_func=init, frames=200, interval=20, blit=True) # save the animation as an mp4. This requires ffmpeg or mencoder to be # installed.


1 Answers

Ok, as someone pointed out, we are dealing with a collection here, so we will have to delete and redraw. So somewhere in the update_data function, delete all collections associated with it:

axes_dummy.collections.clear()

and draw the new "fill_between" PolyCollection:

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

A similar trick is required to overlay an unfilled contour plot on top of a filled one, since an unfilled contour plot is a Collection as well (of lines I suppose?).

like image 192
meyerson Avatar answered Sep 21 '22 21:09

meyerson