在动画中使用Matplotlib补丁

1 投票
1 回答
1935 浏览
提问于 2025-04-18 00:44

我想生成一个空的补丁,以便以后可以设置数据。为了更好地解释我的问题,我给个例子:

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

现在,我想添加一个形状,我随机定义它的边缘点。我需要使用和在init()块中绘制线条时相同的结构:my_line.set_data([], [])。但是,我没有成功。

我使用的结构和在matplotlib教程中提供的例子是一样的。我的verts是通过一个函数生成的。

当我尝试使用:foo = patches.PathPatch([], facecolor='red', lw=2, alpha=0.0)时,我得到了<matplotlib.patches.PathPatch at 0x335d390>

但是后来,我无法设置路径数据。我尝试使用foo.set_datafoo.set_path,但PathPatch没有这些属性,所以它们没有用。我查看了这个页面,但没有找到解决办法。我查阅了所有能找到的教程,但没有一个能帮到我。

作为一种变通方法,我使用了ax1.add_patch()命令,并将透明度设置为0。这在某种程度上有帮助,但由于我必须输入数据才能使用这个命令,所有形状在动画的最后一步都会短暂可见,而我在那个时刻保存图形,结果就不太理想。

任何帮助都将不胜感激...

1 个回答

2

我不太确定你用的是什么形状。如果你使用的是多边形,你可以通过set_xy方法来更新多边形的顶点,并且可以用所有顶点都相等的点来创建初始的多边形。下面是一个例子。如果你需要一个完全任意的形状,可能更好的是绘制线条,然后使用fill_between来绘制它。

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

撰写回答