T-800
T-800

Reputation: 1603

Using Matplotlib-Patch inside an animation

I try to generate an empty patch to be able to set data later on. In order to explain my problem better, i will give an example:

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

x = range(10)
y = [i**2 for i in x]

figure = plt.figure()
ax1 = figure.add_subplot(111, xlim=(0,10), ylim=(0,100))

my_line, = ax1.plot([],[], 'o-')

def init():
    my_line.set_data([], [])
    return my_line,

i = 0

def animate(_):
    global i
    my_line.set_data(x[0:i], y[0:i])
    i = (i+1)%(len(x)+1)   
    return my_line,

ani = animation.FuncAnimation(figure, animate, repeat=True, blit=True, init_func=init)

plt.show()

Now, I to add a shape, which I define its edge points randomly. I need to use the same structure as I used for plotting lines inside the init() block: my_line.set_data([], []) . However, I couldn't succeed.

I use the same structure as the example provided in the matplotlib tutorial . My verts are generated from a function.

When I try using: foo = patches.PathPatch([], facecolor='red', lw=2, alpha=0.0) I get <matplotlib.patches.PathPatch at 0x335d390>

But later, I cannot set the path data. I tried using foo.set_data and foo.set_path but PathPatch doesn't have such attributes and therefore, they didn't work. I checked this page but I couldn't get anywhere. I checked all of the tutorials I could find, but none of them helped.

As a workaround, I used ax1.add_patch() command and have set the alpha value to 0. This helped to some extend but, as I have to enter data to be able to use this command, all of the shapes become visible at the final step of the animation for a very short time and, as I save my figure in that moment, it yields unfavorable results.

Any help would be appreciated...

Upvotes: 1

Views: 2045

Answers (1)

Molly
Molly

Reputation: 13610

I'm not sure what shape you're using, if you use a polygon, you can update the vertices of a polygon with the set_xy method and create the initial polygon with vertices that are all equal to each other. Example below. If you need a completely arbitrary shape, you might be better off plotting lines and using fill_between to draw it.

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

# Create the figure and axis
fig = plt.figure()
ax = plt.axes(xlim=(0, 10), ylim=(0, 10))

# mMke the initial polygon with all vertices set to 0
pts = [[0,0], [0,0], [0,0], [0,0]]
patch = plt.Polygon(pts)
ax.add_patch(patch)

def init():   
    return patch,

def animate(i):
    # Randomly set the vertices
    x1= 5*np.random.rand((1))[0]
    x2= 5*np.random.rand((1))[0] 
    x3= 5*np.random.rand((1))[0] + 5
    x4= 5*np.random.rand((1))[0] + 5

    y1= 5*np.random.rand((1))[0]
    y2= 5*np.random.rand((1))[0] 
    y3= 5*np.random.rand((1))[0] + 5
    y4= 5*np.random.rand((1))[0] + 5

    patch.set_xy([[x1,y1], [x2,y2], [x3,y3], [x4,y4]])

    return patch,

anim = animation.FuncAnimation(fig,animate,init_func=init,frames=36,interval=1000,blit=True)

plt.show()

Upvotes: 2

Related Questions