2017-04-18 19 views
0

我有一个动画python图形。虽然我可以在计数器每次除以100时添加注释(箭头),但我无法弄清楚如何维持箭头(或将其附加到图)(请参阅我的屏幕截图)。目前,add_annotation的作品,但只有1秒,然后消失(它应该继续看到至少10秒左右)。带matplotlib的动画图形 - 无法维持/追加注释

转述从here

enter image description here

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

fig = plt.figure() 
ax1 = fig.add_subplot(1,1,1) 

z = np.random.normal(0,1,255) 
u = 0.1 
sd = 0.3 
counter = 0 
price = [100] 
t = [0] 

def add_annotation(annotated_message,value): 
    plt.annotate(annotated_message, 
       xy = (counter, value), xytext = (counter-5, value+20), 
       textcoords = 'offset points', ha = 'right', va = 'bottom', 
       bbox = dict(boxstyle = 'round,pad=0.1', fc = 'yellow', alpha = 0.5), 
       arrowprops = dict(arrowstyle = '->', connectionstyle = 'arc3,rad=0')) 

def getNewPrice(s,mean,stdev): 
    r = np.random.normal(0,1,1) 
    priceToday = s + s*(mean/255+stdev/np.sqrt(225)*r) 
    return priceToday 


def animate(i): 
    global t,u,sd,counter 
    x = t 
    y = price 
    counter += 1 
    x.append(counter) 
    value = getNewPrice(price[counter-1],u,sd) 
    y.append(value) 
    ax1.clear() 

    if counter%100==0: 
     print "ping" 
     add_annotation("100",value) 

    plt.plot(x,y,color="blue") 


ani = animation.FuncAnimation(fig,animate,interval=20) 
plt.show() 

回答

0

有几个问题与您的代码所采取的例子,最主要的是,你是在动画的每一步(ax1.clear())清除轴,因此您将删除注释。

一个选择是保存一个包含所有注释的数组,并且每次都重新创建它们。这显然不是最优雅的解决方案。

正确的方法做一个动画是创建Line2D对象,并使用Line2D.set_data(),或Line2D.set_xdata()Line2D.set_ydata()更新您的直线绘制的坐标。

请注意,动画功能应返回已修改的艺术家列表(至少如果您想使用blitting,这可以提高性能)。出于这个原因,当您创建注释时,您需要返回Annotation对象,并将它们保存在列表中并通过动画功能返回所有艺术家。

这是迅速扔在一起,但应该给你一个起点:

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

fig = plt.figure() 
ax1 = fig.add_subplot(1,1,1) 

ax1.set_xlim((0,500)) 
ax1.set_ylim((0,200)) 

z = np.random.normal(0,1,255) 
u = 0.1 
sd = 0.3 
counter = 0 
price = [100] 
t = [0] 
artists = [] 
l, = plt.plot([],[],color="blue") 


def add_annotation(annotated_message,value): 
    annotation = plt.annotate(annotated_message, 
       xy = (counter, value), xytext = (counter-5, value+20), 
       textcoords = 'offset points', ha = 'right', va = 'bottom', 
       bbox = dict(boxstyle = 'round,pad=0.1', fc = 'yellow', alpha = 0.5), 
       arrowprops = dict(arrowstyle = '->', connectionstyle = 'arc3,rad=0')) 
    return annotation 


def getNewPrice(s,mean,stdev): 
    r = np.random.normal(0,1,1) 
    priceToday = s + s*(mean/255+stdev/np.sqrt(225)*r) 
    return priceToday 


def animate(i): 
    global t,u,sd,counter,artists 
    x = t 
    y = price 
    counter += 1 
    x.append(counter) 
    value = getNewPrice(price[counter-1],u,sd) 
    y.append(value) 
    l.set_data(x,y) 

    if counter%100==0: 
     print(artists) 
     new_annotation = add_annotation("100",value) 
     artists.append(new_annotation) 

    return [l]+artists 


ani = animation.FuncAnimation(fig,animate,interval=20,frames=500)