用于自定义艺术家类的Matplotlib动画

时间:2015-07-20 06:20:50

标签: python animation matplotlib

目标

您好, 我试图使用多个子图为一个复杂的图形设置动画,并开始使用artist animationfunction animation方法进行测试。

目前,我的目标是让左侧的子图显示移动的彩色线(不是问题),右侧的子图显示脑扫描的更新表示(问题)。静态,这看起来像这样。

# Imports
import nilearn as nil
from nilearn import plotting as nlp
from matplotlib import pyplot as plt

window = np.arange(0,200-50)

fig = plt.figure(figsize=(7,4))
ax = fig.add_subplot(121)
ax.set_xlim([0, 200])
a = ax.axvspan(window[0], window[0]+50, color='blue', alpha=0.5)

ay = fig.add_subplot(122)
b = nlp.plot_stat_map(nil.image.index_img(s_img, 0), axes=ay, colorbar=False, display_mode='x', cut_coords=(0,))

Static version of what I'd like to display

问题

如您所见,我正在使用nilearn来绘制大脑图像。出于某种原因,plot_stat_map中的nilearn对象与set_visible中的matplotlib对象不同,没有属性axvspan

所以当我尝试这样的简单动画时:

fig = plt.figure(figsize=(7,4))
ax = fig.add_subplot(121)
ax.set_xlim([0, 200])
ay = fig.add_subplot(122)
iml = list()

for i in np.arange(50):
    a = ax.axvspan(window[i], window[i]+50, color='blue', alpha=0.5)
    b = nlp.plot_stat_map(nil.image.index_img(s_img, i), axes=ay)
    iml.append((a,b))

ani = animation.ArtistAniTruemation(fig, iml, interval=50, blit=False,
    repeat_delay=1000)

崩溃时出现以下错误:

/home/surchs/Enthought/Canopy_64bit/User/lib/python2.7/site-packages/matplotlib/animation.pyc in _init_draw(self)
    974         for f in self.new_frame_seq():
    975             for artist in f:
--> 976                 artist.set_visible(False)
    977                 # Assemble a list of unique axes that need flushing
    978                 if artist.axes not in axes:

AttributeError: 'OrthoSlicer' object has no attribute 'set_visible'

有道理,nilearn可能不符合matplotlibs的期望。所以我尝试了这样的函数动画方法:

def show_things(i, window, ax, ay):
    ax.axvspan(window[i], window[i]+50, color='blue', alpha=0.5)
    nlp.plot_stat_map(nil.image.index_img(s_img, i), axes=ay, colorbar=False, display_mode='x', cut_coords=(0,))

fig = plt.figure(figsize=(7,4))
ax = fig.add_subplot(121)
ax.set_xlim([0, 200])
ay = fig.add_subplot(122)

ani = animation.FuncAnimation(fig, show_things, interval=10, blit=False, fargs=(window, ax, ay))

虽然我不确定我是否正确使用了东西,但这给了我一个右边的动画脑图。但是,左边的情节现在没有更新,只是被抽出。因此,我没有滑动条,而是获得了扩展的颜色表面。像这样:

enter image description here

问题

我如何

  • 在使用函数动画方法时,在每次迭代时获取左边的图以更新(而不是覆盖)? 我已经在matplotlib中尝试了ax.cla()函数,但由于这也清除了所有轴属性(如xlim),这对我来说不是解决方案。有没有altneratives?
  • 使用艺术家动画方法获得右边的情节,即使自定义绘图类显然缺少一个关键属性。

另外,我不确定我是否正在执行整个实施部分,因此对此方面的任何建议也非常感激。

1 个答案:

答案 0 :(得分:1)

我怀疑您可能需要清除axvspan图之间的ax.cla()轴以获得正确的左图(N.B.也可能应该清除正确的图)。为了解决缺少属性的问题,我建议从nlp.plot_stat_map的返回句柄中提取数据,并使用matplotlib pcolormesh(或imshow)进行绘图。另一种可能性是创建子类并自己添加此方法。如果存在错误/功能请求,也可能值得提交nilearn

顺便说一下,如果你只是在快速简单的情节之后,你可以使用交互式情节做一个穷人的动画版本,作为一个最小的例子,

import matplotlib.pyplot as plt
import numpy as np
import time

#Interactive plot
plt.ion()

#Setup figures
fig = plt.figure(figsize=(7,4))
ax = fig.add_subplot(121)
ay = fig.add_subplot(122)
plt.show()


x = np.linspace(0,2*np.pi)
for i in range(10000):
    print(i)
    #Clear axes
    ax.cla(); ay.cla()

    #Update data
    yx = np.sin(x+i*0.1)
    yy = np.sin(2.*(x+i*0.1))

    #Replot
    ax.plot(x,yx)
    ay.plot(x,yy)

    #Pause to allow redraw
    plt.draw()
    plt.pause(0.01)