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!
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:and draw the new "fill_between" PolyCollection:
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?).
another idiom which will work is too keep a list of your plotted objects; this method seems to work with any type of plotted object.
initialize pyplot interactive mode
use the optional label argument when plotting the fill:
later in our script we can select by label to delete that specific fill or a list of fills, thus animating on a object by object basis.
you can use the same label for groups of objects you would like to delete; or otherwise encode the labels with tags as needed to suit needs
for example if we had fills labelled:
"cone1" "cone2" "sideways1"
would sort to delete both those prefixed with "cone".
You can also animate lines in the same manner
this is not my answer, but I found it most useful:
http://matplotlib.1069221.n5.nabble.com/animation-of-a-fill-between-region-td42814.html
Hi Mauricio, Patch objects are a bit more difficult to work with than line objects, because unlike line objects are a step removed from the input data supplied by the user. There is an example similar to what you want to do here: http://matplotlib.org/examples/animation/histogram.html
Basically, you need to modify the vertices of the path at each frame. It might look something like this:
Take a look at path.vertices to see how they're laid out. Hope that helps, Jake
If you don't want to use anitmation, or to remove everything from your figure to update only filling, you could use my way :
call
fill_lines.remove()
and then call againaxes_dummy.fill_between()
to draw new ones. Worked for me.