我目前正在尝试对一系列图像进行动画处理,其中每个图像最初绘制的省略号数量未知。到目前为止,我已经尝试了很多事情,但还没有找到解决方案,尽管我想我接近了。这是我的代码:
import matplotlib.pyplot as plt
from matplotlib.patches import Ellipse
def plot_images(img1, img2, objects, ax):
im1 = ax.imshow(img1)
im2 = ax.imshow(img2 with transparency as an overlay)
# plotting an ellipse for each object
e = [None]*len(objects)
for j in range(len(objects)):
e[j] = Ellipse(xy=(objects['x'][j], objects['y'][j]),
width=6 * objects['a'][j],
height=6 * objects['b'][j],
angle=objects['theta'][j] * 180. / np.pi)
e[j].set_facecolor('none')
e[j].set_edgecolor('red')
ax.add_artist(e[j])
return im1, im2, e
def animate(j):
# extracting objects
im1, im2, objects = object_finder_function()
imm1, imm2, e = plot_images(im1, im2, objects, axs)
return imm1, imm2, e
fig, axs = plt.subplots()
ani = animation.FuncAnimation(fig, animate, frames=image_number, interval=50, blit=True)
plt.show()
现在,当我尝试此代码时,我收到以下错误消息:
AttributeError: 'list' object has no attribute 'get_zorder'
所以我尝试了不同的东西,但最终,我发现,作为测试,我输入了plot_images函数。
return im1, im2, e[0], e[1], e[2]
并相应地更改动画功能,即
imm1, imm2, e0, e1, e2 = plot_images(im1, im2, objects, axs)
和
return imm1, imm2, e0, e1, e2
我没有收到错误消息,省略号实际上按照我的预期绘制在各自的帧中。现在的问题是,首先,我想绘制每个图像有数百个椭圆,所以我必须手动写下所有椭圆(即 e[0]、e[1]、e[2] - e[k],动画函数也是如此),这似乎不是正确的方法。另一件事是,正如我已经说过的那样,每个图像的省略号数量都会发生变化,并且以前不知道,因此我不可能相应地调整功能。
如何返回此省略号列表,以便动画读取它,就好像我会像在工作示例中那样将它们全部单独写下来一样?
你的代码有点不python,所以我为了清楚起见清理了一下。您的AttributeError
与get_zorder
函数有关,该函数在 matplotlib 中用于弄清楚如何对绘图进行分层。通过你尝试过的事情,我可以告诉你只需要在最后打开你的list_of_ellipses。
def plot_images(img1, img2, objects, ax):
im1 = ax.imshow(img1)
im2 = ax.imshow(img2 with transparency as an overlay)
list_of_ellipses = []
for j in range(len(objects)):
my_ellipse = Ellipse(xy=(objects['x'][j], objects['y'][j]),
width=6 * objects['a'][j],
height=6 * objects['b'][j],
angle=objects['theta'][j] * 180. / np.pi)
my_ellipse.set_facecolor('none')
my_ellipse.set_edgecolor('red')
ax.add_artist(my_ellipse)
list_of_ellipses.append(my_ellipse)
return im1, im2, list_of_ellipses
def animate():
im1, im2, objects = object_finder_function()
imm1, imm2, list_of_ellipses = plot_images(im1, im2, objects, axs)
return (imm1, imm2)+tuple(list_of_ellipses)
fig, axs = plt.subplots()
ani = animation.FuncAnimation(fig, animate, frames=image_number, interval=50, blit=True)
plt.show()
听起来你想扁平化e
.
您可以使用已经平面化的变量创建一个列表,并使用 e 对其进行扩展:
return tuple([im1, im2] + e)
或者e
任何您想使用它的地方打开包装。
假设您使用的是matplotlib.animation,animate
应该返回一个iterable
并且您返回一个包含三个对象的。return imm1, imm2, e
返回三个实例的元组。 最后一个是列表。 您应该能够通过将animate
函数更改为以下内容来返回list
而不是tuple
:
def animate(j):
im1, im2, objects = object_finder_function()
imm1, imm2, e = plot_images(im1, im2, objects, axs)
return [imm1, imm2] + e
但是,我会更改plot_images
以返回list
。 也许像下面这样:
def create_ellipse(objects, object_idx, artists):
ellipse = Ellipse(
xy=(objects['x'][object_idx], objects['y'][object_idx]),
width=(6 * objects['a'][object_idx]),
height=(6 * objects['b'][object_idx]),
angle=(objects['theta'][object_idx] * 180.0 / np.pi))
ellipse.set_facecolor('none')
ellipse.set_edgecolor('red')
artists.add_artists(ellipse)
return ellipse
def plot_images(img1, img2, objects, ax):
renderables = [ax.imshow(img1),
ax.imshow(img2 with transparency as an overlay)]
renderables.extend(create_ellipse(objects, idx, ax)
for idx in range(len(objects)))
return renderables