2015-07-20 149 views
0

目标

嗨, 我想动画一个复杂图形与几个次要情节,并已开始与artist animationfunction animation方法测试。Matplotlib动画自定义艺术家类

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

# 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对象不具有与来自axvspan的matplotlib对象不同的属性set_visible

所以,当我尝试一个简单的动画,像这样:

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),所以对我来说这不是一个解决方案。有没有优点?
  • 获得与艺术家动画方法一起工作的情节,即使自定义绘图类明显缺少关键属性。

此外,我不知道如果我正在做整个实施部分权利,所以任何意见,在这方面也非常赞赏。

回答

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) 
+0

感谢。我应该澄清ax.cla不是我们所希望的,因为它也会重新设置每次重绘时的轴属性(例如xlim),从而弄乱了图形。我相信我的问题可以重新表述为:如何在不放松轴属性的情况下清除绘图? – surchs

+0

你不能简单地重新设置动画循环内的轴限制吗?如果没有清除所有其他属性,我认为您不能清除轴。如果轴必须保持不变,则需要更新/清除显示的数据对象。绘图句柄('a'和'b')应该有'set_data'方法,可以在不触碰轴的情况下改变绘图。例如'ax.patches.remove(a)'会移除当前的'axvspan'实例。对于其他原始艺术家对象将会有类似的删除。 –