动画中Pyplot的zorder丢失

4
我正在尝试使用pyplot的funcanimation在同一图表中动画不同的对象。
它几乎按照我的期望工作,除了显示不同元素的顺序。因此,绘图曲线、文本和图例显示在它们几乎看不见的图像后面。

这是我的(不太)最小化工作示例:

#! /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轻松控制不同元素的顺序,但当动画更新图像时,这个顺序就会丢失。我尝试在init函数和animate函数中再次设置zorder,但没有成功。

非常感谢您对此事的任何帮助。


我注意到在这个例子中你正在更新的 line_sumu 不存在于轴范围内,所以无论 zorder 是什么它都不会显示。但是如果我修复了这个问题,使用 1.3.1 版本,这个代码实际上对我来说完全正常,没有任何 zorder 的问题。你使用的是哪个版本的 matplotlib? - Ajean
谢谢Ajean。我已经编辑了那个超出边界的问题,但那只是为了举例说明。很高兴它对你有用,我确实使用的是旧版本:1.1.1。我会尝试更新它并告诉你结果。 - snake_charmer
最终,我有机会使用matplotlib 1.3.1测试脚本。不幸的是,它并没有解决任何问题。你只能透过透明度看到曲线/图例/时间字符串,图像仍然在顶部并且降低了绘图的可读性。 - snake_charmer
1个回答

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接