Matplotlib动画:更新极坐标图的径向视图限制

时间:2014-07-29 17:19:32

标签: animation matplotlib labels limits

我试图创建一个动画极坐标图,其中径向视图限制增加/减少以适应半径。如果我设置了polar = False,那么yaxis就更新了,但它对极轴没有正常工作。

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

def data_gen():
    t = data_gen.t
    cnt = 0
    while cnt < 1000:
        cnt+=1
        t += 0.05
        yield t, 1.1 + np.sin(2*np.pi*t) * np.exp(t/10.)
data_gen.t = 0

plt.rc ('grid', color='g', lw=1, ls='-')
plt.rc ('xtick', labelsize=15, color='b')
plt.rc ('ytick', labelsize=15, color='b')
fig = plt.figure(figsize=(8,8))
ax1 = fig.add_axes([.05, .90, .9, .08], polar=False, axisbg='#BFBFBF', xticks=[], yticks=[])
ax2 = fig.add_axes([.05, .05, .9, .8], polar=True, axisbg='k')
#ax = fig.add_axes([.1,.1,.8,.8], polar=False, axisbg='k')
line, = ax2.plot([], [], lw=2)
ax2.set_ylim(0, 2.2)
ax2.set_xlim(0, 140)
ax2.grid(1)
xdata, ydata = [], []
title = ax1.text (0.02, 0.5, '', fontsize=14, transform=ax1.transAxes)

def init():
    line.set_data([], [])
    title.set_text ('')
    return line, title

def run(data):
    # update the data
    t,y = data
    xdata.append(t)
    ydata.append(y)
    ymin, ymax = ax2.get_ylim()

    if y >= ymax:
        ax2.set_ylim (ymin, 2*ymax)
        ax2.figure.canvas.draw()

    title.set_text ("time = %.3f, y(t) = 1.1 + sin(2*pi*t) + exp(t/10) = %.3f" % (t, y))
    line.set_data(xdata, ydata)
    return line, title

ani = animation.FuncAnimation(fig, run, data_gen, init, blit=True, interval=100, repeat=False)

实际上,视图限制确实会调整,但刻度标签保持不变。在重绘画布后插入raw_input()会显示所有内容都已正确重绘,但随后刻度标签将恢复为之前的状态。更奇怪的是,直到第二次调用update()函数并返回时才会发生这种情况。

当我通过重复调用draw()为旧方式设置动画时,我没有遇到这个问题。但我宁愿用动画模块以正确的方式做到这一点,因为旧的方式存在性能问题(上面的代码块只是为了演示问题,而不是实际的程序,我是&#39;写作。)

我应该注意到我还在学习MPL,所以如果我的一些术语出错,我会道歉。

1 个答案:

答案 0 :(得分:1)

如果您使用blit,背景将保存在缓存中以便快速绘制,您可以在更改轴范围时清除缓存,添加ani._blit_cache.clear()

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

def data_gen():
    t = data_gen.t
    cnt = 0
    while cnt < 1000:
        cnt+=1
        t += 0.05
        yield t, 1.1 + np.sin(2*np.pi*t) * np.exp(t/10.)
data_gen.t = 0

plt.rc ('grid', color='g', lw=1, ls='-')
plt.rc ('xtick', labelsize=15, color='b')
plt.rc ('ytick', labelsize=15, color='b')
fig = plt.figure(figsize=(8,8))
ax1 = fig.add_axes([.05, .90, .9, .08], polar=False, axisbg='#BFBFBF', xticks=[], yticks=[])
ax2 = fig.add_axes([.05, .05, .9, .8], polar=True, axisbg='k')
#ax = fig.add_axes([.1,.1,.8,.8], polar=False, axisbg='k')
line, = ax2.plot([], [], lw=2)
ax2.set_ylim(0, 2.2)
ax2.set_xlim(0, 140)
ax2.grid(1)
xdata, ydata = [], []
title = ax1.text (0.02, 0.5, '', fontsize=14, transform=ax1.transAxes)

def init():
    line.set_data([], [])
    title.set_text ('')
    return line, title

def run(data):
    # update the data
    t,y = data
    xdata.append(t)
    ydata.append(y)
    ymin, ymax = ax2.get_ylim()

    if y >= ymax:
        ax2.set_ylim (ymin, 2*ymax)
        ani._blit_cache.clear() # <- add to clear background from blit cache
        title.set_text('') # <- eliminate text artifact in title
        ax2.figure.canvas.draw()

    title.set_text ("time = %.3f, y(t) = 1.1 + sin(2*pi*t) + exp(t/10) = %.3f" % (t, y))
    line.set_data(xdata, ydata)
    return line, title

ani = animation.FuncAnimation(fig, run, data_gen, init, blit=True, interval=100, repeat=False)