2014-09-15 4 views
3

Я пытаюсь анимировать разные объекты в одном и том же графе, используя фуканизацию pyplot.
Он работает почти так, как я ожидаю, за исключением порядка, в котором отображаются различные элементы. Таким образом, кривая графика, текст и легенда отображаются за изображением, где они едва видны.Pyplot zorder lost with animation

Вот мой (не так) минимальный рабочий пример:

#! /usr/bin/python 
import numpy as np 
from matplotlib import pyplot as plt 
from matplotlib import animation 
import random 

def init(): 
    line_simu.set_data([], []) 
    time_text.set_text('') 
    imobj.set_data(np.zeros((100, 100))) 
    imobj.set_zorder(0) 
    time_text.set_zorder(10) 
    return line_simu, time_text, imobj 

def animate(i): 
    imobj.set_zorder(0) 
    time_text.set_zorder(10) 
    y_simu = np.linspace(0,100, 100) 
    x_simu = np.linspace(-10, 10, 100) 
    line_simu.set_data(x_simu, y_simu) 

    time_text.set_text('time = %.1f' % i) 

    global data 
    imobj.set_data(data + np.random.random((100,1)) * 0.5) 

    return line_simu, time_text, imobj 


def forceAspect(ax,aspect=1): 
    im = ax.get_images() 
    extent = im[0].get_extent() 
    ax.set_aspect(abs((extent[1]-extent[0])/(extent[3]-extent[2]))/aspect) 


fig = plt.figure() 
ax = plt.axes(xlim=(-15,15), ylim=(-110, 0) , aspect=1) 

data = np.random.random((100,100)) - .5 
imobj = ax.imshow(data , extent=[-15,15, -110, 0.0], origin='lower', cmap=plt.cm.gray, vmin=-2, vmax=2, alpha=.7, zorder=0, aspect=1) 

line_simu, = ax.plot([], [],"r--", lw=2, markersize=4 , label = "Some curve" , zorder= 2) 

time_text = ax.text(-14.9, -108, '', zorder=10) 

l = plt.legend(loc='lower right', prop={'size':8}) 
l.set_zorder(200) 

forceAspect(ax,aspect=1) 

anim = animation.FuncAnimation(fig, animate, init_func=init, frames=range(50), interval=3000, blit=True) 

plt.show() 

Без анимации, я могу легко контролировать порядок различных элементов с set_zorder, но когда анимация обновляет изображение, этот порядок теряется , Я попытался установить zorder в функции init и снова в функции анимации без успеха.

Я очень благодарен за любую помощь по этому вопросу.

+0

Я заметил, что 'line_sumu' вы обновляете в этом примере не существует в той степени, осей, поэтому он не показывает, независимо от того, что ZOrder есть. Но если я это исправлю, это действительно отлично подходит для меня без каких-либо проблем с zorder, используя 1.3.1. Какая версия matplotlib у вас есть? – Ajean

+0

Спасибо Ajean. Я отредактировал проблему с линией вне границ, но это было просто для иллюстрации. Это хорошая новость, что это сработало для вас, у меня действительно есть более старая версия: 1.1.1. Я попробую обновить его, и я дам вам знать. –

+0

Наконец, я получил возможность протестировать скрипт с помощью matplotlib 1.3.1. К сожалению, это ничего не решает. Вы можете видеть только кривую/легенду/timestring через прозрачность, изображение остается сверху и ухудшает читаемость сюжета. –

ответ

1

Ответ на мой собственный вопрос: Кажется, что порядок, в котором объекты возврата init() и animate() возвращают объекты, контролирует порядок их отображения. Кроме того, эти функции должны возвращать объект легенды, чтобы включить его в анимацию.

Вот мой исправленный код:

#! /usr/bin/python 
import numpy as np 
from matplotlib import pyplot as plt 
from matplotlib import animation 
import random 

def init(): 
    imobj.set_data(np.zeros((100, 100))) 
    line_simu.set_data([], []) 
    time_text.set_text('time = 0.0') 

    return imobj , line_simu, time_text, l 

def animate(i): 
    global data 
    imobj.set_data(data + np.random.random((100,1)) * 0.5) 

    imobj.set_zorder(0) 
    y_simu = np.linspace(-100,-10, 100) 
    x_simu = np.linspace(-10, 10, 100) 
    line_simu.set_data(x_simu, y_simu) 
    time_text.set_text('time = %.1f' % i) 


    return imobj , line_simu, time_text, l 


def forceAspect(ax,aspect=1): 
    im = ax.get_images() 
    extent = im[0].get_extent() 
    ax.set_aspect(abs((extent[1]-extent[0])/(extent[3]-extent[2]))/aspect) 



fig = plt.figure() 
ax = plt.axes(xlim=(-15,15), ylim=(-110, 0) , aspect=1) 

data = np.random.random((100,100)) - .5 
imobj = ax.imshow(data , extent=[-15,15, -110, 0.0], origin='lower', cmap=plt.cm.gray, vmin=-2, vmax=2, alpha=1.0, zorder=1, aspect=1) 

line_simu, = ax.plot([], [],"r--", lw=2, markersize=4 , label = "Some curve" , zorder= 1) 
time_text = ax.text(-14.0, -108, '', zorder=10) 

forceAspect(ax,aspect=1) 

l = plt.legend(loc='lower right', prop={'size':8}) 

anim = animation.FuncAnimation(fig, animate, init_func=init, frames=range(50), interval=500, blit=True) 

plt.show()